Apply nits, uplift ExistentialPredicate too

This commit is contained in:
Michael Goulet 2024-05-11 18:14:44 -04:00
parent 0a8f33830c
commit 905f565824
9 changed files with 100 additions and 82 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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<TyCtxt<'tcx>>;
pub type ProjectionPredicate<'tcx> = IrProjectionPredicate<TyCtxt<'tcx>>;
pub type ExistentialTraitRef<'tcx> = IrExistentialTraitRef<TyCtxt<'tcx>>;
pub type ExistentialProjection<'tcx> = IrExistentialProjection<TyCtxt<'tcx>>;
pub type TraitPredicate<'tcx> = IrTraitPredicate<TyCtxt<'tcx>>;
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
pub type NormalizesTo<'tcx> = IrNormalizesTo<TyCtxt<'tcx>>;
pub type CoercePredicate<'tcx> = IrCoercePredicate<TyCtxt<'tcx>>;
pub type SubtypePredicate<'tcx> = IrSubtypePredicate<TyCtxt<'tcx>>;
pub type TraitRef<'tcx> = ir::TraitRef<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,
@ -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<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,
}
}
}

View File

@ -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()));

View File

@ -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<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))),
}
});

View File

@ -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;

View File

@ -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};

View File

@ -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<I: Interner> {
/// E.g., `Iterator`.
Trait(ExistentialTraitRef<I>),
/// E.g., `Iterator::Item = T`.
Projection(ExistentialProjection<I>),
/// E.g., `Send`.
AutoTrait(I::DefId),
}
// FIXME: Implement this the right way after
impl<I: Interner> DebugWithInfcx<I> for ExistentialPredicate<I> {
fn fmt<Infcx: rustc_type_ir::InferCtxtLike<Interner = I>>(
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)