diff options
Diffstat (limited to 'compiler/rustc_middle/src/ty')
20 files changed, 590 insertions, 1066 deletions
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 9badf65115e..6d7b6259747 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -15,7 +15,7 @@ pub enum PointerCoercion { /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer. /// It cannot convert a closure that requires unsafe. - ClosureFnPointer(hir::Unsafety), + ClosureFnPointer(hir::Safety), /// Go from a mut raw pointer to a const raw pointer. MutToConstPointer, diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index a65b3a41ade..9dc30447f0e 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -7,8 +7,7 @@ use rustc_hir as hir; 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::{self as ir, TypeFlags, WithCachedTypeInfo}; mod int; mod kind; @@ -20,7 +19,8 @@ use rustc_span::Span; use rustc_span::DUMMY_SP; pub use valtree::*; -pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>; +pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>; +pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>; #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); @@ -30,7 +30,7 @@ rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); #[rustc_pass_by_value] pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>); -impl<'tcx> IntoKind for Const<'tcx> { +impl<'tcx> rustc_type_ir::inherent::IntoKind for Const<'tcx> { type Kind = ConstKind<'tcx>; fn kind(self) -> ConstKind<'tcx> { @@ -48,12 +48,6 @@ impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> { } } -impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> { - fn ty(self) -> Ty<'tcx> { - self.ty() - } -} - /// Typed constant value. #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable)] @@ -180,7 +174,7 @@ impl<'tcx> Const<'tcx> { } } -impl<'tcx> rustc_type_ir::new::Const<TyCtxt<'tcx>> for Const<'tcx> { +impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> { fn new_anon_bound( tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, @@ -189,6 +183,18 @@ impl<'tcx> rustc_type_ir::new::Const<TyCtxt<'tcx>> for Const<'tcx> { ) -> Self { Const::new_bound(tcx, debruijn, var, ty) } + + fn new_unevaluated( + interner: TyCtxt<'tcx>, + uv: ty::UnevaluatedConst<'tcx>, + ty: Ty<'tcx>, + ) -> Self { + Const::new_unevaluated(interner, uv, ty) + } + + fn ty(self) -> Ty<'tcx> { + self.ty() + } } impl<'tcx> Const<'tcx> { diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 7e49b0ac915..d7ae050ed4d 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -1,30 +1,15 @@ use super::Const; use crate::mir; use crate::ty::abstract_const::CastKind; -use crate::ty::GenericArgsRef; use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt}; -use rustc_hir::def_id::DefId; -use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; +use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; -/// An unevaluated (potentially generic) constant used in the type-system. -#[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)] -#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] -pub struct UnevaluatedConst<'tcx> { - pub def: DefId, - pub args: GenericArgsRef<'tcx>, -} - -impl rustc_errors::IntoDiagArg for UnevaluatedConst<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - format!("{self:?}").into_diag_arg() - } -} - -impl<'tcx> UnevaluatedConst<'tcx> { +#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)] +impl<'tcx> ty::UnevaluatedConst<'tcx> { /// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this /// hurts performance. #[inline] - pub(crate) fn prepare_for_eval( + fn prepare_for_eval( self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -55,13 +40,6 @@ impl<'tcx> UnevaluatedConst<'tcx> { } } -impl<'tcx> UnevaluatedConst<'tcx> { - #[inline] - pub fn new(def: DefId, args: GenericArgsRef<'tcx>) -> UnevaluatedConst<'tcx> { - UnevaluatedConst { def, args } - } -} - #[derive(Copy, Clone, Eq, PartialEq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] pub enum Expr<'tcx> { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1a55e492688..69681930be6 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}; @@ -24,6 +26,7 @@ use crate::traits::solve; use crate::traits::solve::{ ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData, }; +use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern, @@ -73,6 +76,7 @@ use rustc_type_ir::TyKind::*; use rustc_type_ir::WithCachedTypeInfo; use rustc_type_ir::{CollectAndApply, Interner, TypeFlags}; +use std::assert_matches::assert_matches; use std::borrow::Borrow; use std::cmp::Ordering; use std::fmt; @@ -85,21 +89,26 @@ use std::ops::{Bound, Deref}; #[allow(rustc::usage_of_ty_tykind)] impl<'tcx> Interner for TyCtxt<'tcx> { type DefId = DefId; - type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>; type AdtDef = ty::AdtDef<'tcx>; + type GenericArgs = ty::GenericArgsRef<'tcx>; + type OwnItemArgs = &'tcx [ty::GenericArg<'tcx>]; type GenericArg = ty::GenericArg<'tcx>; type Term = ty::Term<'tcx>; type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>; type BoundVars = &'tcx List<ty::BoundVariableKind>; type BoundVar = ty::BoundVariableKind; + type CanonicalVars = CanonicalVarInfos<'tcx>; + type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; + type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>; + type ExternalConstraints = ExternalConstraints<'tcx>; + type GoalEvaluationSteps = &'tcx [solve::inspect::GoalEvaluationStep<TyCtxt<'tcx>>]; type Ty = Ty<'tcx>; - type Pat = Pattern<'tcx>; type Tys = &'tcx List<Ty<'tcx>>; - type AliasTy = ty::AliasTy<'tcx>; + type FnInputTys = &'tcx [Ty<'tcx>]; type ParamTy = ParamTy; type BoundTy = ty::BoundTy; type PlaceholderTy = ty::PlaceholderType; @@ -109,6 +118,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type PolyFnSig = PolyFnSig<'tcx>; type AllocId = crate::mir::interpret::AllocId; + type Pat = Pattern<'tcx>; + type Safety = hir::Safety; + type Abi = abi::Abi; + type Const = ty::Const<'tcx>; type AliasConst = ty::UnevaluatedConst<'tcx>; type PlaceholderConst = ty::PlaceholderConst; @@ -119,11 +132,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Region = Region<'tcx>; type EarlyParamRegion = ty::EarlyParamRegion; - type BoundRegion = ty::BoundRegion; type LateParamRegion = ty::LateParamRegion; + type BoundRegion = ty::BoundRegion; type InferRegion = ty::RegionVid; type PlaceholderRegion = ty::PlaceholderRegion; + type ParamEnv = ty::ParamEnv<'tcx>; type Predicate = Predicate<'tcx>; type TraitPredicate = ty::TraitPredicate<'tcx>; type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>; @@ -131,13 +145,106 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ProjectionPredicate = ty::ProjectionPredicate<'tcx>; type NormalizesTo = ty::NormalizesTo<'tcx>; type SubtypePredicate = ty::SubtypePredicate<'tcx>; + type CoercePredicate = ty::CoercePredicate<'tcx>; type ClosureKind = ty::ClosureKind; + type Clauses = ty::Clauses<'tcx>; fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars { self.mk_canonical_var_infos(infos) } + + type GenericsOf = &'tcx ty::Generics; + + fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics { + self.generics_of(def_id) + } + + fn type_of_instantiated(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> Ty<'tcx> { + self.type_of(def_id).instantiate(self, args) + } + + fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind { + match self.def_kind(alias.def_id) { + DefKind::AssocTy => { + if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) + { + ty::Inherent + } else { + ty::Projection + } + } + DefKind::OpaqueTy => ty::Opaque, + DefKind::TyAlias => ty::Weak, + kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), + } + } + + fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind { + match self.def_kind(alias.def_id) { + DefKind::AssocTy => { + if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) + { + ty::AliasTermKind::InherentTy + } else { + ty::AliasTermKind::ProjectionTy + } + } + DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, + DefKind::TyAlias => ty::AliasTermKind::WeakTy, + DefKind::AssocConst => ty::AliasTermKind::ProjectionConst, + DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst, + kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), + } + } + + fn trait_ref_and_own_args_for_alias( + self, + def_id: Self::DefId, + args: Self::GenericArgs, + ) -> (rustc_type_ir::TraitRef<Self>, Self::OwnItemArgs) { + assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst); + let trait_def_id = self.parent(def_id); + assert_matches!(self.def_kind(trait_def_id), DefKind::Trait); + let trait_generics = self.generics_of(trait_def_id); + ( + ty::TraitRef::new(self, trait_def_id, args.truncate_to(self, trait_generics)), + &args[trait_generics.count()..], + ) + } + + fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs { + self.mk_args(args) + } + + fn mk_args_from_iter(self, args: impl Iterator<Item = Self::GenericArg>) -> Self::GenericArgs { + self.mk_args_from_iter(args) + } + + 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) + } + + fn parent(self, def_id: Self::DefId) -> Self::DefId { + self.parent(def_id) + } +} + +impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi { + fn is_rust(self) -> bool { + matches!(self, abi::Abi::Rust) + } +} + +impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety { + fn prefix_str(self) -> &'static str { + self.prefix_str() + } } type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>; @@ -917,7 +1024,7 @@ impl<'tcx> TyCtxt<'tcx> { ) } - pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> { + pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> { value.lift_to_tcx(self) } @@ -1524,31 +1631,9 @@ impl<'tcx> TyCtxt<'tcx> { } } -/// A trait implemented for all `X<'a>` types that can be safely and -/// efficiently converted to `X<'tcx>` as long as they are part of the -/// provided `TyCtxt<'tcx>`. -/// This can be done, for example, for `Ty<'tcx>` or `GenericArgsRef<'tcx>` -/// by looking them up in their respective interners. -/// -/// However, this is still not the best implementation as it does -/// need to compare the components, even for interned values. -/// It would be more efficient if `TypedArena` provided a way to -/// determine whether the address is in the allocated range. -/// -/// `None` is returned if the value or one of the components is not part -/// of the provided context. -/// For `Ty`, `None` can be returned if either the type interner doesn't -/// contain the `TyKind` key or if the address of the interned -/// pointer differs. The latter case is possible if a primitive type, -/// e.g., `()` or `u8`, was interned in a different context. -pub trait Lift<'tcx>: fmt::Debug { - type Lifted: fmt::Debug + 'tcx; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>; -} - macro_rules! nop_lift { ($set:ident; $ty:ty => $lifted:ty) => { - impl<'a, 'tcx> Lift<'tcx> for $ty { + impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty { type Lifted = $lifted; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { // Assert that the set has the right type. @@ -1583,7 +1668,7 @@ macro_rules! nop_lift { macro_rules! nop_list_lift { ($set:ident; $ty:ty => $lifted:ty) => { - impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> { + impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> { type Lifted = &'tcx List<$lifted>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { // Assert that the set has the right type. @@ -1621,7 +1706,7 @@ nop_list_lift! {args; GenericArg<'a> => GenericArg<'tcx>} macro_rules! nop_slice_lift { ($ty:ty => $lifted:ty) => { - impl<'a, 'tcx> Lift<'tcx> for &'a [$ty] { + impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a [$ty] { type Lifted = &'tcx [$lifted]; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { if self.is_empty() { @@ -1945,11 +2030,8 @@ impl<'tcx> TyCtxt<'tcx> { /// that is, a `fn` type that is equivalent in every way for being /// unsafe. pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> { - assert_eq!(sig.unsafety(), hir::Unsafety::Normal); - Ty::new_fn_ptr( - self, - sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }), - ) + assert_eq!(sig.safety(), hir::Safety::Safe); + Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })) } /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name` @@ -2006,20 +2088,16 @@ impl<'tcx> TyCtxt<'tcx> { /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then /// you would get a `fn(u32, i32)`. /// `unsafety` determines the unsafety of the fn signature. If you pass - /// `hir::Unsafety::Unsafe` in the previous example, then you would get + /// `hir::Safety::Unsafe` in the previous example, then you would get /// an `unsafe fn (u32, i32)`. /// It cannot convert a closure that requires unsafe. - pub fn signature_unclosure( - self, - sig: PolyFnSig<'tcx>, - unsafety: hir::Unsafety, - ) -> PolyFnSig<'tcx> { + pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> { sig.map_bound(|s| { let params = match s.inputs()[0].kind() { ty::Tuple(params) => *params, _ => bug!(), }; - self.mk_fn_sig(params, s.output(), s.c_variadic, unsafety, abi::Abi::Rust) + self.mk_fn_sig(params, s.output(), s.c_variadic, safety, abi::Abi::Rust) }) } @@ -2286,7 +2364,7 @@ impl<'tcx> TyCtxt<'tcx> { inputs: I, output: I::Item, c_variadic: bool, - unsafety: hir::Unsafety, + safety: hir::Safety, abi: abi::Abi, ) -> T::Output where @@ -2296,7 +2374,7 @@ impl<'tcx> TyCtxt<'tcx> { T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig { inputs_and_output: self.mk_type_list(xs), c_variadic, - unsafety, + safety, abi, }) } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 71437ce1df9..99d703be873 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -34,7 +34,7 @@ pub enum TypeError<'tcx> { Mismatch, ConstnessMismatch(ExpectedFound<ty::BoundConstness>), PolarityMismatch(ExpectedFound<ty::PredicatePolarity>), - UnsafetyMismatch(ExpectedFound<hir::Unsafety>), + SafetyMismatch(ExpectedFound<hir::Safety>), AbiMismatch(ExpectedFound<abi::Abi>), Mutability, ArgumentMutability(usize), @@ -107,7 +107,7 @@ impl<'tcx> TypeError<'tcx> { format!("expected {} polarity, found {} polarity", values.expected, values.found) .into() } - UnsafetyMismatch(values) => { + SafetyMismatch(values) => { format!("expected {} fn, found {} fn", values.expected, values.found).into() } AbiMismatch(values) => { @@ -204,7 +204,7 @@ impl<'tcx> TypeError<'tcx> { pub fn must_include_note(self) -> bool { use self::TypeError::*; match self { - CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_) + CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | ConstnessMismatch(_) | PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_) | IntMismatch(_) | FloatMismatch(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false, diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 8d7489f5f7e..7508f0080cc 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -281,13 +281,13 @@ impl DeepRejectCtxt { } ty::FnPtr(obl_sig) => match k { ty::FnPtr(impl_sig) => { - let ty::FnSig { inputs_and_output, c_variadic, unsafety, abi } = + let ty::FnSig { inputs_and_output, c_variadic, safety, abi } = obl_sig.skip_binder(); let impl_sig = impl_sig.skip_binder(); abi == impl_sig.abi && c_variadic == impl_sig.c_variadic - && unsafety == impl_sig.unsafety + && safety == impl_sig.safety && inputs_and_output.len() == impl_sig.inputs_and_output.len() && iter::zip(inputs_and_output, impl_sig.inputs_and_output) .all(|(obl, imp)| self.types_may_unify(obl, imp)) diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 0dc835671d5..4de7d532c96 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -294,10 +294,10 @@ impl FlagComputation { self.add_ty(b); } ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty, + projection_term, term, })) => { - self.add_alias_ty(projection_ty); + self.add_alias_term(projection_term); self.add_term(term); } ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { @@ -313,7 +313,7 @@ impl FlagComputation { } ty::PredicateKind::Ambiguous => {} ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) => { - self.add_alias_ty(alias); + self.add_alias_term(alias); self.add_term(term); } ty::PredicateKind::AliasRelate(t1, t2, _) => { @@ -410,6 +410,10 @@ impl FlagComputation { self.add_args(alias_ty.args); } + fn add_alias_term(&mut self, alias_term: ty::AliasTerm<'_>) { + self.add_args(alias_term.args); + } + fn add_args(&mut self, args: &[GenericArg<'_>]) { for kind in args { match kind.unpack() { diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 4a613083ef7..38b2987399a 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -11,6 +11,7 @@ use rustc_ast_ir::walk_visitable_list; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; +use rustc_macros::extension; use rustc_macros::{ Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, }; @@ -25,6 +26,8 @@ use std::num::NonZero; use std::ops::Deref; use std::ptr::NonNull; +pub type GenericArgKind<'tcx> = rustc_type_ir::GenericArgKind<TyCtxt<'tcx>>; + /// An entity in the Rust type system, which can be one of /// several kinds (types, lifetimes, and consts). /// To reduce memory usage, a `GenericArg` is an interned pointer, @@ -39,6 +42,24 @@ pub struct GenericArg<'tcx> { marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>, } +impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> { + fn type_at(self, i: usize) -> Ty<'tcx> { + self.type_at(i) + } + + fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> { + GenericArgs::identity_for_item(tcx, def_id) + } +} + +impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> { + type Kind = GenericArgKind<'tcx>; + + fn kind(self) -> Self::Kind { + self.unpack() + } +} + #[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 @@ -69,13 +90,7 @@ const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; const CONST_TAG: usize = 0b10; -#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, HashStable)] -pub enum GenericArgKind<'tcx> { - Lifetime(ty::Region<'tcx>), - Type(Ty<'tcx>), - Const(ty::Const<'tcx>), -} - +#[extension(trait GenericArgPackExt<'tcx>)] impl<'tcx> GenericArgKind<'tcx> { #[inline] fn pack(self) -> GenericArg<'tcx> { @@ -205,7 +220,7 @@ impl<'tcx> GenericArg<'tcx> { } } -impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { +impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> { type Lifted = GenericArg<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index f380aeaae0e..cfaca05c2f0 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<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` @@ -385,6 +391,14 @@ impl<'tcx> Generics { } false } + + pub fn is_empty(&'tcx self) -> bool { + self.count() == 0 + } + + pub fn is_own_empty(&'tcx self) -> bool { + self.own_params.is_empty() + } } /// Bounds on generics. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 73b20f0485b..44f09b8ba21 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -28,7 +28,7 @@ use crate::ty::fast_reject::SimplifiedType; use crate::ty::util::Discr; pub use adt::*; pub use assoc::*; -pub use generic_args::*; +pub use generic_args::{GenericArgKind, *}; pub use generics::*; pub use intrinsic::IntrinsicDef; use rustc_ast as ast; @@ -96,13 +96,13 @@ pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::parameterized::ParameterizedOverTcx; pub use self::pattern::{Pattern, PatternKind}; pub use self::predicate::{ - Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialProjection, - ExistentialTraitRef, NormalizesTo, OutlivesPredicate, PolyCoercePredicate, - PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef, - PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate, - PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate, - RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitPredicate, - TraitRef, TypeOutlivesPredicate, + AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate, + ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo, + OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection, + PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate, + PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, + PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, + TraitPredicate, TraitRef, TypeOutlivesPredicate, }; pub use self::region::{ BoundRegion, BoundRegionKind, BoundRegionKind::*, EarlyParamRegion, LateParamRegion, Region, @@ -266,7 +266,7 @@ pub struct ImplHeader<'tcx> { pub struct ImplTraitHeader<'tcx> { pub trait_ref: ty::EarlyBinder<ty::TraitRef<'tcx>>, pub polarity: ImplPolarity, - pub unsafety: hir::Unsafety, + pub safety: hir::Safety, } #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] @@ -277,61 +277,6 @@ pub enum ImplSubject<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] #[derive(TypeFoldable, TypeVisitable)] -pub enum ImplPolarity { - /// `impl Trait for Type` - Positive, - /// `impl !Trait for Type` - Negative, - /// `#[rustc_reservation_impl] impl Trait for Type` - /// - /// This is a "stability hack", not a real Rust feature. - /// See #64631 for details. - Reservation, -} - -impl fmt::Display for ImplPolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - Self::Reservation => f.write_str("reservation"), - } - } -} - -/// Polarity for a trait predicate. May either be negative or positive. -/// Distinguished from [`ImplPolarity`] since we never compute goals with -/// "reservation" level. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] -#[derive(TypeFoldable, TypeVisitable)] -pub enum PredicatePolarity { - /// `Type: Trait` - Positive, - /// `Type: !Trait` - Negative, -} - -impl PredicatePolarity { - /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. - pub fn flip(&self) -> PredicatePolarity { - match self { - PredicatePolarity::Positive => PredicatePolarity::Negative, - PredicatePolarity::Negative => PredicatePolarity::Positive, - } - } -} - -impl fmt::Display for PredicatePolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] -#[derive(TypeFoldable, TypeVisitable)] pub enum Asyncness { Yes, No, @@ -530,7 +475,7 @@ pub struct CReaderCacheKey { #[rustc_pass_by_value] pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>); -impl<'tcx> IntoKind for Ty<'tcx> { +impl<'tcx> rustc_type_ir::inherent::IntoKind for Ty<'tcx> { type Kind = TyKind<'tcx>; fn kind(self) -> TyKind<'tcx> { @@ -591,14 +536,10 @@ unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync impl Debug for Term<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let data = if let Some(ty) = self.ty() { - format!("Term::Ty({ty:?})") - } else if let Some(ct) = self.ct() { - format!("Term::Ct({ct:?})") - } else { - unreachable!() - }; - f.write_str(&data) + match self.unpack() { + TermKind::Ty(ty) => write!(f, "Term::Ty({ty:?})"), + TermKind::Const(ct) => write!(f, "Term::Const({ct:?})"), + } } } @@ -684,15 +625,14 @@ impl<'tcx> Term<'tcx> { } } - /// This function returns the inner `AliasTy` for a `ty::Alias` or `ConstKind::Unevaluated`. - pub fn to_alias_ty(&self, tcx: TyCtxt<'tcx>) -> Option<AliasTy<'tcx>> { + pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> { match self.unpack() { TermKind::Ty(ty) => match *ty.kind() { - ty::Alias(_kind, alias_ty) => Some(alias_ty), + ty::Alias(_kind, alias_ty) => Some(alias_ty.into()), _ => None, }, TermKind::Const(ct) => match ct.kind() { - ConstKind::Unevaluated(uv) => Some(AliasTy::new(tcx, uv.def, uv.args)), + ConstKind::Unevaluated(uv) => Some(uv.into()), _ => None, }, } @@ -981,7 +921,7 @@ pub struct Placeholder<T> { pub type PlaceholderRegion = Placeholder<BoundRegion>; -impl PlaceholderLike for PlaceholderRegion { +impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderRegion { fn universe(self) -> UniverseIndex { self.universe } @@ -1001,7 +941,7 @@ impl PlaceholderLike for PlaceholderRegion { pub type PlaceholderType = Placeholder<BoundTy>; -impl PlaceholderLike for PlaceholderType { +impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderType { fn universe(self) -> UniverseIndex { self.universe } @@ -1028,7 +968,7 @@ pub struct BoundConst<'tcx> { pub type PlaceholderConst = Placeholder<BoundVar>; -impl PlaceholderLike for PlaceholderConst { +impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderConst { fn universe(self) -> UniverseIndex { self.universe } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 48d900ef0c9..644fca7c5fe 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -1,22 +1,29 @@ 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_macros::{ + extension, HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; +use rustc_type_ir as ir; 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, Binder, DebruijnIndex, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, + Upcast, UpcastFrom, WithCachedTypeInfo, }; -pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>; -pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>; +pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>; +pub type AliasTerm<'tcx> = ir::AliasTerm<TyCtxt<'tcx>>; +pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate<TyCtxt<'tcx>>; +pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>; +pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>; +pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>; +pub type TraitPredicate<'tcx> = ir::TraitPredicate<TyCtxt<'tcx>>; +pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>; +pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>; +pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>; +pub type CoercePredicate<'tcx> = ir::CoercePredicate<TyCtxt<'tcx>>; +pub type SubtypePredicate<'tcx> = ir::SubtypePredicate<TyCtxt<'tcx>>; /// A statement that can be proven by a trait solver. This includes things that may /// show up in where clauses, such as trait predicates and projection predicates, @@ -30,6 +37,8 @@ pub struct Predicate<'tcx>( pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>, ); +impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {} + impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> { fn flags(&self) -> TypeFlags { self.0.flags @@ -193,43 +202,25 @@ impl<'tcx> Clause<'tcx> { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub enum ExistentialPredicate<'tcx> { - /// E.g., `Iterator`. - Trait(ExistentialTraitRef<'tcx>), - /// E.g., `Iterator::Item = T`. - Projection(ExistentialProjection<'tcx>), - /// E.g., `Send`. - AutoTrait(DefId), -} - -impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ExistentialPredicate<'tcx> { - fn fmt<Infcx: rustc_type_ir::InferCtxtLike<Interner = TyCtxt<'tcx>>>( - this: rustc_type_ir::WithInfcx<'_, Infcx, &Self>, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - std::fmt::Debug::fmt(&this.data, f) - } -} - +#[extension(pub trait ExistentialPredicateStableCmpExt<'tcx>)] impl<'tcx> ExistentialPredicate<'tcx> { /// Compares via an ordering that will not change if modules are reordered or other changes are /// made to the tree. In particular, this ordering is preserved across incremental compilations. - pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { - use self::ExistentialPredicate::*; + fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { match (*self, *other) { - (Trait(_), Trait(_)) => Ordering::Equal, - (Projection(ref a), Projection(ref b)) => { + (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal, + (ExistentialPredicate::Projection(ref a), ExistentialPredicate::Projection(ref b)) => { tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id)) } - (AutoTrait(ref a), AutoTrait(ref b)) => { + (ExistentialPredicate::AutoTrait(ref a), ExistentialPredicate::AutoTrait(ref b)) => { tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b)) } - (Trait(_), _) => Ordering::Less, - (Projection(_), Trait(_)) => Ordering::Greater, - (Projection(_), _) => Ordering::Less, - (AutoTrait(_), _) => Ordering::Greater, + (ExistentialPredicate::Trait(_), _) => Ordering::Less, + (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => { + Ordering::Greater + } + (ExistentialPredicate::Projection(_), _) => Ordering::Less, + (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater, } } } @@ -243,10 +234,10 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx> { match self.skip_binder() { ExistentialPredicate::Trait(tr) => { - self.rebind(tr).with_self_ty(tcx, self_ty).to_predicate(tcx) + self.rebind(tr).with_self_ty(tcx, self_ty).upcast(tcx) } ExistentialPredicate::Projection(p) => { - self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) + self.rebind(p.with_self_ty(tcx, self_ty)).upcast(tcx) } ExistentialPredicate::AutoTrait(did) => { let generics = tcx.generics_of(did); @@ -258,7 +249,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { let err_args = ty::GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]); ty::TraitRef::new(tcx, did, err_args) }; - self.rebind(trait_ref).to_predicate(tcx) + self.rebind(trait_ref).upcast(tcx) } } } @@ -326,76 +317,6 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> { } } -/// A complete reference to a trait. These take numerous guises in syntax, -/// but perhaps the most recognizable form is in a where-clause: -/// ```ignore (illustrative) -/// T: Foo<U> -/// ``` -/// This would be represented by a trait-reference where the `DefId` is the -/// `DefId` for the trait `Foo` and the args define `T` as parameter 0, -/// and `U` as parameter 1. -/// -/// Trait references also appear in object types like `Foo<U>`, but in -/// that case the `Self` parameter is absent from the generic parameters. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct TraitRef<'tcx> { - pub def_id: DefId, - pub args: GenericArgsRef<'tcx>, - /// This field exists to prevent the creation of `TraitRef` without - /// calling [`TraitRef::new`]. - pub(super) _use_trait_ref_new_instead: (), -} - -impl<'tcx> TraitRef<'tcx> { - pub fn new( - tcx: TyCtxt<'tcx>, - trait_def_id: DefId, - args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, - ) -> Self { - let args = tcx.check_and_mk_args(trait_def_id, args); - Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } - } - - pub fn from_lang_item( - tcx: TyCtxt<'tcx>, - trait_lang_item: LangItem, - span: Span, - args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, - ) -> Self { - let trait_def_id = tcx.require_lang_item(trait_lang_item, Some(span)); - Self::new(tcx, trait_def_id, args) - } - - pub fn from_method( - tcx: TyCtxt<'tcx>, - trait_id: DefId, - args: GenericArgsRef<'tcx>, - ) -> ty::TraitRef<'tcx> { - let defs = tcx.generics_of(trait_id); - ty::TraitRef::new(tcx, trait_id, tcx.mk_args(&args[..defs.own_params.len()])) - } - - /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` - /// are the parameters defined on trait. - pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> { - ty::TraitRef::new(tcx, def_id, GenericArgs::identity_for_item(tcx, def_id)) - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - ty::TraitRef::new( - tcx, - self.def_id, - [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), - ) - } - - #[inline] - pub fn self_ty(&self) -> Ty<'tcx> { - self.args.type_at(0) - } -} - pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>; impl<'tcx> PolyTraitRef<'tcx> { @@ -408,58 +329,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) -/// exists T. T: Trait<'a, 'b, X, Y> -/// ``` -/// The generic parameters don't include the erased `Self`, only trait -/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ExistentialTraitRef<'tcx> { - pub def_id: DefId, - pub args: GenericArgsRef<'tcx>, -} - -impl<'tcx> ExistentialTraitRef<'tcx> { - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - ) -> ty::ExistentialTraitRef<'tcx> { - // Assert there is a Self. - trait_ref.args.type_at(0); - - ty::ExistentialTraitRef { - def_id: trait_ref.def_id, - args: tcx.mk_args(&trait_ref.args[1..]), - } - } - - /// Object types don't have a self type specified. Therefore, when - /// we convert the principal trait-ref into a normal trait-ref, - /// you must give *some* self type. A common choice is `mk_err()` - /// or some placeholder type. - pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> { - // otherwise the escaping vars would be captured by the binder - // debug_assert!(!self_ty.has_escaping_bound_vars()); - - ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter())) - } -} - -impl<'tcx> IntoDiagArg for ExistentialTraitRef<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() - } -} - pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>; impl<'tcx> PolyExistentialTraitRef<'tcx> { @@ -476,62 +345,8 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { } } -/// A `ProjectionPredicate` for an `ExistentialTraitRef`. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ExistentialProjection<'tcx> { - pub def_id: DefId, - pub args: GenericArgsRef<'tcx>, - pub term: Term<'tcx>, -} - pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>; -impl<'tcx> ExistentialProjection<'tcx> { - /// Extracts the underlying existential trait reference from this projection. - /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`, - /// then this function would return an `exists T. T: Iterator` existential trait - /// reference. - pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { - let def_id = tcx.parent(self.def_id); - let args_count = tcx.generics_of(def_id).count() - 1; - let args = tcx.mk_args(&self.args[..args_count]); - ty::ExistentialTraitRef { def_id, args } - } - - pub fn with_self_ty( - &self, - tcx: TyCtxt<'tcx>, - self_ty: Ty<'tcx>, - ) -> ty::ProjectionPredicate<'tcx> { - // otherwise the escaping regions would be captured by the binders - debug_assert!(!self_ty.has_escaping_bound_vars()); - - ty::ProjectionPredicate { - projection_ty: AliasTy::new( - tcx, - self.def_id, - [self_ty.into()].into_iter().chain(self.args), - ), - term: self.term, - } - } - - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - projection_predicate: ty::ProjectionPredicate<'tcx>, - ) -> Self { - // Assert there is a Self. - projection_predicate.projection_ty.args.type_at(0); - - Self { - def_id: projection_predicate.projection_ty.def_id, - args: tcx.mk_args(&projection_predicate.projection_ty.args[1..]), - term: projection_predicate.term, - } - } -} - impl<'tcx> PolyExistentialProjection<'tcx> { pub fn with_self_ty( &self, @@ -652,37 +467,8 @@ impl<'tcx> Clause<'tcx> { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct TraitPredicate<'tcx> { - pub trait_ref: TraitRef<'tcx>, - - /// If polarity is Positive: we are proving that the trait is implemented. - /// - /// If polarity is Negative: we are proving that a negative impl of this trait - /// exists. (Note that coherence also checks whether negative impls of supertraits - /// exist via a series of predicates.) - /// - /// If polarity is Reserved: that's a bug. - pub polarity: PredicatePolarity, -} - pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; -impl<'tcx> TraitPredicate<'tcx> { - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self } - } - - pub fn def_id(self) -> DefId { - self.trait_ref.def_id - } - - pub fn self_ty(self) -> Ty<'tcx> { - self.trait_ref.self_ty() - } -} - impl<'tcx> PolyTraitPredicate<'tcx> { pub fn def_id(self) -> DefId { // Ok to skip binder since trait `DefId` does not care about regions. @@ -708,71 +494,17 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'t pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; -/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates -/// whether the `a` type is the type that we should label as "expected" when -/// presenting user diagnostics. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct SubtypePredicate<'tcx> { - pub a_is_expected: bool, - pub a: Ty<'tcx>, - pub b: Ty<'tcx>, -} pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; -/// Encodes that we have to coerce *from* the `a` type to the `b` type. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct CoercePredicate<'tcx> { - pub a: Ty<'tcx>, - pub b: Ty<'tcx>, -} pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>; -/// This kind of predicate has no *direct* correspondent in the -/// syntax, but it roughly corresponds to the syntactic forms: -/// -/// 1. `T: TraitRef<..., Item = Type>` -/// 2. `<T as TraitRef<...>>::Item == Type` (NYI) -/// -/// In particular, form #1 is "desugared" to the combination of a -/// normal trait predicate (`T: TraitRef<...>`) and one of these -/// predicates. Form #2 is a broader form in that it also permits -/// equality between arbitrary types. Processing an instance of -/// Form #2 eventually yields one of these `ProjectionPredicate` -/// instances to normalize the LHS. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ProjectionPredicate<'tcx> { - pub projection_ty: AliasTy<'tcx>, - pub term: Term<'tcx>, -} - -impl<'tcx> ProjectionPredicate<'tcx> { - pub fn self_ty(self) -> Ty<'tcx> { - self.projection_ty.self_ty() - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ProjectionPredicate<'tcx> { - Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self } - } - - pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { - self.projection_ty.trait_def_id(tcx) - } - - pub fn def_id(self) -> DefId { - self.projection_ty.def_id - } -} - pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>; impl<'tcx> PolyProjectionPredicate<'tcx> { /// Returns the `DefId` of the trait of the associated item being projected. #[inline] pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { - self.skip_binder().projection_ty.trait_def_id(tcx) + self.skip_binder().projection_term.trait_def_id(tcx) } /// Get the [PolyTraitRef] required for this projection to be well formed. @@ -785,7 +517,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { // This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. - self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx)) + self.map_bound(|predicate| predicate.projection_term.trait_ref(tcx)) } pub fn term(&self) -> Binder<'tcx, Term<'tcx>> { @@ -798,34 +530,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. pub fn projection_def_id(&self) -> DefId { // Ok to skip binder since trait `DefId` does not care about regions. - self.skip_binder().projection_ty.def_id - } -} - -/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be -/// proven by actually normalizing `alias`. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct NormalizesTo<'tcx> { - pub alias: AliasTy<'tcx>, - pub term: Term<'tcx>, -} - -impl<'tcx> NormalizesTo<'tcx> { - pub fn self_ty(self) -> Ty<'tcx> { - self.alias.self_ty() - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> NormalizesTo<'tcx> { - Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self } - } - - pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { - self.alias.trait_def_id(tcx) - } - - pub fn def_id(self) -> DefId { - self.alias.def_id + self.skip_binder().projection_term.def_id } } @@ -839,185 +544,164 @@ impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { } } -pub trait ToPredicate<'tcx, P = Predicate<'tcx>> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> P; -} - -impl<'tcx, T> ToPredicate<'tcx, T> for T { - fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> T { - self +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PredicateKind<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: PredicateKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + ty::Binder::dummy(from).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx> for PredicateKind<'tcx> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ty::Binder::dummy(self).to_predicate(tcx) - } -} - -impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - tcx.mk_predicate(self) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, PredicateKind<'tcx>>> for Predicate<'tcx> { + fn upcast_from(from: Binder<'tcx, PredicateKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { + tcx.mk_predicate(from) } } -impl<'tcx> ToPredicate<'tcx> for ClauseKind<'tcx> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::Clause(self))) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from))) } } -impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, ClauseKind<'tcx>> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - tcx.mk_predicate(self.map_bound(ty::PredicateKind::Clause)) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, ClauseKind<'tcx>>> for Predicate<'tcx> { + fn upcast_from(from: Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { + tcx.mk_predicate(from.map_bound(PredicateKind::Clause)) } } -impl<'tcx> ToPredicate<'tcx> for Clause<'tcx> { - #[inline(always)] - fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.as_predicate() +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Clause<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: Clause<'tcx>, _tcx: TyCtxt<'tcx>) -> Self { + from.as_predicate() } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for ClauseKind<'tcx> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - tcx.mk_predicate(Binder::dummy(ty::PredicateKind::Clause(self))).expect_clause() +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Clause<'tcx> { + fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(from))).expect_clause() } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, ClauseKind<'tcx>> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - tcx.mk_predicate(self.map_bound(|clause| ty::PredicateKind::Clause(clause))).expect_clause() +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, ClauseKind<'tcx>>> for Clause<'tcx> { + fn upcast_from(from: Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { + tcx.mk_predicate(from.map_bound(|clause| PredicateKind::Clause(clause))).expect_clause() } } -impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ty::Binder::dummy(self).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + ty::Binder::dummy(from).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx, TraitPredicate<'tcx>> for TraitRef<'tcx> { - #[inline(always)] - fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> TraitPredicate<'tcx> { - TraitPredicate { trait_ref: self, polarity: PredicatePolarity::Positive } +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for TraitPredicate<'tcx> { + fn upcast_from(from: TraitRef<'tcx>, _tcx: TyCtxt<'tcx>) -> Self { + TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive } } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - let p: Predicate<'tcx> = self.to_predicate(tcx); +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> { + fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + let p: Predicate<'tcx> = from.upcast(tcx); p.expect_clause() } } -impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx); - pred.to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, TraitRef<'tcx>>> for Predicate<'tcx> { + fn upcast_from(from: Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { + let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx); + pred.upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx); - pred.to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, TraitRef<'tcx>>> for Clause<'tcx> { + fn upcast_from(from: Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { + let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx); + pred.upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { - #[inline(always)] - fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> { - self.map_bound(|trait_ref| TraitPredicate { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, TraitRef<'tcx>>> for PolyTraitPredicate<'tcx> { + fn upcast_from(from: Binder<'tcx, TraitRef<'tcx>>, _tcx: TyCtxt<'tcx>) -> Self { + from.map_bound(|trait_ref| TraitPredicate { trait_ref, - polarity: ty::PredicatePolarity::Positive, + polarity: PredicatePolarity::Positive, }) } } -impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateKind::Clause(ClauseKind::Trait(self)).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + PredicateKind::Clause(ClauseKind::Trait(from)).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + from.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - let p: Predicate<'tcx> = self.to_predicate(tcx); +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Clause<'tcx> { + fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + let p: Predicate<'tcx> = from.upcast(tcx); p.expect_clause() } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyTraitPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - let p: Predicate<'tcx> = self.to_predicate(tcx); +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Clause<'tcx> { + fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + let p: Predicate<'tcx> = from.upcast(tcx); p.expect_clause() } } -impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesPredicate<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: PolyRegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + from.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx> for OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ty::Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(self))).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> + for Predicate<'tcx> +{ + fn upcast_from(from: OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { + ty::Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(from))).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx> for ProjectionPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ty::Binder::dummy(PredicateKind::Clause(ClauseKind::Projection(self))).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + ty::Binder::dummy(PredicateKind::Clause(ClauseKind::Projection(from))).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.map_bound(|p| PredicateKind::Clause(ClauseKind::Projection(p))).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + from.map_bound(|p| PredicateKind::Clause(ClauseKind::Projection(p))).upcast(tcx) } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for ProjectionPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - let p: Predicate<'tcx> = self.to_predicate(tcx); +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Clause<'tcx> { + fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + let p: Predicate<'tcx> = from.upcast(tcx); p.expect_clause() } } -impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - let p: Predicate<'tcx> = self.to_predicate(tcx); +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Clause<'tcx> { + fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + let p: Predicate<'tcx> = from.upcast(tcx); p.expect_clause() } } -impl<'tcx> ToPredicate<'tcx> for NormalizesTo<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateKind::NormalizesTo(self).to_predicate(tcx) +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, NormalizesTo<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: NormalizesTo<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + PredicateKind::NormalizesTo(from).upcast(tcx) } } impl<'tcx> Predicate<'tcx> { - pub fn to_opt_poly_trait_pred(self) -> Option<PolyTraitPredicate<'tcx>> { + pub fn as_trait_clause(self) -> Option<PolyTraitPredicate<'tcx>> { let predicate = self.kind(); match predicate.skip_binder() { PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)), @@ -1037,7 +721,7 @@ impl<'tcx> Predicate<'tcx> { } } - pub fn to_opt_poly_projection_pred(self) -> Option<PolyProjectionPredicate<'tcx>> { + pub fn as_projection_clause(self) -> Option<PolyProjectionPredicate<'tcx>> { let predicate = self.kind(); match predicate.skip_binder() { PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)), diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index eecd7dc6422..dc77f59f3d0 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> { @@ -157,7 +160,7 @@ pub trait Printer<'tcx>: Sized { // If we have any generic arguments to print, we do that // on top of the same path, but without its own generics. _ => { - if !generics.own_params.is_empty() && args.len() >= generics.count() { + if !generics.is_own_empty() && args.len() >= generics.count() { let args = generics.own_args_no_defaults(self.tcx(), args); return self.path_generic_args( |cx| cx.print_def_path(def_id, parent_args), @@ -334,3 +337,21 @@ pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> Str format!("module `{}`", tcx.def_path_str(def_id)) } } + +impl<T> rustc_type_ir::ir_print::IrPrint<T> for TyCtxt<'_> +where + T: Copy + for<'a, 'tcx> Lift<TyCtxt<'tcx>, Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>>, +{ + fn print(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + ty::tls::with(|tcx| { + let mut cx = FmtPrinter::new(tcx, Namespace::TypeNS); + tcx.lift(*t).expect("could not lift for printing").print(&mut cx)?; + fmt.write_str(&cx.into_buffer())?; + Ok(()) + }) + } + + fn print_debug(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + with_no_trimmed_paths!(Self::print(t, fmt)) + } +} diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 46dcd18cfbb..0dbb17e9db4 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}; @@ -1277,7 +1277,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { fn pretty_print_inherent_projection( &mut self, - alias_ty: ty::AliasTy<'tcx>, + alias_ty: ty::AliasTerm<'tcx>, ) -> Result<(), PrintError> { let def_key = self.tcx().def_key(alias_ty.def_id); self.path_generic_args( @@ -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) } } @@ -2952,8 +2953,9 @@ impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> { } } +#[extension(pub trait PrintTraitPredicateExt<'tcx>)] impl<'tcx> ty::TraitPredicate<'tcx> { - pub fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { + fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { TraitPredPrintModifiersAndPath(self) } } @@ -3032,6 +3034,56 @@ forward_display_to_print! { define_print! { (self, cx): + ty::FnSig<'tcx> { + p!(write("{}", self.safety.prefix_str())); + + if self.abi != Abi::Rust { + p!(write("extern {} ", self.abi)); + } + + 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())) + } + + ty::AliasTy<'tcx> { + let alias_term: ty::AliasTerm<'tcx> = (*self).into(); + p!(print(alias_term)) + } + + ty::AliasTerm<'tcx> { + match self.kind(cx.tcx()) { + ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)), + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::UnevaluatedConst + | ty::AliasTermKind::ProjectionConst => { + // If we're printing verbosely, or don't want to invoke queries + // (`is_impl_trait_in_trait`), then fall back to printing the def path. + // This is likely what you want if you're debugging the compiler anyways. + if !(cx.should_print_verbose() || with_reduced_queries()) + && cx.tcx().is_impl_trait_in_trait(self.def_id) + { + return cx.pretty_print_opaque_impl_type(self.def_id, self.args); + } else { + p!(print_def_path(self.def_id, self.args)); + } + } + } + } + + ty::TraitPredicate<'tcx> { + p!(print(self.trait_ref.self_ty()), ": "); + p!(pretty_print_bound_constness(self.trait_ref)); + if let ty::PredicatePolarity::Negative = self.polarity { + p!("!"); + } + p!(print(self.trait_ref.print_trait_sugared())) + } + ty::TypeAndMut<'tcx> { p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) } @@ -3072,13 +3124,15 @@ define_print! { ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)), } } -} -define_print_and_forward_display! { - (self, cx): - - &'tcx ty::List<Ty<'tcx>> { - p!("{{", comma_sep(self.iter()), "}}") + ty::ExistentialPredicate<'tcx> { + match *self { + ty::ExistentialPredicate::Trait(x) => p!(print(x)), + ty::ExistentialPredicate::Projection(x) => p!(print(x)), + ty::ExistentialPredicate::AutoTrait(def_id) => { + p!(print_def_path(def_id, &[])); + } + } } ty::ExistentialTraitRef<'tcx> { @@ -3093,28 +3147,36 @@ define_print_and_forward_display! { p!(write("{} = ", name), print(self.term)) } - ty::ExistentialPredicate<'tcx> { - match *self { - ty::ExistentialPredicate::Trait(x) => p!(print(x)), - ty::ExistentialPredicate::Projection(x) => p!(print(x)), - ty::ExistentialPredicate::AutoTrait(def_id) => { - p!(print_def_path(def_id, &[])); - } - } + ty::ProjectionPredicate<'tcx> { + p!(print(self.projection_term), " == "); + cx.reset_type_limit(); + p!(print(self.term)) } - ty::FnSig<'tcx> { - p!(write("{}", self.unsafety.prefix_str())); + ty::SubtypePredicate<'tcx> { + p!(print(self.a), " <: "); + cx.reset_type_limit(); + p!(print(self.b)) + } - if self.abi != Abi::Rust { - p!(write("extern {} ", self.abi)); - } + ty::CoercePredicate<'tcx> { + p!(print(self.a), " -> "); + cx.reset_type_limit(); + p!(print(self.b)) + } - p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); + ty::NormalizesTo<'tcx> { + p!(print(self.alias), " normalizes-to "); + cx.reset_type_limit(); + p!(print(self.term)) } +} - ty::TraitRef<'tcx> { - p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path())) +define_print_and_forward_display! { + (self, cx): + + &'tcx ty::List<Ty<'tcx>> { + p!("{{", comma_sep(self.iter()), "}}") } TraitRefPrintOnlyTraitPath<'tcx> { @@ -3163,39 +3225,6 @@ define_print_and_forward_display! { p!(write("{}", self.name)) } - ty::SubtypePredicate<'tcx> { - p!(print(self.a), " <: "); - cx.reset_type_limit(); - p!(print(self.b)) - } - - ty::CoercePredicate<'tcx> { - p!(print(self.a), " -> "); - cx.reset_type_limit(); - p!(print(self.b)) - } - - ty::TraitPredicate<'tcx> { - p!(print(self.trait_ref.self_ty()), ": "); - p!(pretty_print_bound_constness(self.trait_ref)); - if let ty::PredicatePolarity::Negative = self.polarity { - p!("!"); - } - p!(print(self.trait_ref.print_trait_sugared())) - } - - ty::ProjectionPredicate<'tcx> { - p!(print(self.projection_ty), " == "); - cx.reset_type_limit(); - p!(print(self.term)) - } - - ty::NormalizesTo<'tcx> { - p!(print(self.alias), " normalizes-to "); - cx.reset_type_limit(); - p!(print(self.term)) - } - ty::Term<'tcx> { match self.unpack() { ty::TermKind::Ty(ty) => p!(print(ty)), @@ -3203,24 +3232,6 @@ define_print_and_forward_display! { } } - ty::AliasTy<'tcx> { - if let DefKind::Impl { of_trait: false } = cx.tcx().def_kind(cx.tcx().parent(self.def_id)) { - p!(pretty_print_inherent_projection(*self)) - } else { - // If we're printing verbosely, or don't want to invoke queries - // (`is_impl_trait_in_trait`), then fall back to printing the def path. - // This is likely what you want if you're debugging the compiler anyways. - if !(cx.should_print_verbose() || with_reduced_queries()) - && cx.tcx().is_impl_trait_in_trait(self.def_id) - { - return cx.pretty_print_opaque_impl_type(self.def_id, self.args); - } else { - p!(print_def_path(self.def_id, self.args)); - } - - } - } - ty::Predicate<'tcx> { p!(print(self.kind())) } diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 3d9be15310f..7540f0ab83f 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<TyCtxt<'tcx>>; #[rustc_pass_by_value] pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>); -impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> { +impl<'tcx> rustc_type_ir::inherent::IntoKind for Region<'tcx> { type Kind = RegionKind<'tcx>; fn kind(self) -> RegionKind<'tcx> { @@ -137,7 +137,7 @@ impl<'tcx> Region<'tcx> { } } -impl<'tcx> rustc_type_ir::new::Region<TyCtxt<'tcx>> for Region<'tcx> { +impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> { fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self { Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon }) } @@ -396,6 +396,12 @@ pub struct BoundRegion { pub kind: BoundRegionKind, } +impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundRegion { + fn var(self) -> BoundVar { + self.var + } +} + impl core::fmt::Debug for BoundRegion { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self.kind { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 7063ef07201..947de3f3aaa 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -5,10 +5,11 @@ //! subtyping, type equality, etc. use crate::ty::error::{ExpectedFound, TypeError}; -use crate::ty::{self, Expr, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable}; -use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef}; +use crate::ty::{ + self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, Expr, GenericArg, + GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, +}; use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_macros::TypeVisitable; use rustc_target::spec::abi; @@ -145,7 +146,7 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { if a.c_variadic != b.c_variadic { return Err(TypeError::VariadicMismatch(expected_found(a.c_variadic, b.c_variadic))); } - let unsafety = relation.relate(a.unsafety, b.unsafety)?; + let safety = relation.relate(a.safety, b.safety)?; let abi = relation.relate(a.abi, b.abi)?; if a.inputs().len() != b.inputs().len() { @@ -180,7 +181,7 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { Ok(ty::FnSig { inputs_and_output: tcx.mk_type_list_from_iter(inputs_and_output)?, c_variadic: a.c_variadic, - unsafety, + safety, abi, }) } @@ -196,13 +197,13 @@ impl<'tcx> Relate<'tcx> for ty::BoundConstness { } } -impl<'tcx> Relate<'tcx> for hir::Unsafety { +impl<'tcx> Relate<'tcx> for hir::Safety { fn relate<R: TypeRelation<'tcx>>( _relation: &mut R, - a: hir::Unsafety, - b: hir::Unsafety, - ) -> RelateResult<'tcx, hir::Unsafety> { - if a != b { Err(TypeError::UnsafetyMismatch(expected_found(a, b))) } else { Ok(a) } + a: hir::Safety, + b: hir::Safety, + ) -> RelateResult<'tcx, hir::Safety> { + if a != b { Err(TypeError::SafetyMismatch(expected_found(a, b))) } else { Ok(a) } } } @@ -225,8 +226,8 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { if a.def_id != b.def_id { Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) } else { - let args = match relation.tcx().def_kind(a.def_id) { - DefKind::OpaqueTy => relate_args_with_variances( + let args = match a.kind(relation.tcx()) { + ty::Opaque => relate_args_with_variances( relation, a.def_id, relation.tcx().variances_of(a.def_id), @@ -234,16 +235,46 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, - DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => { + ty::Projection | ty::Weak | ty::Inherent => { relate_args_invariantly(relation, a.args, b.args)? } - def => bug!("unknown alias DefKind: {def:?}"), }; Ok(ty::AliasTy::new(relation.tcx(), a.def_id, args)) } } } +impl<'tcx> Relate<'tcx> for ty::AliasTerm<'tcx> { + fn relate<R: TypeRelation<'tcx>>( + relation: &mut R, + a: ty::AliasTerm<'tcx>, + b: ty::AliasTerm<'tcx>, + ) -> RelateResult<'tcx, ty::AliasTerm<'tcx>> { + if a.def_id != b.def_id { + Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) + } else { + let args = match a.kind(relation.tcx()) { + ty::AliasTermKind::OpaqueTy => relate_args_with_variances( + relation, + a.def_id, + relation.tcx().variances_of(a.def_id), + a.args, + b.args, + false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle + )?, + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::UnevaluatedConst + | ty::AliasTermKind::ProjectionConst => { + relate_args_invariantly(relation, a.args, b.args)? + } + }; + Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args)) + } + } +} + impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> { fn relate<R: TypeRelation<'tcx>>( relation: &mut R, @@ -702,14 +733,21 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { } let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { - use crate::ty::ExistentialPredicate::*; match (ep_a.skip_binder(), ep_b.skip_binder()) { - (Trait(a), Trait(b)) => Ok(ep_a - .rebind(Trait(relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder()))), - (Projection(a), Projection(b)) => Ok(ep_a.rebind(Projection( - relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), - ))), - (AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))), + (ExistentialPredicate::Trait(a), ExistentialPredicate::Trait(b)) => Ok(ep_a + .rebind(ExistentialPredicate::Trait( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))), + (ExistentialPredicate::Projection(a), ExistentialPredicate::Projection(b)) => { + Ok(ep_a.rebind(ExistentialPredicate::Projection( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))) + } + (ExistentialPredicate::AutoTrait(a), ExistentialPredicate::AutoTrait(b)) + if a == b => + { + Ok(ep_a.rebind(ExistentialPredicate::AutoTrait(a))) + } _ => Err(TypeError::ExistentialMismatch(expected_found(a, b))), } }); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 14a77d4b37e..7d24824d568 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -7,7 +7,7 @@ use crate::mir::interpret; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; +use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; use rustc_hir::def::Namespace; @@ -55,12 +55,6 @@ impl fmt::Debug for ty::UpvarId { } } -impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - with_no_trimmed_paths!(fmt::Display::fmt(self, f)) - } -} - impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?} -> {}", self.kind, self.target) @@ -89,55 +83,6 @@ impl fmt::Debug for ty::LateParamRegion { } } -impl<'tcx> fmt::Debug for ty::FnSig<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::FnSig<'tcx> { - fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - let sig = this.data; - let ty::FnSig { inputs_and_output: _, c_variadic, unsafety, abi } = sig; - - write!(f, "{}", unsafety.prefix_str())?; - match abi { - rustc_target::spec::abi::Abi::Rust => (), - abi => write!(f, "extern \"{abi:?}\" ")?, - }; - - write!(f, "fn(")?; - let inputs = sig.inputs(); - match inputs.len() { - 0 if *c_variadic => write!(f, "...)")?, - 0 => write!(f, ")")?, - _ => { - for ty in &sig.inputs()[0..(sig.inputs().len() - 1)] { - write!(f, "{:?}, ", &this.wrap(ty))?; - } - write!(f, "{:?}", &this.wrap(sig.inputs().last().unwrap()))?; - if *c_variadic { - write!(f, "...")?; - } - write!(f, ")")?; - } - } - - match sig.output().kind() { - ty::Tuple(list) if list.is_empty() => Ok(()), - _ => write!(f, " -> {:?}", &this.wrap(sig.output())), - } - } -} - -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>, @@ -164,25 +109,6 @@ impl fmt::Debug for ty::ParamConst { } } -impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // FIXME(effects) printing? - write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) - } -} - -impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) - } -} - -impl<'tcx> fmt::Debug for ty::NormalizesTo<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) - } -} - impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.kind()) @@ -195,23 +121,6 @@ impl<'tcx> fmt::Debug for ty::Clause<'tcx> { } } -impl<'tcx> fmt::Debug for AliasTy<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for AliasTy<'tcx> { - fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - f.debug_struct("AliasTy") - .field("args", &this.map(|data| data.args)) - .field("def_id", &this.data.def_id) - .finish() - } -} - impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for Pattern<'tcx> { fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>( this: WithInfcx<'_, Infcx, &Self>, @@ -261,23 +170,6 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::consts::Expr<'tcx> { } } -impl<'tcx> fmt::Debug for ty::UnevaluatedConst<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> { - fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - f.debug_struct("UnevaluatedConst") - .field("def", &this.data.def) - .field("args", &this.wrap(this.data.args)) - .finish() - } -} - impl<'tcx> fmt::Debug for ty::Const<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { WithInfcx::with_no_infcx(self).fmt(f) @@ -441,7 +333,7 @@ TrivialTypeTraversalImpls! { crate::ty::BoundRegionKind, crate::ty::AssocItem, crate::ty::AssocKind, - crate::ty::AliasKind, + crate::ty::AliasTyKind, crate::ty::Placeholder<crate::ty::BoundRegion>, crate::ty::Placeholder<crate::ty::BoundTy>, crate::ty::Placeholder<ty::BoundVar>, @@ -463,7 +355,7 @@ TrivialTypeTraversalImpls! { // interners). TrivialTypeTraversalAndLiftImpls! { ::rustc_hir::def_id::DefId, - ::rustc_hir::Unsafety, + ::rustc_hir::Safety, ::rustc_target::spec::abi::Abi, crate::ty::ClosureKind, crate::ty::ParamConst, @@ -478,7 +370,7 @@ TrivialTypeTraversalAndLiftImpls! { /////////////////////////////////////////////////////////////////////////// // Lift implementations -impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> { +impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> { type Lifted = Option<T::Lifted>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { Some(match self { @@ -488,7 +380,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> { } } -impl<'a, 'tcx> Lift<'tcx> for Term<'a> { +impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> { type Lifted = ty::Term<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { Some( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 32b970962e8..7c41c5f512e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -28,20 +28,18 @@ use std::iter; use std::ops::{ControlFlow, Deref, Range}; use ty::util::IntTypeExt; -use rustc_type_ir::BoundVar; -use rustc_type_ir::CollectAndApply; -use rustc_type_ir::DynKind; -use rustc_type_ir::TyKind as IrTyKind; use rustc_type_ir::TyKind::*; -use rustc_type_ir::TypeAndMut as IrTypeAndMut; +use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind}; use super::fold::FnMutDelegate; use super::GenericParamDefKind; // Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here #[rustc_diagnostic_item = "TyKind"] -pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>; -pub type TypeAndMut<'tcx> = IrTypeAndMut<TyCtxt<'tcx>>; +pub type TyKind<'tcx> = ir::TyKind<TyCtxt<'tcx>>; +pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>; +pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>; +pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>; pub trait Article { fn article(&self) -> &'static str; @@ -390,7 +388,7 @@ impl<'tcx> CoroutineClosureArgs<'tcx> { yield_ty, return_ty, c_variadic: sig.c_variadic, - unsafety: sig.unsafety, + safety: sig.safety, abi: sig.abi, } }) @@ -418,8 +416,8 @@ pub struct CoroutineClosureSignature<'tcx> { // from scratch just for good measure. /// Always false pub c_variadic: bool, - /// Always [`hir::Unsafety::Normal`] - pub unsafety: hir::Unsafety, + /// Always [`hir::Safety::Safe`] + pub safety: hir::Safety, /// Always [`abi::Abi::RustCall`] pub abi: abi::Abi, } @@ -942,7 +940,7 @@ where } } -impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { +impl<'tcx, T> rustc_type_ir::inherent::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> { self.bound_vars } @@ -988,14 +986,6 @@ impl<'tcx, T> Binder<'tcx, T> { Binder { value: &self.value, bound_vars: self.bound_vars } } - pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U> - where - F: FnOnce(&T) -> U, - { - let value = f(&self.value); - Binder { value, bound_vars: self.bound_vars } - } - pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U> where F: FnOnce(&T) -> U, @@ -1105,167 +1095,6 @@ where } } -/// Represents the projection of an associated type. -/// -/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`. -/// * For an inherent projection, this would be `Ty::N<...>`. -/// * For an opaque type, there is no explicit syntax. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct AliasTy<'tcx> { - /// The parameters of the associated or opaque item. - /// - /// For a projection, these are the generic parameters for the trait and the - /// GAT parameters, if there are any. - /// - /// For an inherent projection, they consist of the self type and the GAT parameters, - /// if there are any. - /// - /// For RPIT the generic parameters are for the generics of the function, - /// while for TAIT it is used for the generic parameters of the alias. - pub args: GenericArgsRef<'tcx>, - - /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether - /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if - /// this is an opaque. - /// - /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the - /// underlying type if the type is an opaque. - /// - /// Note that if this is an associated type, this is not the `DefId` of the - /// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`, - /// aka. `tcx.parent(def_id)`. - pub def_id: DefId, - - /// This field exists to prevent the creation of `AliasTy` without using - /// [AliasTy::new]. - _use_alias_ty_new_instead: (), -} - -impl<'tcx> AliasTy<'tcx> { - pub fn new( - tcx: TyCtxt<'tcx>, - def_id: DefId, - args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, - ) -> ty::AliasTy<'tcx> { - let args = tcx.check_and_mk_args(def_id, args); - ty::AliasTy { def_id, args, _use_alias_ty_new_instead: () } - } - - pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind { - match tcx.def_kind(self.def_id) { - DefKind::AssocTy - if let DefKind::Impl { of_trait: false } = - tcx.def_kind(tcx.parent(self.def_id)) => - { - ty::Inherent - } - DefKind::AssocTy => ty::Projection, - DefKind::OpaqueTy => ty::Opaque, - DefKind::TyAlias => ty::Weak, - kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), - } - } - - /// Whether this alias type is an opaque. - pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool { - matches!(self.opt_kind(tcx), Some(ty::Opaque)) - } - - /// FIXME: rename `AliasTy` to `AliasTerm` and always handle - /// constants. This function can then be removed. - pub fn opt_kind(self, tcx: TyCtxt<'tcx>) -> Option<ty::AliasKind> { - match tcx.def_kind(self.def_id) { - DefKind::AssocTy - if let DefKind::Impl { of_trait: false } = - tcx.def_kind(tcx.parent(self.def_id)) => - { - Some(ty::Inherent) - } - DefKind::AssocTy => Some(ty::Projection), - DefKind::OpaqueTy => Some(ty::Opaque), - DefKind::TyAlias => Some(ty::Weak), - _ => None, - } - } - - pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - Ty::new_alias(tcx, self.kind(tcx), self) - } -} - -/// The following methods work only with associated type projections. -impl<'tcx> AliasTy<'tcx> { - pub fn self_ty(self) -> Ty<'tcx> { - self.args.type_at(0) - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - AliasTy::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter().skip(1))) - } -} - -/// The following methods work only with trait associated type projections. -impl<'tcx> AliasTy<'tcx> { - pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { - match tcx.def_kind(self.def_id) { - DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), - kind => bug!("expected a projection AliasTy; found {kind:?}"), - } - } - - /// Extracts the underlying trait reference and own args from this projection. - /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`, - /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own args - pub fn trait_ref_and_own_args( - self, - tcx: TyCtxt<'tcx>, - ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { - debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst)); - let trait_def_id = self.trait_def_id(tcx); - let trait_generics = tcx.generics_of(trait_def_id); - ( - ty::TraitRef::new(tcx, trait_def_id, self.args.truncate_to(tcx, trait_generics)), - &self.args[trait_generics.count()..], - ) - } - - /// Extracts the underlying trait reference from this projection. - /// For example, if this is a projection of `<T as Iterator>::Item`, - /// then this function would return a `T: Iterator` trait reference. - /// - /// WARNING: This will drop the args for generic associated types - /// consider calling [Self::trait_ref_and_own_args] to get those - /// as well. - pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { - let def_id = self.trait_def_id(tcx); - ty::TraitRef::new(tcx, def_id, self.args.truncate_to(tcx, tcx.generics_of(def_id))) - } -} - -/// The following methods work only with inherent associated type projections. -impl<'tcx> AliasTy<'tcx> { - /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that. - /// - /// Does the following transformation: - /// - /// ```text - /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] - /// - /// I_i impl args - /// P_j GAT args - /// ``` - pub fn rebase_inherent_args_onto_impl( - self, - impl_args: ty::GenericArgsRef<'tcx>, - tcx: TyCtxt<'tcx>, - ) -> ty::GenericArgsRef<'tcx> { - debug_assert_eq!(self.kind(tcx), ty::Inherent); - - tcx.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1))) - } -} - #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] pub struct GenSig<'tcx> { pub resume_ty: Ty<'tcx>, @@ -1273,73 +1102,37 @@ pub struct GenSig<'tcx> { pub return_ty: Ty<'tcx>, } -/// Signature of a function type, which we have arbitrarily -/// decided to use to refer to the input/output types. -/// -/// - `inputs`: is the list of arguments and their modes. -/// - `output`: is the return type. -/// - `c_variadic`: indicates whether this is a C-variadic function. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct FnSig<'tcx> { - pub inputs_and_output: &'tcx List<Ty<'tcx>>, - pub c_variadic: bool, - pub unsafety: hir::Unsafety, - pub abi: abi::Abi, -} - -impl<'tcx> FnSig<'tcx> { - pub fn inputs(&self) -> &'tcx [Ty<'tcx>] { - &self.inputs_and_output[..self.inputs_and_output.len() - 1] - } - - pub fn output(&self) -> Ty<'tcx> { - self.inputs_and_output[self.inputs_and_output.len() - 1] - } - - // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible - // method. - fn fake() -> FnSig<'tcx> { - FnSig { - inputs_and_output: List::empty(), - c_variadic: false, - unsafety: hir::Unsafety::Normal, - abi: abi::Abi::Rust, - } - } -} - -impl<'tcx> IntoDiagArg for FnSig<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() - } -} - pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; impl<'tcx> PolyFnSig<'tcx> { #[inline] pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { - self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs()) + self.map_bound_ref(|fn_sig| fn_sig.inputs()) } + #[inline] #[track_caller] pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { self.map_bound_ref(|fn_sig| fn_sig.inputs()[index]) } + pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> { self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output) } + #[inline] pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> { self.map_bound_ref(|fn_sig| fn_sig.output()) } + pub fn c_variadic(&self) -> bool { self.skip_binder().c_variadic } - pub fn unsafety(&self) -> hir::Unsafety { - self.skip_binder().unsafety + + pub fn safety(&self) -> hir::Safety { + self.skip_binder().safety } + pub fn abi(&self) -> abi::Abi { self.skip_binder().abi } @@ -1347,12 +1140,7 @@ impl<'tcx> PolyFnSig<'tcx> { pub fn is_fn_trait_compatible(&self) -> bool { matches!( self.skip_binder(), - ty::FnSig { - unsafety: rustc_hir::Unsafety::Normal, - abi: Abi::Rust, - c_variadic: false, - .. - } + ty::FnSig { safety: rustc_hir::Safety::Safe, abi: Abi::Rust, c_variadic: false, .. } ) } } @@ -1411,6 +1199,12 @@ pub struct BoundTy { pub kind: BoundTyKind, } +impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundTy { + fn var(self) -> BoundVar { + self.var + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable)] pub enum BoundTyKind { @@ -1511,7 +1305,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_alias( tcx: TyCtxt<'tcx>, - kind: ty::AliasKind, + kind: ty::AliasTyKind, alias_ty: ty::AliasTy<'tcx>, ) -> Ty<'tcx> { debug_assert_matches!( @@ -1812,10 +1606,22 @@ impl<'tcx> Ty<'tcx> { } } -impl<'tcx> rustc_type_ir::new::Ty<TyCtxt<'tcx>> for Ty<'tcx> { +impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> { + fn new_bool(tcx: TyCtxt<'tcx>) -> Self { + tcx.types.bool + } + 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 }) } + + fn new_alias( + interner: TyCtxt<'tcx>, + kind: ty::AliasTyKind, + alias_ty: ty::AliasTy<'tcx>, + ) -> Self { + Ty::new_alias(interner, kind, alias_ty) + } } /// Type utilities @@ -2187,7 +1993,12 @@ impl<'tcx> Ty<'tcx> { FnPtr(f) => *f, Error(_) => { // ignore errors (#54954) - ty::Binder::dummy(FnSig::fake()) + ty::Binder::dummy(ty::FnSig { + inputs_and_output: ty::List::empty(), + c_variadic: false, + safety: hir::Safety::Safe, + abi: abi::Abi::Rust, + }) } Closure(..) => bug!( "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`", @@ -2780,6 +2591,13 @@ impl<'tcx> Ty<'tcx> { } } +impl<'tcx> rustc_type_ir::inherent::Tys<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> { + fn split_inputs_and_output(self) -> (&'tcx [Ty<'tcx>], Ty<'tcx>) { + let (output, inputs) = self.split_last().unwrap(); + (inputs, *output) + } +} + /// Extra information about why we ended up with a particular variance. /// This is only used to add more information to error messages, and /// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo` diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index cf5decffea9..c5b3de17bcb 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -15,7 +15,7 @@ use rustc_macros::{Decodable, Encodable, HashStable}; pub struct TraitDef { pub def_id: DefId, - pub unsafety: hir::Unsafety, + pub safety: hir::Safety, /// If `true`, then this trait had the `#[rustc_paren_sugar]` /// attribute, indicating that it should be used with `Foo()` diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 41f417dfd4b..24e3e623ff2 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -79,6 +79,10 @@ pub struct TypeckResults<'tcx> { /// Stores the actual binding mode for all instances of [`BindingMode`]. pat_binding_modes: ItemLocalMap<BindingMode>, + /// Top-level patterns whose match ergonomics need to be desugared + /// by the Rust 2021 -> 2024 migration lint. + rust_2024_migration_desugared_pats: ItemLocalSet, + /// Stores the types which were implicitly dereferenced in pattern binding modes /// for later usage in THIR lowering. For example, /// @@ -229,6 +233,7 @@ impl<'tcx> TypeckResults<'tcx> { adjustments: Default::default(), pat_binding_modes: Default::default(), pat_adjustments: Default::default(), + rust_2024_migration_desugared_pats: Default::default(), skipped_ref_pats: Default::default(), closure_kind_origins: Default::default(), liberated_fn_sigs: Default::default(), @@ -432,6 +437,20 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } + pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> { + LocalSetInContext { + hir_owner: self.hir_owner, + data: &self.rust_2024_migration_desugared_pats, + } + } + + pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> { + LocalSetInContextMut { + hir_owner: self.hir_owner, + data: &mut self.rust_2024_migration_desugared_pats, + } + } + pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> { LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6ad4f492f74..8c14f1e080a 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -4,8 +4,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::{IntoQueryParam, Providers}; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ - self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, + self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, Upcast, }; use crate::ty::{GenericArgKind, GenericArgsRef}; use rustc_apfloat::Float as _; @@ -1086,7 +1086,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> { { p.kind() .rebind(ty::ProjectionPredicate { - projection_ty: projection_pred.projection_ty.fold_with(self), + projection_term: projection_pred.projection_term.fold_with(self), // Don't fold the term on the RHS of the projection predicate. // This is because for default trait methods with RPITITs, we // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` @@ -1094,7 +1094,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> { // anything that requires `ParamEnv::with_reveal_all_normalized`. term: projection_pred.term, }) - .to_predicate(self.tcx) + .upcast(self.tcx) } else { p.super_fold_with(self) } @@ -1130,7 +1130,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for WeakAliasTypeExpander<'tcx> { } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - if !ct.ty().has_type_flags(ty::TypeFlags::HAS_TY_WEAK) { + if !ct.has_type_flags(ty::TypeFlags::HAS_TY_WEAK) { return ct; } ct.super_fold_with(self) |
