From 905f5658246ae2f108dee3620ace203c0d5286e1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 May 2024 18:14:44 -0400 Subject: [PATCH] Apply nits, uplift ExistentialPredicate too --- .../src/hir_ty_lowering/object_safety.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 14 ++-- compiler/rustc_middle/src/ty/predicate.rs | 80 +++++++------------ compiler/rustc_middle/src/ty/print/pretty.rs | 20 ++--- compiler/rustc_middle/src/ty/relate.rs | 27 ++++--- .../cfi/typeid/itanium_cxx_abi/transform.rs | 3 +- .../src/traits/object_safety.rs | 3 +- compiler/rustc_type_ir/src/predicate.rs | 32 +++++++- 9 files changed, 100 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 297cfe7027ec..37d4d4ec3558 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits::error_reporting::report_object_safety_error; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 70fb937cae7a..f9d1a77c3d96 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -26,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, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 28baa3348402..2b0d87969686 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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, + 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, + ToPredicate, TraitPredicate, TraitRef, TypeOutlivesPredicate, }; pub use self::region::{ BoundRegion, BoundRegionKind, BoundRegionKind::*, EarlyParamRegion, LateParamRegion, Region, diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index dbbb86cb28e1..c1de23b24986 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -1,34 +1,28 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; -use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; -use rustc_type_ir::ClauseKind as IrClauseKind; -use rustc_type_ir::CoercePredicate as IrCoercePredicate; -use rustc_type_ir::ExistentialProjection as IrExistentialProjection; -use rustc_type_ir::ExistentialTraitRef as IrExistentialTraitRef; -use rustc_type_ir::NormalizesTo as IrNormalizesTo; -use rustc_type_ir::PredicateKind as IrPredicateKind; -use rustc_type_ir::ProjectionPredicate as IrProjectionPredicate; -use rustc_type_ir::SubtypePredicate as IrSubtypePredicate; -use rustc_type_ir::TraitPredicate as IrTraitPredicate; -use rustc_type_ir::TraitRef as IrTraitRef; +use rustc_macros::{ + extension, HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; +use rustc_type_ir as ir; use std::cmp::Ordering; use crate::ty::{ - self, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, - TypeFlags, WithCachedTypeInfo, + self, Binder, DebruijnIndex, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, + WithCachedTypeInfo, }; -pub type TraitRef<'tcx> = IrTraitRef>; -pub type ProjectionPredicate<'tcx> = IrProjectionPredicate>; -pub type ExistentialTraitRef<'tcx> = IrExistentialTraitRef>; -pub type ExistentialProjection<'tcx> = IrExistentialProjection>; -pub type TraitPredicate<'tcx> = IrTraitPredicate>; -pub type ClauseKind<'tcx> = IrClauseKind>; -pub type PredicateKind<'tcx> = IrPredicateKind>; -pub type NormalizesTo<'tcx> = IrNormalizesTo>; -pub type CoercePredicate<'tcx> = IrCoercePredicate>; -pub type SubtypePredicate<'tcx> = IrSubtypePredicate>; +pub type TraitRef<'tcx> = ir::TraitRef>; +pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate>; +pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate>; +pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef>; +pub type ExistentialProjection<'tcx> = ir::ExistentialProjection>; +pub type TraitPredicate<'tcx> = ir::TraitPredicate>; +pub type ClauseKind<'tcx> = ir::ClauseKind>; +pub type PredicateKind<'tcx> = ir::PredicateKind>; +pub type NormalizesTo<'tcx> = ir::NormalizesTo>; +pub type CoercePredicate<'tcx> = ir::CoercePredicate>; +pub type SubtypePredicate<'tcx> = ir::SubtypePredicate>; /// 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, @@ -207,43 +201,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> for ExistentialPredicate<'tcx> { - fn fmt>>( - 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, } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6137a5fd48a8..be9525a083ce 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3088,6 +3088,16 @@ define_print! { } } + 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> { // Use a type that can't appear in defaults of type parameters. let dummy_self = Ty::new_fresh(cx.tcx(), 0); @@ -3132,16 +3142,6 @@ define_print_and_forward_display! { 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::FnSig<'tcx> { p!(write("{}", self.unsafety.prefix_str())); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 7063ef07201b..417edda10cae 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -5,8 +5,10 @@ //! 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; @@ -702,14 +704,21 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { } 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_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 7141c6c9bb0c..21433cfdb613 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -8,7 +8,8 @@ use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{ - self, Instance, IntTy, List, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, UintTy, + self, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, Ty, TyCtxt, TypeFoldable, + TypeVisitableExt, UintTy, }; use rustc_span::sym; use rustc_trait_selection::traits; diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5cb61dff8314..75e43bc8f5d9 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -18,7 +18,8 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, EarlyBinder, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeSuperVisitable, + TypeVisitable, TypeVisitor, }; use rustc_middle::ty::{GenericArg, GenericArgs}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index b16227ee10f7..b2510cb01df3 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -5,7 +5,7 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use crate::inherent::*; use crate::visit::TypeVisitableExt as _; -use crate::Interner; +use crate::{DebugWithInfcx, Interner}; /// A complete reference to a trait. These take numerous guises in syntax, /// but perhaps the most recognizable form is in a where-clause: @@ -146,6 +146,36 @@ impl fmt::Display for PredicatePolarity { } } +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum ExistentialPredicate { + /// E.g., `Iterator`. + Trait(ExistentialTraitRef), + /// E.g., `Iterator::Item = T`. + Projection(ExistentialProjection), + /// E.g., `Send`. + AutoTrait(I::DefId), +} + +// FIXME: Implement this the right way after +impl DebugWithInfcx for ExistentialPredicate { + fn fmt>( + this: rustc_type_ir::WithInfcx<'_, Infcx, &Self>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(&this.data, f) + } +} + /// An existential reference to a trait, where `Self` is erased. /// For example, the trait object `Trait<'a, 'b, X, Y>` is: /// ```ignore (illustrative)