Auto merge of #124982 - compiler-errors:uplift-trait-ref, r=lcnr

Uplift `TraitRef` into `rustc_type_ir`

Emotional rollercoaster

r? lcnr
This commit is contained in:
bors 2024-05-10 22:24:53 +00:00
commit 19dacee0d8
55 changed files with 492 additions and 313 deletions

View File

@ -22,6 +22,7 @@ use rustc_middle::mir::{
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
TerminatorKind, VarBindingForm,
};
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{
self, suggest_constraining_type_params, PredicateKind, ToPredicate, Ty, TyCtxt,
TypeSuperVisitable, TypeVisitor,

View File

@ -532,8 +532,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let tcx = self.tcx();
let trait_ref =
ty::TraitRef::from_lang_item(tcx, LangItem::Copy, self.last_span, [place_ty.ty]);
let trait_ref = ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
[place_ty.ty],
);
// To have a `Copy` operand, the type `T` of the
// value must be `Copy`. Note that we prove that `T: Copy`,
@ -1273,10 +1276,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.check_rvalue(body, rv, location);
if !self.unsized_feature_enabled() {
let trait_ref = ty::TraitRef::from_lang_item(
let trait_ref = ty::TraitRef::new(
tcx,
LangItem::Sized,
self.last_span,
tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
[place_ty],
);
self.prove_trait_ref(
@ -1925,8 +1927,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Operand::Move(place) => {
// Make sure that repeated elements implement `Copy`.
let ty = place.ty(body, tcx).ty;
let trait_ref =
ty::TraitRef::from_lang_item(tcx, LangItem::Copy, span, [ty]);
let trait_ref = ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Copy, Some(span)),
[ty],
);
self.prove_trait_ref(
trait_ref,
@ -1939,7 +1944,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
let trait_ref = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, span, [ty]);
let trait_ref = ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Sized, Some(span)),
[ty],
);
self.prove_trait_ref(
trait_ref,
@ -1952,7 +1961,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Rvalue::ShallowInitBox(operand, ty) => {
self.check_operand(operand, location);
let trait_ref = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, span, [*ty]);
let trait_ref = ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Sized, Some(span)),
[*ty],
);
self.prove_trait_ref(
trait_ref,
@ -2050,10 +2063,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
let &ty = ty;
let trait_ref = ty::TraitRef::from_lang_item(
let trait_ref = ty::TraitRef::new(
tcx,
LangItem::CoerceUnsized,
span,
tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
[op.ty(body, tcx), ty],
);

View File

@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::{self, CallSource};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _};
use rustc_middle::ty::{
self, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef,
Param, TraitRef, Ty,

View File

@ -94,6 +94,12 @@ into_diag_arg_using_display!(
ErrCode,
);
impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::TraitRef<I> {
fn into_diag_arg(self) -> DiagArgValue {
self.to_string().into_diag_arg()
}
}
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
impl IntoDiagArg for bool {

View File

@ -14,6 +14,7 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::{self, RegionResolutionError};
use rustc_infer::traits::Obligation;
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;

View File

@ -3,6 +3,7 @@
use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir::Unsafety;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{ImplPolarity::*, ImplTraitHeader, TraitDef, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_span::ErrorGuaranteed;

View File

@ -5,6 +5,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
use rustc_span::symbol::Ident;
use rustc_span::{ErrorGuaranteed, Span, Symbol};

View File

@ -17,6 +17,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::traits::FulfillmentError;
use rustc_middle::query::Key;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{self, suggest_constraining_type_param};
use rustc_middle::ty::{AdtDef, Ty, TyCtxt, TypeVisitableExt};

View File

@ -758,10 +758,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
self.tcx,
self.cause.clone(),
self.param_env,
ty::TraitRef::from_lang_item(
ty::TraitRef::new(
self.tcx,
hir::LangItem::PointerLike,
self.cause.span,
self.tcx.require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)),
[a],
),
));

View File

@ -25,7 +25,9 @@ use rustc_hir::{ExprKind, Node, QPath};
use rustc_infer::infer::{self, RegionVariableOrigin};
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
use rustc_middle::ty::print::{
with_crate_prefix, with_forced_trimmed_paths, PrintTraitRefExt as _,
};
use rustc_middle::ty::IsSuggestable;
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::DefIdSet;

View File

@ -70,7 +70,7 @@ use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_macros::extension;
use rustc_middle::dep_graph::DepContext;
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _};
use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::{

View File

@ -12,7 +12,7 @@ use rustc_errors::{Diag, IntoDiagArg};
use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode};
use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode};
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, RePlaceholder, Region, TyCtxt};

View File

@ -30,7 +30,7 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::bug;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintError};
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintError, PrintTraitRefExt as _};
use rustc_middle::ty::{self, print::Printer, GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_session::lint::{BuiltinLintDiag, LintExpectationId};
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};

View File

@ -41,7 +41,7 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre
s.add_impl_generic(newtcx);
s.bound_impl(
quote!(::rustc_middle::ty::Lift<'__lifted>),
quote!(::rustc_middle::ty::Lift<::rustc_middle::ty::TyCtxt<'__lifted>>),
quote! {
type Lifted = #lifted;

View File

@ -57,7 +57,7 @@ macro_rules! span_bug {
macro_rules! TrivialLiftImpls {
($($ty:ty),+ $(,)?) => {
$(
impl<'tcx> $crate::ty::Lift<'tcx> for $ty {
impl<'tcx> $crate::ty::Lift<$crate::ty::TyCtxt<'tcx>> for $ty {
type Lifted = Self;
fn lift_to_tcx(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> {
Some(self)

View File

@ -8,7 +8,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_type_ir::ConstKind as IrConstKind;
use rustc_type_ir::{ConstTy, IntoKind, TypeFlags, WithCachedTypeInfo};
use rustc_type_ir::{TypeFlags, WithCachedTypeInfo};
mod int;
mod kind;
@ -30,7 +30,7 @@ rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
#[rustc_pass_by_value]
pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>);
impl<'tcx> IntoKind for Const<'tcx> {
impl<'tcx> rustc_type_ir::inherent::IntoKind for Const<'tcx> {
type Kind = ConstKind<'tcx>;
fn kind(self) -> ConstKind<'tcx> {
@ -48,12 +48,6 @@ impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> {
}
}
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
fn ty(self) -> Ty<'tcx> {
self.ty()
}
}
/// Typed constant value.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable)]
@ -180,7 +174,7 @@ impl<'tcx> Const<'tcx> {
}
}
impl<'tcx> rustc_type_ir::new::Const<TyCtxt<'tcx>> for Const<'tcx> {
impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
fn new_anon_bound(
tcx: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
@ -189,6 +183,10 @@ impl<'tcx> rustc_type_ir::new::Const<TyCtxt<'tcx>> for Const<'tcx> {
) -> Self {
Const::new_bound(tcx, debruijn, var, ty)
}
fn ty(self) -> Ty<'tcx> {
self.ty()
}
}
impl<'tcx> Const<'tcx> {

View File

@ -4,6 +4,8 @@
pub mod tls;
pub use rustc_type_ir::lift::Lift;
use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKindStruct};
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
@ -138,6 +140,19 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
}
type GenericsOf = &'tcx ty::Generics;
fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
self.generics_of(def_id)
}
fn check_and_mk_args(
self,
def_id: DefId,
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
) -> ty::GenericArgsRef<'tcx> {
self.check_and_mk_args(def_id, args)
}
}
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
@ -917,7 +932,7 @@ impl<'tcx> TyCtxt<'tcx> {
)
}
pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> {
pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
value.lift_to_tcx(self)
}
@ -1524,31 +1539,9 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
/// A trait implemented for all `X<'a>` types that can be safely and
/// efficiently converted to `X<'tcx>` as long as they are part of the
/// provided `TyCtxt<'tcx>`.
/// This can be done, for example, for `Ty<'tcx>` or `GenericArgsRef<'tcx>`
/// by looking them up in their respective interners.
///
/// However, this is still not the best implementation as it does
/// need to compare the components, even for interned values.
/// It would be more efficient if `TypedArena` provided a way to
/// determine whether the address is in the allocated range.
///
/// `None` is returned if the value or one of the components is not part
/// of the provided context.
/// For `Ty`, `None` can be returned if either the type interner doesn't
/// contain the `TyKind` key or if the address of the interned
/// pointer differs. The latter case is possible if a primitive type,
/// e.g., `()` or `u8`, was interned in a different context.
pub trait Lift<'tcx>: fmt::Debug {
type Lifted: fmt::Debug + 'tcx;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
}
macro_rules! nop_lift {
($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for $ty {
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
type Lifted = $lifted;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
// Assert that the set has the right type.
@ -1583,7 +1576,7 @@ macro_rules! nop_lift {
macro_rules! nop_list_lift {
($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
type Lifted = &'tcx List<$lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
// Assert that the set has the right type.
@ -1621,7 +1614,7 @@ nop_list_lift! {args; GenericArg<'a> => GenericArg<'tcx>}
macro_rules! nop_slice_lift {
($ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for &'a [$ty] {
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a [$ty] {
type Lifted = &'tcx [$lifted];
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if self.is_empty() {

View File

@ -39,6 +39,16 @@ pub struct GenericArg<'tcx> {
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
}
impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> {
fn type_at(self, i: usize) -> Ty<'tcx> {
self.type_at(i)
}
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
GenericArgs::identity_for_item(tcx, def_id)
}
}
#[cfg(parallel_compiler)]
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend
@ -205,7 +215,7 @@ impl<'tcx> GenericArg<'tcx> {
}
}
impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> {
type Lifted = GenericArg<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {

View File

@ -145,6 +145,12 @@ pub struct Generics {
pub host_effect_index: Option<usize>,
}
impl<'tcx> rustc_type_ir::inherent::GenericsOf<TyCtxt<'tcx>> for &'tcx Generics {
fn count(&self) -> usize {
self.parent_count + self.own_params.len()
}
}
impl<'tcx> Generics {
/// Looks through the generics and all parents to find the index of the
/// given param def-id. This is in comparison to the `param_def_id_to_index`

View File

@ -530,7 +530,7 @@ pub struct CReaderCacheKey {
#[rustc_pass_by_value]
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
impl<'tcx> IntoKind for Ty<'tcx> {
impl<'tcx> rustc_type_ir::inherent::IntoKind for Ty<'tcx> {
type Kind = TyKind<'tcx>;
fn kind(self) -> TyKind<'tcx> {
@ -981,7 +981,7 @@ pub struct Placeholder<T> {
pub type PlaceholderRegion = Placeholder<BoundRegion>;
impl PlaceholderLike for PlaceholderRegion {
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderRegion {
fn universe(self) -> UniverseIndex {
self.universe
}
@ -1001,7 +1001,7 @@ impl PlaceholderLike for PlaceholderRegion {
pub type PlaceholderType = Placeholder<BoundTy>;
impl PlaceholderLike for PlaceholderType {
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderType {
fn universe(self) -> UniverseIndex {
self.universe
}
@ -1028,7 +1028,7 @@ pub struct BoundConst<'tcx> {
pub type PlaceholderConst = Placeholder<BoundVar>;
impl PlaceholderLike for PlaceholderConst {
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderConst {
fn universe(self) -> UniverseIndex {
self.universe
}

View File

@ -2,19 +2,19 @@ use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::Interned;
use rustc_errors::{DiagArgValue, IntoDiagArg};
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_span::Span;
use rustc_type_ir::ClauseKind as IrClauseKind;
use rustc_type_ir::PredicateKind as IrPredicateKind;
use rustc_type_ir::TraitRef as IrTraitRef;
use std::cmp::Ordering;
use crate::ty::visit::TypeVisitableExt;
use crate::ty::{
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArg, GenericArgs,
GenericArgsRef, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArgsRef,
PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
};
pub type TraitRef<'tcx> = IrTraitRef<TyCtxt<'tcx>>;
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
@ -30,6 +30,8 @@ pub struct Predicate<'tcx>(
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
);
impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {}
impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
fn flags(&self) -> TypeFlags {
self.0.flags
@ -326,76 +328,6 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
}
}
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where-clause:
/// ```ignore (illustrative)
/// T: Foo<U>
/// ```
/// This would be represented by a trait-reference where the `DefId` is the
/// `DefId` for the trait `Foo` and the args define `T` as parameter 0,
/// and `U` as parameter 1.
///
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the generic parameters.
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
pub args: GenericArgsRef<'tcx>,
/// This field exists to prevent the creation of `TraitRef` without
/// calling [`TraitRef::new`].
pub(super) _use_trait_ref_new_instead: (),
}
impl<'tcx> TraitRef<'tcx> {
pub fn new(
tcx: TyCtxt<'tcx>,
trait_def_id: DefId,
args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
) -> Self {
let args = tcx.check_and_mk_args(trait_def_id, args);
Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
}
pub fn from_lang_item(
tcx: TyCtxt<'tcx>,
trait_lang_item: LangItem,
span: Span,
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
) -> Self {
let trait_def_id = tcx.require_lang_item(trait_lang_item, Some(span));
Self::new(tcx, trait_def_id, args)
}
pub fn from_method(
tcx: TyCtxt<'tcx>,
trait_id: DefId,
args: GenericArgsRef<'tcx>,
) -> ty::TraitRef<'tcx> {
let defs = tcx.generics_of(trait_id);
ty::TraitRef::new(tcx, trait_id, tcx.mk_args(&args[..defs.own_params.len()]))
}
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
/// are the parameters defined on trait.
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
ty::TraitRef::new(tcx, def_id, GenericArgs::identity_for_item(tcx, def_id))
}
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
ty::TraitRef::new(
tcx,
self.def_id,
[self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
)
}
#[inline]
pub fn self_ty(&self) -> Ty<'tcx> {
self.args.type_at(0)
}
}
pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>;
impl<'tcx> PolyTraitRef<'tcx> {
@ -408,12 +340,6 @@ impl<'tcx> PolyTraitRef<'tcx> {
}
}
impl<'tcx> IntoDiagArg for TraitRef<'tcx> {
fn into_diag_arg(self) -> DiagArgValue {
self.to_string().into_diag_arg()
}
}
/// An existential reference to a trait, where `Self` is erased.
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
/// ```ignore (illustrative)

View File

@ -1,6 +1,7 @@
use crate::ty::GenericArg;
use crate::ty::{self, Ty, TyCtxt};
use hir::def::Namespace;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sso::SsoHashSet;
use rustc_hir as hir;
@ -11,6 +12,8 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
mod pretty;
pub use self::pretty::*;
use super::Lift;
pub type PrintError = std::fmt::Error;
pub trait Print<'tcx, P> {
@ -334,3 +337,21 @@ pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> Str
format!("module `{}`", tcx.def_path_str(def_id))
}
}
impl<T> rustc_type_ir::ir_print::IrPrint<T> for TyCtxt<'_>
where
T: Copy + for<'a, 'tcx> Lift<TyCtxt<'tcx>, Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>>,
{
fn print(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ty::tls::with(|tcx| {
let mut cx = FmtPrinter::new(tcx, Namespace::TypeNS);
tcx.lift(*t).expect("could not lift for printing").print(&mut cx)?;
fmt.write_str(&cx.into_buffer())?;
Ok(())
})
}
fn print_debug(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
with_no_trimmed_paths!(Self::print(t, fmt))
}
}

View File

@ -16,7 +16,7 @@ use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
use rustc_hir::def_id::{DefIdMap, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPathDataName};
use rustc_hir::LangItem;
use rustc_macros::Lift;
use rustc_macros::{extension, Lift};
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
use rustc_session::Limit;
use rustc_span::symbol::{kw, Ident, Symbol};
@ -2919,16 +2919,17 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitName<'tcx> {
}
}
#[extension(pub trait PrintTraitRefExt<'tcx>)]
impl<'tcx> ty::TraitRef<'tcx> {
pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
TraitRefPrintOnlyTraitPath(self)
}
pub fn print_trait_sugared(self) -> TraitRefPrintSugared<'tcx> {
fn print_trait_sugared(self) -> TraitRefPrintSugared<'tcx> {
TraitRefPrintSugared(self)
}
pub fn print_only_trait_name(self) -> TraitRefPrintOnlyTraitName<'tcx> {
fn print_only_trait_name(self) -> TraitRefPrintOnlyTraitName<'tcx> {
TraitRefPrintOnlyTraitName(self)
}
}
@ -3032,6 +3033,10 @@ forward_display_to_print! {
define_print! {
(self, cx):
ty::TraitRef<'tcx> {
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
}
ty::TypeAndMut<'tcx> {
p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
}
@ -3113,10 +3118,6 @@ define_print_and_forward_display! {
p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
}
ty::TraitRef<'tcx> {
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
}
TraitRefPrintOnlyTraitPath<'tcx> {
p!(print_def_path(self.0.def_id, self.0.args));
}

View File

@ -19,7 +19,7 @@ pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
#[rustc_pass_by_value]
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> {
impl<'tcx> rustc_type_ir::inherent::IntoKind for Region<'tcx> {
type Kind = RegionKind<'tcx>;
fn kind(self) -> RegionKind<'tcx> {
@ -137,7 +137,7 @@ impl<'tcx> Region<'tcx> {
}
}
impl<'tcx> rustc_type_ir::new::Region<TyCtxt<'tcx>> for Region<'tcx> {
impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> {
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
}

View File

@ -132,12 +132,6 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::FnSig<'tcx> {
}
}
impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
with_no_trimmed_paths!(fmt::Display::fmt(self, f))
}
}
impl<'tcx> ty::DebugWithInfcx<TyCtxt<'tcx>> for Ty<'tcx> {
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
this: WithInfcx<'_, Infcx, &Self>,
@ -478,7 +472,7 @@ TrivialTypeTraversalAndLiftImpls! {
///////////////////////////////////////////////////////////////////////////
// Lift implementations
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> {
type Lifted = Option<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
Some(match self {
@ -488,7 +482,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
}
}
impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> {
type Lifted = ty::Term<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
Some(

View File

@ -942,7 +942,7 @@ where
}
}
impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
impl<'tcx, T> rustc_type_ir::inherent::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> {
self.bound_vars
}
@ -1812,7 +1812,7 @@ impl<'tcx> Ty<'tcx> {
}
}
impl<'tcx> rustc_type_ir::new::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
}

View File

@ -32,10 +32,9 @@ fn custom_coerce_unsize_info<'tcx>(
source_ty: Ty<'tcx>,
target_ty: Ty<'tcx>,
) -> Result<CustomCoerceUnsized, ErrorGuaranteed> {
let trait_ref = ty::TraitRef::from_lang_item(
let trait_ref = ty::TraitRef::new(
tcx.tcx,
LangItem::CoerceUnsized,
tcx.span,
tcx.require_lang_item(LangItem::CoerceUnsized, Some(tcx.span)),
[source_ty, target_ty],
);

View File

@ -1,11 +1,11 @@
use std::cmp::Ordering;
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_type_ir::new::{Const, Region, Ty};
use rustc_type_ir::inherent::*;
use rustc_type_ir::visit::TypeVisitableExt;
use rustc_type_ir::{
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, InferCtxtLike,
Interner,
};
/// Whether we're canonicalizing a query input or the query response.

View File

@ -20,6 +20,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind};
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::{self, Const, GenericParamDefKind};
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};

View File

@ -4,7 +4,7 @@ use rustc_errors::{
SubdiagMessageOp, Subdiagnostic,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
use rustc_middle::ty::{self, print::PrintTraitRefExt as _, ClosureKind, PolyTraitRef, Ty};
use rustc_span::{Span, Symbol};
#[derive(Diagnostic)]

View File

@ -368,7 +368,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
}
};
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output])
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [output])
});
let pred = tupled_inputs_and_output
@ -414,7 +414,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
)?;
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| {
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output_ty])
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [output_ty])
},
);
@ -576,10 +576,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
// and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
// FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
// exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
let sized_predicate = ty::TraitRef::from_lang_item(
let sized_predicate = ty::TraitRef::new(
tcx,
LangItem::Sized,
DUMMY_SP,
tcx.require_lang_item(LangItem::Sized, None),
[ty::GenericArg::from(goal.predicate.self_ty())],
);
// FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?

View File

@ -16,7 +16,7 @@ use rustc_middle::traits::{BuiltinImplSource, Reveal};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
use rustc_span::ErrorGuaranteed;
impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
fn self_ty(self) -> Ty<'tcx> {
@ -307,7 +307,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}
};
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output])
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [output])
});
let pred = tupled_inputs_and_output
@ -346,7 +346,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
)?;
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output_coroutine_ty])
ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Sized, None),
[output_coroutine_ty],
)
},
);

View File

@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::{extension, LintDiagnostic};
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
use rustc_parse_format::{ParseMode, Parser, Piece, Position};

View File

@ -537,10 +537,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.tcx,
obligation.cause.clone(),
obligation.param_env,
ty::TraitRef::from_lang_item(
ty::TraitRef::new(
self.tcx,
hir::LangItem::Sized,
obligation.cause.span,
self.tcx.require_lang_item(
hir::LangItem::Sized,
Some(obligation.cause.span),
),
[base_ty],
),
);
@ -4033,10 +4035,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let node = tcx.hir_node_by_def_id(hir.get_parent_item(expr.hir_id).def_id);
let pred = ty::Binder::dummy(ty::TraitPredicate {
trait_ref: ty::TraitRef::from_lang_item(
trait_ref: ty::TraitRef::new(
tcx,
LangItem::Clone,
span,
tcx.require_lang_item(LangItem::Clone, Some(span)),
[*ty],
),
polarity: ty::PredicatePolarity::Positive,

View File

@ -37,7 +37,9 @@ use rustc_middle::traits::SignatureMismatchData;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
use rustc_middle::ty::print::{
with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitRefExt as _,
};
use rustc_middle::ty::{
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
TypeVisitable, TypeVisitableExt,

View File

@ -974,9 +974,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
//
// NOTE: This should be kept in sync with the similar code in
// `rustc_ty_utils::instance::resolve_associated_item()`.
let node_item =
specialization_graph::assoc_def(selcx.tcx(), impl_data.impl_def_id, obligation.predicate.def_id)
.map_err(|ErrorGuaranteed { .. }| ())?;
let node_item = specialization_graph::assoc_def(
selcx.tcx(),
impl_data.impl_def_id,
obligation.predicate.def_id,
)
.map_err(|ErrorGuaranteed { .. }| ())?;
if node_item.is_final() {
// Non-specializable items are always projectable.
@ -1019,7 +1022,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
lang_items.async_fn_trait(),
lang_items.async_fn_mut_trait(),
lang_items.async_fn_once_trait(),
].contains(&Some(trait_ref.def_id))
]
.contains(&Some(trait_ref.def_id))
{
true
} else if lang_items.async_fn_kind_helper() == Some(trait_ref.def_id) {
@ -1032,7 +1036,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
true
} else {
obligation.predicate.args.type_at(0).to_opt_closure_kind().is_some()
&& obligation.predicate.args.type_at(1).to_opt_closure_kind().is_some()
&& obligation.predicate.args.type_at(1).to_opt_closure_kind().is_some()
}
} else if lang_items.discriminant_kind_trait() == Some(trait_ref.def_id) {
match self_ty.kind() {
@ -1159,12 +1163,20 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// Otherwise, type parameters, opaques, and unnormalized projections have
// unit metadata if they're known (e.g. by the param_env) to be sized.
ty::Param(_) | ty::Alias(..)
if self_ty != tail || selcx.infcx.predicate_must_hold_modulo_regions(
&obligation.with(
selcx.tcx(),
ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]),
),
) =>
if self_ty != tail
|| selcx.infcx.predicate_must_hold_modulo_regions(
&obligation.with(
selcx.tcx(),
ty::TraitRef::new(
selcx.tcx(),
selcx.tcx().require_lang_item(
LangItem::Sized,
Some(obligation.cause.span()),
),
[self_ty],
),
),
) =>
{
true
}
@ -1227,7 +1239,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
obligation.cause.span,
format!("Cannot project an associated type from `{impl_source:?}`"),
);
return Err(())
return Err(());
}
};
@ -1556,10 +1568,9 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
// and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
// FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
// exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
let sized_predicate = ty::TraitRef::from_lang_item(
let sized_predicate = ty::TraitRef::new(
tcx,
LangItem::Sized,
obligation.cause.span(),
tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span())),
[self_ty],
);
obligations.push(obligation.with(tcx, sized_predicate));

View File

@ -34,7 +34,9 @@ where
}
}
pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx> + Copy {
pub trait Normalizable<'tcx>:
fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<TyCtxt<'tcx>> + Copy
{
fn type_op_method(
tcx: TyCtxt<'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,

View File

@ -735,7 +735,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
output_ty,
&mut nested,
);
let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]);
let tr = ty::TraitRef::new(
self.tcx(),
self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
[output_ty],
);
nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
Ok(nested)
@ -1009,10 +1013,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} else {
nested.push(obligation.with(
self.tcx(),
ty::TraitRef::from_lang_item(
ty::TraitRef::new(
self.tcx(),
LangItem::AsyncFnKindHelper,
obligation.cause.span,
self.tcx().require_lang_item(
LangItem::AsyncFnKindHelper,
Some(obligation.cause.span),
),
[kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)],
),
));
@ -1241,10 +1247,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.collect();
// We can only make objects from sized types.
let tr = ty::TraitRef::from_lang_item(
let tr = ty::TraitRef::new(
tcx,
LangItem::Sized,
obligation.cause.span,
tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)),
[source],
);
nested.push(predicate_to_obligation(tr.to_predicate(tcx)));
@ -1474,10 +1479,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
cause.clone(),
obligation.recursion_depth + 1,
self_ty.rebind(ty::TraitPredicate {
trait_ref: ty::TraitRef::from_lang_item(
trait_ref: ty::TraitRef::new(
self.tcx(),
LangItem::Destruct,
cause.span,
self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)),
[nested_ty.into(), host_effect_param],
),
polarity: ty::PredicatePolarity::Positive,
@ -1507,10 +1511,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Infer(_)
| ty::Placeholder(_) => {
let predicate = self_ty.rebind(ty::TraitPredicate {
trait_ref: ty::TraitRef::from_lang_item(
trait_ref: ty::TraitRef::new(
self.tcx(),
LangItem::Destruct,
cause.span,
self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)),
[nested_ty.into(), host_effect_param],
),
polarity: ty::PredicatePolarity::Positive,

View File

@ -41,6 +41,7 @@ use rustc_middle::dep_graph::DepNodeIndex;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::_match::MatchAgainstFreshVars;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, PolyProjectionPredicate, ToPredicate};

View File

@ -11,6 +11,7 @@
pub mod specialization_graph;
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use specialization_graph::GraphExt;
use crate::errors::NegativePositiveConflict;

View File

@ -526,8 +526,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
if !subty.has_escaping_bound_vars() {
let cause = self.cause(cause);
let trait_ref =
ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [subty]);
let trait_ref = ty::TraitRef::new(
self.tcx(),
self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
[subty],
);
self.out.push(traits::Obligation::with_depth(
self.tcx(),
cause,

View File

@ -3,7 +3,7 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::query::Providers;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::{Clause, ParamEnvAnd};
use rustc_middle::ty::{FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{FnSig, PolyFnSig, Ty, TyCtxt, TypeFoldable};
use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{
@ -54,7 +54,7 @@ fn type_op_normalize<'tcx, T>(
key: ParamEnvAnd<'tcx, Normalize<T>>,
) -> Result<T, NoSolution>
where
T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx>,
T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
{
let (param_env, Normalize { value }) = key.into_parts();
let Normalized { value, obligations } =

View File

@ -1,7 +0,0 @@
use crate::Interner;
pub trait BoundVars<I: Interner> {
fn bound_vars(&self) -> I::BoundVars;
fn has_no_bound_vars(&self) -> bool;
}

View File

@ -6,8 +6,9 @@ use std::fmt;
use std::hash::Hash;
use crate::fold::{FallibleTypeFolder, TypeFoldable};
use crate::inherent::*;
use crate::visit::{TypeVisitable, TypeVisitor};
use crate::{Interner, PlaceholderLike, UniverseIndex};
use crate::{Interner, UniverseIndex};
/// A "canonicalized" type `V` is one where all free inference
/// variables have been rewritten to "canonical vars". These are

View File

@ -0,0 +1,85 @@
use std::fmt::Debug;
use std::hash::Hash;
use crate::fold::TypeSuperFoldable;
use crate::visit::{Flags, TypeSuperVisitable};
use crate::{
BoundVar, ConstKind, DebruijnIndex, DebugWithInfcx, Interner, RegionKind, TyKind, UniverseIndex,
};
pub trait Ty<I: Interner<Ty = Self>>:
Copy
+ DebugWithInfcx<I>
+ Hash
+ Eq
+ Into<I::GenericArg>
+ IntoKind<Kind = TyKind<I>>
+ TypeSuperVisitable<I>
+ TypeSuperFoldable<I>
+ Flags
{
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
}
pub trait Region<I: Interner<Region = Self>>:
Copy + DebugWithInfcx<I> + Hash + Eq + Into<I::GenericArg> + IntoKind<Kind = RegionKind<I>> + Flags
{
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
fn new_static(interner: I) -> Self;
}
pub trait Const<I: Interner<Const = Self>>:
Copy
+ DebugWithInfcx<I>
+ Hash
+ Eq
+ Into<I::GenericArg>
+ IntoKind<Kind = ConstKind<I>>
+ TypeSuperVisitable<I>
+ TypeSuperFoldable<I>
+ Flags
{
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self;
fn ty(self) -> I::Ty;
}
pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
fn count(&self) -> usize;
}
pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
Copy + DebugWithInfcx<I> + Hash + Eq + IntoIterator<Item = I::GenericArg>
{
fn type_at(self, i: usize) -> I::Ty;
fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
}
pub trait Predicate<I: Interner<Predicate = Self>>:
Copy + Debug + Hash + Eq + TypeSuperVisitable<I> + TypeSuperFoldable<I> + Flags
{
}
/// Common capabilities of placeholder kinds
pub trait PlaceholderLike: Copy + Debug + Hash + Eq {
fn universe(self) -> UniverseIndex;
fn var(self) -> BoundVar;
fn with_updated_universe(self, ui: UniverseIndex) -> Self;
fn new(ui: UniverseIndex, var: BoundVar) -> Self;
}
pub trait IntoKind {
type Kind;
fn kind(self) -> Self::Kind;
}
pub trait BoundVars<I: Interner> {
fn bound_vars(&self) -> I::BoundVars;
fn has_no_bound_vars(&self) -> bool;
}

View File

@ -2,23 +2,17 @@ use smallvec::SmallVec;
use std::fmt::Debug;
use std::hash::Hash;
use crate::fold::TypeSuperFoldable;
use crate::inherent::*;
use crate::ir_print::IrPrint;
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
use crate::{
new, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebugWithInfcx, RegionKind, TyKind,
UniverseIndex,
};
use crate::{CanonicalVarInfo, DebugWithInfcx, TraitRef};
pub trait Interner: Sized + Copy {
pub trait Interner: Sized + Copy + IrPrint<TraitRef<Self>> {
type DefId: Copy + Debug + Hash + Eq;
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
type AdtDef: Copy + Debug + Hash + Eq;
type GenericArgs: Copy
+ DebugWithInfcx<Self>
+ Hash
+ Eq
+ IntoIterator<Item = Self::GenericArg>;
type GenericArgs: GenericArgs<Self>;
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
type Term: Copy + Debug + Hash + Eq;
@ -29,21 +23,12 @@ pub trait Interner: Sized + Copy {
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
// Kinds of tys
type Ty: Copy
+ DebugWithInfcx<Self>
+ Hash
+ Eq
+ Into<Self::GenericArg>
+ IntoKind<Kind = TyKind<Self>>
+ TypeSuperVisitable<Self>
+ TypeSuperFoldable<Self>
+ Flags
+ new::Ty<Self>;
type Ty: Ty<Self>;
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Eq;
type ParamTy: Copy + Debug + Hash + Eq;
type BoundTy: Copy + Debug + Hash + Eq;
type PlaceholderTy: Copy + Debug + Hash + Eq + PlaceholderLike;
type PlaceholderTy: PlaceholderLike;
// Things stored inside of tys
type ErrorGuaranteed: Copy + Debug + Hash + Eq;
@ -53,47 +38,24 @@ pub trait Interner: Sized + Copy {
type Pat: Copy + Debug + Hash + Eq + DebugWithInfcx<Self>;
// Kinds of consts
type Const: Copy
+ DebugWithInfcx<Self>
+ Hash
+ Eq
+ Into<Self::GenericArg>
+ IntoKind<Kind = ConstKind<Self>>
+ ConstTy<Self>
+ TypeSuperVisitable<Self>
+ TypeSuperFoldable<Self>
+ Flags
+ new::Const<Self>;
type Const: Const<Self>;
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
type PlaceholderConst: Copy + Debug + Hash + Eq + PlaceholderLike;
type PlaceholderConst: PlaceholderLike;
type ParamConst: Copy + Debug + Hash + Eq;
type BoundConst: Copy + Debug + Hash + Eq;
type ValueConst: Copy + Debug + Hash + Eq;
type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
// Kinds of regions
type Region: Copy
+ DebugWithInfcx<Self>
+ Hash
+ Eq
+ Into<Self::GenericArg>
+ IntoKind<Kind = RegionKind<Self>>
+ Flags
+ new::Region<Self>;
type Region: Region<Self>;
type EarlyParamRegion: Copy + Debug + Hash + Eq;
type LateParamRegion: Copy + Debug + Hash + Eq;
type BoundRegion: Copy + Debug + Hash + Eq;
type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Eq;
type PlaceholderRegion: Copy + Debug + Hash + Eq + PlaceholderLike;
type PlaceholderRegion: PlaceholderLike;
// Predicates
type Predicate: Copy
+ Debug
+ Hash
+ Eq
+ TypeSuperVisitable<Self>
+ TypeSuperFoldable<Self>
+ Flags;
type Predicate: Predicate<Self>;
type TraitPredicate: Copy + Debug + Hash + Eq;
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
@ -105,26 +67,15 @@ pub trait Interner: Sized + Copy {
type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
}
/// Common capabilities of placeholder kinds
pub trait PlaceholderLike {
fn universe(self) -> UniverseIndex;
fn var(self) -> BoundVar;
type GenericsOf: GenericsOf<Self>;
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
fn with_updated_universe(self, ui: UniverseIndex) -> Self;
fn new(ui: UniverseIndex, var: BoundVar) -> Self;
}
pub trait IntoKind {
type Kind;
fn kind(self) -> Self::Kind;
}
pub trait ConstTy<I: Interner> {
fn ty(self) -> I::Ty;
fn check_and_mk_args(
self,
def_id: Self::DefId,
args: impl IntoIterator<Item: Into<Self::GenericArg>>,
) -> Self::GenericArgs;
}
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`

View File

@ -0,0 +1,28 @@
use std::fmt;
use crate::{Interner, TraitRef};
pub trait IrPrint<T> {
fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
fn print_debug(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
}
macro_rules! define_display_via_print {
($($ty:ident),+ $(,)?) => {
$(
impl<I: Interner> fmt::Display for $ty<I> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
<I as IrPrint<$ty<I>>>::print(self, fmt)
}
}
impl<I: Interner> fmt::Debug for $ty<I> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
<I as IrPrint<$ty<I>>>::print_debug(self, fmt)
}
}
)*
}
}
define_display_via_print!(TraitRef,);

View File

@ -23,13 +23,14 @@ pub mod visit;
#[cfg(feature = "nightly")]
pub mod codec;
pub mod fold;
pub mod new;
pub mod inherent;
pub mod ir_print;
pub mod lift;
pub mod ty_info;
pub mod ty_kind;
#[macro_use]
mod macros;
mod binder;
mod canonical;
mod const_kind;
mod debug;
@ -38,8 +39,8 @@ mod infcx;
mod interner;
mod predicate_kind;
mod region_kind;
mod trait_ref;
pub use binder::*;
pub use canonical::*;
#[cfg(feature = "nightly")]
pub use codec::*;
@ -50,6 +51,7 @@ pub use infcx::InferCtxtLike;
pub use interner::*;
pub use predicate_kind::*;
pub use region_kind::*;
pub use trait_ref::*;
pub use ty_info::*;
pub use ty_kind::*;
pub use AliasKind::*;

View File

@ -0,0 +1,21 @@
/// A trait implemented for all `X<'a>` types that can be safely and
/// efficiently converted to `X<'tcx>` as long as they are part of the
/// provided `TyCtxt<'tcx>`.
/// This can be done, for example, for `Ty<'tcx>` or `GenericArgsRef<'tcx>`
/// by looking them up in their respective interners.
///
/// However, this is still not the best implementation as it does
/// need to compare the components, even for interned values.
/// It would be more efficient if `TypedArena` provided a way to
/// determine whether the address is in the allocated range.
///
/// `None` is returned if the value or one of the components is not part
/// of the provided context.
/// For `Ty`, `None` can be returned if either the type interner doesn't
/// contain the `TyKind` key or if the address of the interned
/// pointer differs. The latter case is possible if a primitive type,
/// e.g., `()` or `u8`, was interned in a different context.
pub trait Lift<I>: std::fmt::Debug {
type Lifted: std::fmt::Debug;
fn lift_to_tcx(self, tcx: I) -> Option<Self::Lifted>;
}

View File

@ -1,15 +0,0 @@
use crate::{BoundVar, DebruijnIndex, Interner};
pub trait Ty<I: Interner<Ty = Self>> {
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
}
pub trait Region<I: Interner<Region = Self>> {
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
fn new_static(interner: I) -> Self;
}
pub trait Const<I: Interner<Const = Self>> {
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self;
}

View File

@ -0,0 +1,109 @@
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
use crate::fold::{FallibleTypeFolder, TypeFoldable};
use crate::inherent::*;
use crate::lift::Lift;
use crate::visit::{TypeVisitable, TypeVisitor};
use crate::Interner;
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where-clause:
/// ```ignore (illustrative)
/// T: Foo<U>
/// ```
/// This would be represented by a trait-reference where the `DefId` is the
/// `DefId` for the trait `Foo` and the args define `T` as parameter 0,
/// and `U` as parameter 1.
///
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the generic parameters.
#[derive(derivative::Derivative)]
#[derivative(
Clone(bound = ""),
Copy(bound = ""),
Hash(bound = ""),
PartialEq(bound = ""),
Eq(bound = "")
)]
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
pub struct TraitRef<I: Interner> {
pub def_id: I::DefId,
pub args: I::GenericArgs,
/// This field exists to prevent the creation of `TraitRef` without
/// calling [`TraitRef::new`].
_use_trait_ref_new_instead: (),
}
impl<I: Interner> TraitRef<I> {
pub fn new(
interner: I,
trait_def_id: I::DefId,
args: impl IntoIterator<Item: Into<I::GenericArg>>,
) -> Self {
let args = interner.check_and_mk_args(trait_def_id, args);
Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
}
pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
let generics = interner.generics_of(trait_id);
TraitRef::new(interner, trait_id, args.into_iter().take(generics.count()))
}
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
/// are the parameters defined on trait.
pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> {
TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id))
}
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
TraitRef::new(
interner,
self.def_id,
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
)
}
#[inline]
pub fn self_ty(&self) -> I::Ty {
self.args.type_at(0)
}
}
// FIXME(compiler-errors): Make this into a `Lift_Generic` impl.
impl<I: Interner, U: Interner> Lift<U> for TraitRef<I>
where
I::DefId: Lift<U, Lifted = U::DefId>,
I::GenericArgs: Lift<U, Lifted = U::GenericArgs>,
{
type Lifted = TraitRef<U>;
fn lift_to_tcx(self, tcx: U) -> Option<Self::Lifted> {
Some(TraitRef {
def_id: self.def_id.lift_to_tcx(tcx)?,
args: self.args.lift_to_tcx(tcx)?,
_use_trait_ref_new_instead: (),
})
}
}
impl<I: Interner> TypeVisitable<I> for TraitRef<I>
where
I::GenericArgs: TypeVisitable<I>,
{
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
self.args.visit_with(visitor)
}
}
impl<I: Interner> TypeFoldable<I> for TraitRef<I>
where
I::GenericArgs: TypeFoldable<I>,
{
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
Ok(TraitRef {
def_id: self.def_id,
args: self.args.try_fold_with(folder)?,
_use_trait_ref_new_instead: (),
})
}
}

View File

@ -47,7 +47,8 @@ use rustc_index::{Idx, IndexVec};
use std::fmt;
use std::ops::ControlFlow;
use crate::{self as ty, BoundVars, Interner, IntoKind, Lrc, TypeFlags};
use crate::inherent::*;
use crate::{self as ty, Interner, Lrc, TypeFlags};
/// This trait is implemented for every type that can be visited,
/// providing the skeleton of the traversal.

View File

@ -52,6 +52,7 @@ use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::Mutability;
use rustc_middle::ty::print::PrintTraitRefExt;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::RustcVersion;
use rustc_span::{

View File

@ -5,6 +5,7 @@ use rustc_hir::{Body, FnDecl};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind};
use rustc_middle::ty::print::PrintTraitRefExt;
use rustc_session::declare_lint_pass;
use rustc_span::def_id::LocalDefId;
use rustc_span::{sym, Span};

View File

@ -402,7 +402,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
tcx,
ObligationCause::dummy_with_span(body.span),
ConstCx::new(tcx, body).param_env,
TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]),
TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
);
let infcx = tcx.infer_ctxt().build();