mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Uplift NormalizesTo
, CoercePredicate
, and SubtypePredicate
This commit is contained in:
parent
0d4dca2b82
commit
0a8f33830c
@ -100,8 +100,6 @@ impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::TraitRef<I> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::ExistentialTraitRef<I> {
|
||||
fn into_diag_arg(self) -> DiagArgValue {
|
||||
self.to_string().into_diag_arg()
|
||||
|
@ -149,7 +149,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
|
||||
self.mk_args(args)
|
||||
}
|
||||
|
||||
|
||||
fn check_and_mk_args(
|
||||
self,
|
||||
def_id: DefId,
|
||||
@ -157,7 +157,7 @@ impl<'tcx> Interner for TyCtxt<'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)
|
||||
}
|
||||
|
@ -3,17 +3,20 @@ 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_type_ir::ProjectionPredicate as IrProjectionPredicate;
|
||||
use rustc_type_ir::ExistentialTraitRef as IrExistentialTraitRef;
|
||||
use rustc_type_ir::ExistentialProjection as IrExistentialProjection;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::ty::{
|
||||
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder,
|
||||
PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
|
||||
self, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt,
|
||||
TypeFlags, WithCachedTypeInfo,
|
||||
};
|
||||
|
||||
pub type TraitRef<'tcx> = IrTraitRef<TyCtxt<'tcx>>;
|
||||
@ -23,6 +26,9 @@ 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>>;
|
||||
|
||||
/// 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,
|
||||
@ -511,25 +517,8 @@ 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>>;
|
||||
|
||||
pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
|
||||
@ -568,33 +557,6 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToPolyTraitRef<'tcx> {
|
||||
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
|
||||
}
|
||||
|
@ -3105,6 +3105,24 @@ define_print! {
|
||||
cx.reset_type_limit();
|
||||
p!(print(self.term))
|
||||
}
|
||||
|
||||
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::NormalizesTo<'tcx> {
|
||||
p!(print(self.alias), " normalizes-to ");
|
||||
cx.reset_type_limit();
|
||||
p!(print(self.term))
|
||||
}
|
||||
}
|
||||
|
||||
define_print_and_forward_display! {
|
||||
@ -3180,24 +3198,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::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)),
|
||||
|
@ -152,12 +152,6 @@ impl fmt::Debug for ty::ParamConst {
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
|
@ -90,7 +90,7 @@ pub trait BoundVars<I: Interner> {
|
||||
fn has_no_bound_vars(&self) -> bool;
|
||||
}
|
||||
|
||||
// TODO: Uplift `AliasTy`
|
||||
// FIXME: Uplift `AliasTy`
|
||||
pub trait AliasTy<I: Interner>: Copy + DebugWithInfcx<I> + Hash + Eq + Sized {
|
||||
fn new(
|
||||
interner: I,
|
||||
@ -107,5 +107,4 @@ pub trait AliasTy<I: Interner>: Copy + DebugWithInfcx<I> + Hash + Eq + Sized {
|
||||
fn self_ty(self) -> I::Ty;
|
||||
|
||||
fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self;
|
||||
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ use crate::inherent::*;
|
||||
use crate::ir_print::IrPrint;
|
||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||
use crate::{
|
||||
CanonicalVarInfo, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef,
|
||||
ProjectionPredicate, TraitPredicate, TraitRef,
|
||||
CanonicalVarInfo, CoercePredicate, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef,
|
||||
NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||
};
|
||||
|
||||
pub trait Interner:
|
||||
@ -18,6 +18,9 @@ pub trait Interner:
|
||||
+ IrPrint<ExistentialTraitRef<Self>>
|
||||
+ IrPrint<ExistentialProjection<Self>>
|
||||
+ IrPrint<ProjectionPredicate<Self>>
|
||||
+ IrPrint<NormalizesTo<Self>>
|
||||
+ IrPrint<SubtypePredicate<Self>>
|
||||
+ IrPrint<CoercePredicate<Self>>
|
||||
{
|
||||
type DefId: Copy + Debug + Hash + Eq;
|
||||
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::fmt;
|
||||
|
||||
use crate::{
|
||||
ExistentialProjection, ExistentialTraitRef, Interner, ProjectionPredicate, TraitPredicate,
|
||||
TraitRef,
|
||||
CoercePredicate, ExistentialProjection, ExistentialTraitRef, Interner, NormalizesTo,
|
||||
ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||
};
|
||||
|
||||
pub trait IrPrint<T> {
|
||||
@ -39,7 +39,10 @@ define_display_via_print!(
|
||||
TraitPredicate,
|
||||
ExistentialTraitRef,
|
||||
ExistentialProjection,
|
||||
ProjectionPredicate
|
||||
ProjectionPredicate,
|
||||
NormalizesTo,
|
||||
SubtypePredicate,
|
||||
CoercePredicate,
|
||||
);
|
||||
|
||||
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
|
||||
|
@ -37,9 +37,9 @@ mod debug;
|
||||
mod flags;
|
||||
mod infcx;
|
||||
mod interner;
|
||||
mod predicate;
|
||||
mod predicate_kind;
|
||||
mod region_kind;
|
||||
mod predicate;
|
||||
|
||||
pub use canonical::*;
|
||||
#[cfg(feature = "nightly")]
|
||||
@ -49,9 +49,9 @@ pub use debug::{DebugWithInfcx, WithInfcx};
|
||||
pub use flags::*;
|
||||
pub use infcx::InferCtxtLike;
|
||||
pub use interner::*;
|
||||
pub use predicate::*;
|
||||
pub use predicate_kind::*;
|
||||
pub use region_kind::*;
|
||||
pub use predicate::*;
|
||||
pub use ty_info::*;
|
||||
pub use ty_kind::*;
|
||||
pub use AliasKind::*;
|
||||
|
@ -187,7 +187,11 @@ impl<I: Interner> ExistentialTraitRef<I> {
|
||||
// otherwise the escaping vars would be captured by the binder
|
||||
// debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
|
||||
TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.into_iter()))
|
||||
TraitRef::new(
|
||||
interner,
|
||||
self.def_id,
|
||||
[self_ty.into()].into_iter().chain(self.args.into_iter()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,3 +300,81 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
|
||||
write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term)
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be
|
||||
/// proven by actually normalizing `alias`.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct NormalizesTo<I: Interner> {
|
||||
pub alias: I::AliasTy,
|
||||
pub term: I::Term,
|
||||
}
|
||||
|
||||
impl<I: Interner> NormalizesTo<I> {
|
||||
pub fn self_ty(self) -> I::Ty {
|
||||
self.alias.self_ty()
|
||||
}
|
||||
|
||||
pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> NormalizesTo<I> {
|
||||
Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self }
|
||||
}
|
||||
|
||||
pub fn trait_def_id(self, tcx: I) -> I::DefId {
|
||||
self.alias.trait_def_id(tcx)
|
||||
}
|
||||
|
||||
pub fn def_id(self) -> I::DefId {
|
||||
self.alias.def_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> fmt::Debug for NormalizesTo<I> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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(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 struct SubtypePredicate<I: Interner> {
|
||||
pub a_is_expected: bool,
|
||||
pub a: I::Ty,
|
||||
pub b: I::Ty,
|
||||
}
|
||||
|
||||
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
|
||||
#[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 struct CoercePredicate<I: Interner> {
|
||||
pub a: I::Ty,
|
||||
pub b: I::Ty,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user