diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 6f0bd054329..ccc45e2829a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -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, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 76daa1d689c..2740e9689c5 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -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], ); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index dda8f3ed87d..247a2889dc5 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -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, diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 4696917554f..40560a5ad79 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -94,6 +94,12 @@ into_diag_arg_using_display!( ErrCode, ); +impl IntoDiagArg for rustc_type_ir::TraitRef { + 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 { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 0b6c60e4ba2..8f0aba1c38c 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -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; diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 8a1dbc1f942..28735429210 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -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; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 11bd3e5282d..de12475678c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -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}; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index bc6ecae05ee..38dfa8d57d3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -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}; diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index ff0377d3f2d..88ba937e4b5 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -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], ), )); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 42429812d9f..d1891a032e1 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -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; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 89cdc3e45a5..46310941113 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -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::{ diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index e3476d8c394..dbd165c093a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -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}; diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 0931bb29963..62ba9ef5c11 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -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}; diff --git a/compiler/rustc_macros/src/lift.rs b/compiler/rustc_macros/src/lift.rs index f7a84ba1510..d41ceb29816 100644 --- a/compiler/rustc_macros/src/lift.rs +++ b/compiler/rustc_macros/src/lift.rs @@ -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; diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index f70ef51107f..817ac594627 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -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 { Some(self) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index a65b3a41ade..329d5f34a21 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -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>>); -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> 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> for Const<'tcx> { +impl<'tcx> rustc_type_ir::inherent::Const> for Const<'tcx> { fn new_anon_bound( tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, @@ -189,6 +183,10 @@ impl<'tcx> rustc_type_ir::new::Const> for Const<'tcx> { ) -> Self { Const::new_bound(tcx, debruijn, var, ty) } + + fn ty(self) -> Ty<'tcx> { + self.ty() + } } impl<'tcx> Const<'tcx> { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1a55e492688..0464be2df06 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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::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>>, + ) -> ty::GenericArgsRef<'tcx> { + self.check_and_mk_args(def_id, args) + } } type InternedSet<'tcx, T> = ShardedHashMap, ()>; @@ -917,7 +932,7 @@ impl<'tcx> TyCtxt<'tcx> { ) } - pub fn lift>(self, value: T) -> Option { + pub fn lift>>(self, value: T) -> Option { 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; -} - macro_rules! nop_lift { ($set:ident; $ty:ty => $lifted:ty) => { - impl<'a, 'tcx> Lift<'tcx> for $ty { + impl<'a, 'tcx> Lift> for $ty { type Lifted = $lifted; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { // 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> for &'a List<$ty> { type Lifted = &'tcx List<$lifted>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { // 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> for &'a [$ty] { type Lifted = &'tcx [$lifted]; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { if self.is_empty() { diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 4a613083ef7..904c0c332a8 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -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> 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> for GenericArg<'a> { type Lifted = GenericArg<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index f380aeaae0e..04655c5d20b 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -145,6 +145,12 @@ pub struct Generics { pub host_effect_index: Option, } +impl<'tcx> rustc_type_ir::inherent::GenericsOf> 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` diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 73b20f0485b..12cefc23233 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -530,7 +530,7 @@ pub struct CReaderCacheKey { #[rustc_pass_by_value] pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo>>); -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 { pub type PlaceholderRegion = Placeholder; -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; -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; -impl PlaceholderLike for PlaceholderConst { +impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderConst { fn universe(self) -> UniverseIndex { self.universe } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 48d900ef0c9..5387036d409 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -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>; pub type ClauseKind<'tcx> = IrClauseKind>; pub type PredicateKind<'tcx> = IrPredicateKind>; @@ -30,6 +30,8 @@ pub struct Predicate<'tcx>( pub(super) Interned<'tcx, WithCachedTypeInfo>>>, ); +impl<'tcx> rustc_type_ir::inherent::Predicate> 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> { } } -/// 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 -/// ``` -/// 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`, 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>>, - ) -> 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>>, - ) -> 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` 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) diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index eecd7dc6422..e7589737d64 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -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, tcx: TyCtxt<'_>) -> Str format!("module `{}`", tcx.def_path_str(def_id)) } } + +impl rustc_type_ir::ir_print::IrPrint for TyCtxt<'_> +where + T: Copy + for<'a, 'tcx> Lift, 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)) + } +} diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 46dcd18cfbb..14a628ab064 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -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)); } diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 3d9be15310f..8842ecd12e9 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -19,7 +19,7 @@ pub type RegionKind<'tcx> = IrRegionKind>; #[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> for Region<'tcx> { +impl<'tcx> rustc_type_ir::inherent::Region> 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 }) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 14a77d4b37e..a7770f71926 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -132,12 +132,6 @@ impl<'tcx> DebugWithInfcx> 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> for Ty<'tcx> { fn fmt>>( this: WithInfcx<'_, Infcx, &Self>, @@ -478,7 +472,7 @@ TrivialTypeTraversalAndLiftImpls! { /////////////////////////////////////////////////////////////////////////// // Lift implementations -impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option { +impl<'tcx, T: Lift>> Lift> for Option { type Lifted = Option; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { Some(match self { @@ -488,7 +482,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option { } } -impl<'a, 'tcx> Lift<'tcx> for Term<'a> { +impl<'a, 'tcx> Lift> for Term<'a> { type Lifted = ty::Term<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { Some( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 32b970962e8..a97244dda9a 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -942,7 +942,7 @@ where } } -impl<'tcx, T> rustc_type_ir::BoundVars> for ty::Binder<'tcx, T> { +impl<'tcx, T> rustc_type_ir::inherent::BoundVars> for ty::Binder<'tcx, T> { fn bound_vars(&self) -> &'tcx List { self.bound_vars } @@ -1812,7 +1812,7 @@ impl<'tcx> Ty<'tcx> { } } -impl<'tcx> rustc_type_ir::new::Ty> for Ty<'tcx> { +impl<'tcx> rustc_type_ir::inherent::Ty> 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 }) } diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index cbab2006186..ddfb42a6f4a 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -32,10 +32,9 @@ fn custom_coerce_unsize_info<'tcx>( source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> Result { - 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], ); diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index c437dedbbbc..755f5cfa5a3 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -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. diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e64d2eba06b..c8143015583 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -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}; diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 7228a9ba016..b442446f79b 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -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)] diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index f886c588650..454c7a5f00f 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -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` 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`? diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 0fde9dd4cd6..083cc0aa3c2 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -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], + ) }, ); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index c46cee36cf7..040ce450aaf 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -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}; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 3defc03e7f0..597effcbbf0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index de8ec17b113..cdde12af8ea 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -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, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 0aafc1a2efe..1e78484f305 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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` 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)); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 279d96dec72..e9948bf1f71 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -34,7 +34,9 @@ where } } -pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable> + Lift<'tcx> + Copy { +pub trait Normalizable<'tcx>: + fmt::Debug + TypeFoldable> + Lift> + Copy +{ fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 0b91dd72e3b..69d11b45e60 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -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, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 50353a1fd2f..7aa2aabed7f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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}; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 390e711a18d..fe3f66f3a3f 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -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; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index ebcda61f2ad..2c2b84d4a87 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -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, diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 01b9a5640b8..b6a59a4ad3a 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -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>, ) -> Result where - T: fmt::Debug + TypeFoldable> + Lift<'tcx>, + T: fmt::Debug + TypeFoldable>, { let (param_env, Normalize { value }) = key.into_parts(); let Normalized { value, obligations } = diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs deleted file mode 100644 index 57f961ac97e..00000000000 --- a/compiler/rustc_type_ir/src/binder.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::Interner; - -pub trait BoundVars { - fn bound_vars(&self) -> I::BoundVars; - - fn has_no_bound_vars(&self) -> bool; -} diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index f041c5831fc..f7c7ec242c1 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -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 diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs new file mode 100644 index 00000000000..0fd34e0a65f --- /dev/null +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -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>: + Copy + + DebugWithInfcx + + Hash + + Eq + + Into + + IntoKind> + + TypeSuperVisitable + + TypeSuperFoldable + + Flags +{ + fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self; +} + +pub trait Region>: + Copy + DebugWithInfcx + Hash + Eq + Into + IntoKind> + Flags +{ + fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self; + + fn new_static(interner: I) -> Self; +} + +pub trait Const>: + Copy + + DebugWithInfcx + + Hash + + Eq + + Into + + IntoKind> + + TypeSuperVisitable + + TypeSuperFoldable + + Flags +{ + fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self; + + fn ty(self) -> I::Ty; +} + +pub trait GenericsOf> { + fn count(&self) -> usize; +} + +pub trait GenericArgs>: + Copy + DebugWithInfcx + Hash + Eq + IntoIterator +{ + fn type_at(self, i: usize) -> I::Ty; + + fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs; +} + +pub trait Predicate>: + Copy + Debug + Hash + Eq + TypeSuperVisitable + TypeSuperFoldable + 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 { + fn bound_vars(&self) -> I::BoundVars; + + fn has_no_bound_vars(&self) -> bool; +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 70f7e58be19..c8bd7fea11b 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -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> { type DefId: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; type AdtDef: Copy + Debug + Hash + Eq; - type GenericArgs: Copy - + DebugWithInfcx - + Hash - + Eq - + IntoIterator; + type GenericArgs: GenericArgs; type GenericArg: Copy + DebugWithInfcx + Hash + Eq; type Term: Copy + Debug + Hash + Eq; @@ -29,21 +23,12 @@ pub trait Interner: Sized + Copy { type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator>; // Kinds of tys - type Ty: Copy - + DebugWithInfcx - + Hash - + Eq - + Into - + IntoKind> - + TypeSuperVisitable - + TypeSuperFoldable - + Flags - + new::Ty; + type Ty: Ty; type Tys: Copy + Debug + Hash + Eq + IntoIterator; type AliasTy: Copy + DebugWithInfcx + 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; // Kinds of consts - type Const: Copy - + DebugWithInfcx - + Hash - + Eq - + Into - + IntoKind> - + ConstTy - + TypeSuperVisitable - + TypeSuperFoldable - + Flags - + new::Const; + type Const: Const; type AliasConst: Copy + DebugWithInfcx + 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 + Hash + Eq; // Kinds of regions - type Region: Copy - + DebugWithInfcx - + Hash - + Eq - + Into - + IntoKind> - + Flags - + new::Region; + type Region: Region; type EarlyParamRegion: Copy + Debug + Hash + Eq; type LateParamRegion: Copy + Debug + Hash + Eq; type BoundRegion: Copy + Debug + Hash + Eq; type InferRegion: Copy + DebugWithInfcx + Hash + Eq; - type PlaceholderRegion: Copy + Debug + Hash + Eq + PlaceholderLike; + type PlaceholderRegion: PlaceholderLike; // Predicates - type Predicate: Copy - + Debug - + Hash - + Eq - + TypeSuperVisitable - + TypeSuperFoldable - + Flags; + type Predicate: Predicate; 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 + Flags; fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo]) -> Self::CanonicalVars; -} -/// Common capabilities of placeholder kinds -pub trait PlaceholderLike { - fn universe(self) -> UniverseIndex; - fn var(self) -> BoundVar; + type GenericsOf: GenericsOf; + 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 { - fn ty(self) -> I::Ty; + fn check_and_mk_args( + self, + def_id: Self::DefId, + args: impl IntoIterator>, + ) -> Self::GenericArgs; } /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs new file mode 100644 index 00000000000..84e889b486a --- /dev/null +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -0,0 +1,28 @@ +use std::fmt; + +use crate::{Interner, TraitRef}; + +pub trait IrPrint { + 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 fmt::Display for $ty { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + >>::print(self, fmt) + } + } + + impl fmt::Debug for $ty { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + >>::print_debug(self, fmt) + } + } + )* + } +} + +define_display_via_print!(TraitRef,); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index ef7437c2542..62efa32c9f2 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -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::*; diff --git a/compiler/rustc_type_ir/src/lift.rs b/compiler/rustc_type_ir/src/lift.rs new file mode 100644 index 00000000000..839da10db5e --- /dev/null +++ b/compiler/rustc_type_ir/src/lift.rs @@ -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: std::fmt::Debug { + type Lifted: std::fmt::Debug; + fn lift_to_tcx(self, tcx: I) -> Option; +} diff --git a/compiler/rustc_type_ir/src/new.rs b/compiler/rustc_type_ir/src/new.rs deleted file mode 100644 index 1572a641d06..00000000000 --- a/compiler/rustc_type_ir/src/new.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::{BoundVar, DebruijnIndex, Interner}; - -pub trait Ty> { - fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self; -} - -pub trait Region> { - fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self; - - fn new_static(interner: I) -> Self; -} - -pub trait Const> { - fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self; -} diff --git a/compiler/rustc_type_ir/src/trait_ref.rs b/compiler/rustc_type_ir/src/trait_ref.rs new file mode 100644 index 00000000000..4bd513ab7e1 --- /dev/null +++ b/compiler/rustc_type_ir/src/trait_ref.rs @@ -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 +/// ``` +/// 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`, 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 { + 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 TraitRef { + pub fn new( + interner: I, + trait_def_id: I::DefId, + args: impl IntoIterator>, + ) -> 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 { + 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` where `Pi` + /// are the parameters defined on trait. + pub fn identity(interner: I, def_id: I::DefId) -> TraitRef { + 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 Lift for TraitRef +where + I::DefId: Lift, + I::GenericArgs: Lift, +{ + type Lifted = TraitRef; + + fn lift_to_tcx(self, tcx: U) -> Option { + Some(TraitRef { + def_id: self.def_id.lift_to_tcx(tcx)?, + args: self.args.lift_to_tcx(tcx)?, + _use_trait_ref_new_instead: (), + }) + } +} + +impl TypeVisitable for TraitRef +where + I::GenericArgs: TypeVisitable, +{ + fn visit_with>(&self, visitor: &mut V) -> V::Result { + self.args.visit_with(visitor) + } +} + +impl TypeFoldable for TraitRef +where + I::GenericArgs: TypeFoldable, +{ + fn try_fold_with>(self, folder: &mut F) -> Result { + Ok(TraitRef { + def_id: self.def_id, + args: self.args.try_fold_with(folder)?, + _use_trait_ref_new_instead: (), + }) + } +} diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 2f588c67f56..3d4125f600e 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -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. diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 075d94bd337..b4e62e39d8d 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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::{ diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 18f4e51ebd6..2c2daac0234 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -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}; diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index d8d26e21369..95851a2eed8 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -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();