Lift `TraitRef` into `rustc_type_ir`
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 6f0bd05..ccc45e2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -22,6 +22,7 @@
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 76daa1d6..2740e96 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -532,8 +532,11 @@
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 @@
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 @@
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 @@
}
&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 @@
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 @@
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 dda8f3e..247a288 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_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 4696917..40560a5 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -94,6 +94,12 @@
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 {
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 0b6c60e..8f0aba1 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::{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 8a1dbc1..2873542 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 11bd3e52..de12475 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_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 bc6ecae..38dfa8d 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_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 ff0377d..88ba937 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -758,10 +758,9 @@
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 804413a..ab53a93 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_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 6370794..4d2b225 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::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 01e75d59..ba4ddc1 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_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 0931bb2..62ba9ef 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -30,7 +30,7 @@
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_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index a65b3a4..329d5f3 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_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_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> 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> 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 @@
) -> 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 ed15f61..0464be2 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -140,6 +140,19 @@
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>, ()>;
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index b9dc283..904c0c3 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -39,6 +39,16 @@
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
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index f380aea..04655c5 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -145,6 +145,12 @@
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`
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 73b20f0..12cefc2 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -530,7 +530,7 @@
#[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 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 @@
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 type PlaceholderConst = Placeholder<BoundVar>;
-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 48d900e..2279e27 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::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>>;
@@ -326,76 +326,6 @@
}
}
-/// 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 +338,6 @@
}
}
-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 eecd7dc..d0bae91 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 @@
mod pretty;
pub use self::pretty::*;
+use super::Lift;
+
pub type PrintError = std::fmt::Error;
pub trait Print<'tcx, P> {
@@ -334,3 +337,17 @@
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(())
+ })
+ }
+}
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 46dcd18..14a628a 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_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 @@
}
}
+#[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 @@
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 @@
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 3d9be15..8842ecd 100644
--- a/compiler/rustc_middle/src/ty/region.rs
+++ b/compiler/rustc_middle/src/ty/region.rs
@@ -19,7 +19,7 @@
#[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> 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 })
}
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 78a7071..a7770f7 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> 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>,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 32b9709..a97244d 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -942,7 +942,7 @@
}
}
-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> 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 })
}
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index cbab200..ddfb42a 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -32,10 +32,9 @@
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],
);
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index c437ded..755f5cf 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 e64d2eb..c814301 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -20,6 +20,7 @@
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 7228a9b..b442446 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -4,7 +4,7 @@
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 f886c58..454c7a5 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 @@
}
};
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 @@
)?;
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 @@
// 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`?
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 0fde9dd..083cc0a 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::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 @@
}
};
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 @@
)?;
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 31f9ac1..898f83e 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_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 a687ec0..db53d1e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -538,10 +538,12 @@
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],
),
);
@@ -4044,10 +4046,9 @@
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 0989d49..b72a4b4 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::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 587f2f7..6b9593b 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -973,9 +973,12 @@
//
// 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.
@@ -1018,7 +1021,8 @@
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) {
@@ -1031,7 +1035,7 @@
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() {
@@ -1158,12 +1162,20 @@
// 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
}
@@ -1226,7 +1238,7 @@
obligation.cause.span,
format!("Cannot project an associated type from `{impl_source:?}`"),
);
- return Err(())
+ return Err(());
}
};
@@ -1555,10 +1567,9 @@
// 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));
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 22e0ee3..e9117b9 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 @@
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 @@
} 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 @@
.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 @@
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 @@
| 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 dc00598..a4b0f8b 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::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 390e711..fe3f66f 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 28ee76f..1531e2f 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -525,8 +525,11 @@
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_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
deleted file mode 100644
index 57f961a..0000000
--- a/compiler/rustc_type_ir/src/binder.rs
+++ /dev/null
@@ -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;
-}
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index f041c58..f7c7ec2 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -6,8 +6,9 @@
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 0000000..84aeeae
--- /dev/null
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -0,0 +1,49 @@
+use crate::{BoundVar, DebruijnIndex, Interner, UniverseIndex};
+
+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;
+
+ fn ty(self) -> I::Ty;
+}
+
+pub trait GenericsOf<I: Interner> {
+ fn count(&self) -> usize;
+}
+
+pub trait GenericArgs<I: Interner> {
+ fn type_at(self, i: usize) -> I::Ty;
+
+ fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
+}
+
+/// Common capabilities of placeholder kinds
+pub trait PlaceholderLike {
+ 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;
+}
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 70f7e58..32f07b1 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -3,13 +3,12 @@
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, ConstKind, DebugWithInfcx, RegionKind, TraitRef, TyKind};
-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;
@@ -18,7 +17,8 @@
+ DebugWithInfcx<Self>
+ Hash
+ Eq
- + IntoIterator<Item = Self::GenericArg>;
+ + IntoIterator<Item = Self::GenericArg>
+ + GenericArgs<Self>;
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
type Term: Copy + Debug + Hash + Eq;
@@ -38,7 +38,7 @@
+ TypeSuperVisitable<Self>
+ TypeSuperFoldable<Self>
+ Flags
- + new::Ty<Self>;
+ + 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;
@@ -59,11 +59,10 @@
+ Eq
+ Into<Self::GenericArg>
+ IntoKind<Kind = ConstKind<Self>>
- + ConstTy<Self>
+ TypeSuperVisitable<Self>
+ TypeSuperFoldable<Self>
+ Flags
- + new::Const<Self>;
+ + Const<Self>;
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
type PlaceholderConst: Copy + Debug + Hash + Eq + PlaceholderLike;
type ParamConst: Copy + Debug + Hash + Eq;
@@ -79,7 +78,7 @@
+ Into<Self::GenericArg>
+ IntoKind<Kind = RegionKind<Self>>
+ Flags
- + new::Region<Self>;
+ + Region<Self>;
type EarlyParamRegion: Copy + Debug + Hash + Eq;
type LateParamRegion: Copy + Debug + Hash + Eq;
type BoundRegion: Copy + Debug + Hash + Eq;
@@ -105,26 +104,15 @@
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`
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 0000000..89c30fc
--- /dev/null
+++ b/compiler/rustc_type_ir/src/ir_print.rs
@@ -0,0 +1,21 @@
+use std::fmt;
+
+use crate::{Interner, TraitRef};
+
+pub trait IrPrint<T> {
+ fn print(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)
+ }
+ }
+ )*
+ }
+}
+
+define_display_via_print!(TraitRef,);
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index a978a30..62efa32 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -23,14 +23,14 @@
#[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;
-pub mod lift;
#[macro_use]
mod macros;
-mod binder;
mod canonical;
mod const_kind;
mod debug;
@@ -39,8 +39,8 @@
mod interner;
mod predicate_kind;
mod region_kind;
+mod trait_ref;
-pub use binder::*;
pub use canonical::*;
#[cfg(feature = "nightly")]
pub use codec::*;
@@ -51,6 +51,7 @@
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::*;
@@ -58,7 +59,6 @@
pub use InferTy::*;
pub use RegionKind::*;
pub use TyKind::*;
-pub use lift::*;
rustc_index::newtype_index! {
/// A [De Bruijn index][dbi] is a standard means of representing
diff --git a/compiler/rustc_type_ir/src/lift.rs b/compiler/rustc_type_ir/src/lift.rs
new file mode 100644
index 0000000..839da10
--- /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<I>: std::fmt::Debug {
+ type Lifted: std::fmt::Debug;
+ fn lift_to_tcx(self, tcx: I) -> Option<Self::Lifted>;
+}
diff --git a/compiler/rustc_type_ir/src/new.rs b/compiler/rustc_type_ir/src/new.rs
deleted file mode 100644
index 1572a64..0000000
--- a/compiler/rustc_type_ir/src/new.rs
+++ /dev/null
@@ -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;
-}
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 0000000..ad1350d
--- /dev/null
+++ b/compiler/rustc_type_ir/src/trait_ref.rs
@@ -0,0 +1,130 @@
+use std::fmt;
+
+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`].
+ pub(super) _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)
+ }
+}
+
+impl<I: Interner> fmt::Debug for TraitRef<I> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let TraitRef { def_id, args, _use_trait_ref_new_instead: () } = self;
+ let mut args = args.into_iter().peekable();
+ write!(f, "{def_id:?}")?;
+ if args.peek().is_some() {
+ write!(f, "<")?;
+ for (i, arg) in args.enumerate() {
+ if i > 0 {
+ write!(f, ", ")?;
+ }
+ write!(f, "{arg:#?}")?;
+ }
+ write!(f, ">")?;
+ }
+ Ok(())
+ }
+}
+
+// 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: (),
+ })
+ }
+}
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 2f588c6..3d4125f 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -47,7 +47,8 @@
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 075d94b..b4e62e3 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -52,6 +52,7 @@
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 18f4e51..2c2daac 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_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 d8d26e2..95851a2 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 @@
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();