Skip to content

Commit 0d4dca2

Browse files
committedMay 11, 2024
Uplift ExistentialTraitRef, ExistentialProjection, ProjectionPredicate
·
1.91.11.80.0
1 parent 204cde4 commit 0d4dca2

File tree

12 files changed

+428
-325
lines changed

12 files changed

+428
-325
lines changed
 

‎compiler/rustc_errors/src/diagnostic_impls.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::TraitRef<I> {
100100
}
101101
}
102102

103+
104+
105+
impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::ExistentialTraitRef<I> {
106+
fn into_diag_arg(self) -> DiagArgValue {
107+
self.to_string().into_diag_arg()
108+
}
109+
}
110+
103111
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
104112

105113
impl IntoDiagArg for bool {

‎compiler/rustc_middle/src/ty/context.rs‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
9999
type CanonicalVars = CanonicalVarInfos<'tcx>;
100100

101101
type Ty = Ty<'tcx>;
102-
type Pat = Pattern<'tcx>;
103102
type Tys = &'tcx List<Ty<'tcx>>;
104103
type AliasTy = ty::AliasTy<'tcx>;
105104
type ParamTy = ParamTy;
106105
type BoundTy = ty::BoundTy;
107106
type PlaceholderTy = ty::PlaceholderType;
108-
109107
type ErrorGuaranteed = ErrorGuaranteed;
108+
110109
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
111110
type PolyFnSig = PolyFnSig<'tcx>;
112111
type AllocId = crate::mir::interpret::AllocId;
112+
type Pat = Pattern<'tcx>;
113113

114114
type Const = ty::Const<'tcx>;
115115
type AliasConst = ty::UnevaluatedConst<'tcx>;
@@ -121,8 +121,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
121121

122122
type Region = Region<'tcx>;
123123
type EarlyParamRegion = ty::EarlyParamRegion;
124-
type BoundRegion = ty::BoundRegion;
125124
type LateParamRegion = ty::LateParamRegion;
125+
type BoundRegion = ty::BoundRegion;
126126
type InferRegion = ty::RegionVid;
127127
type PlaceholderRegion = ty::PlaceholderRegion;
128128

@@ -146,13 +146,21 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
146146
self.generics_of(def_id)
147147
}
148148

149+
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
150+
self.mk_args(args)
151+
}
152+
149153
fn check_and_mk_args(
150154
self,
151155
def_id: DefId,
152156
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
153157
) -> ty::GenericArgsRef<'tcx> {
154158
self.check_and_mk_args(def_id, args)
155159
}
160+
161+
fn parent(self, def_id: Self::DefId) -> Self::DefId {
162+
self.parent(def_id)
163+
}
156164
}
157165

158166
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;

‎compiler/rustc_middle/src/ty/predicate.rs‎

Lines changed: 7 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
use rustc_data_structures::captures::Captures;
22
use rustc_data_structures::intern::Interned;
3-
use rustc_errors::{DiagArgValue, IntoDiagArg};
43
use rustc_hir::def_id::DefId;
54
use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
65
use rustc_type_ir::ClauseKind as IrClauseKind;
76
use rustc_type_ir::PredicateKind as IrPredicateKind;
87
use rustc_type_ir::TraitPredicate as IrTraitPredicate;
98
use rustc_type_ir::TraitRef as IrTraitRef;
9+
use rustc_type_ir::ProjectionPredicate as IrProjectionPredicate;
10+
use rustc_type_ir::ExistentialTraitRef as IrExistentialTraitRef;
11+
use rustc_type_ir::ExistentialProjection as IrExistentialProjection;
1012
use std::cmp::Ordering;
1113

12-
use crate::ty::visit::TypeVisitableExt;
1314
use crate::ty::{
14-
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArgsRef,
15+
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder,
1516
PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
1617
};
1718

1819
pub type TraitRef<'tcx> = IrTraitRef<TyCtxt<'tcx>>;
20+
pub type ProjectionPredicate<'tcx> = IrProjectionPredicate<TyCtxt<'tcx>>;
21+
pub type ExistentialTraitRef<'tcx> = IrExistentialTraitRef<TyCtxt<'tcx>>;
22+
pub type ExistentialProjection<'tcx> = IrExistentialProjection<TyCtxt<'tcx>>;
1923
pub type TraitPredicate<'tcx> = IrTraitPredicate<TyCtxt<'tcx>>;
2024
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
2125
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
@@ -342,52 +346,6 @@ impl<'tcx> PolyTraitRef<'tcx> {
342346
}
343347
}
344348

345-
/// An existential reference to a trait, where `Self` is erased.
346-
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
347-
/// ```ignore (illustrative)
348-
/// exists T. T: Trait<'a, 'b, X, Y>
349-
/// ```
350-
/// The generic parameters don't include the erased `Self`, only trait
351-
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
352-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
353-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
354-
pub struct ExistentialTraitRef<'tcx> {
355-
pub def_id: DefId,
356-
pub args: GenericArgsRef<'tcx>,
357-
}
358-
359-
impl<'tcx> ExistentialTraitRef<'tcx> {
360-
pub fn erase_self_ty(
361-
tcx: TyCtxt<'tcx>,
362-
trait_ref: ty::TraitRef<'tcx>,
363-
) -> ty::ExistentialTraitRef<'tcx> {
364-
// Assert there is a Self.
365-
trait_ref.args.type_at(0);
366-
367-
ty::ExistentialTraitRef {
368-
def_id: trait_ref.def_id,
369-
args: tcx.mk_args(&trait_ref.args[1..]),
370-
}
371-
}
372-
373-
/// Object types don't have a self type specified. Therefore, when
374-
/// we convert the principal trait-ref into a normal trait-ref,
375-
/// you must give *some* self type. A common choice is `mk_err()`
376-
/// or some placeholder type.
377-
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> {
378-
// otherwise the escaping vars would be captured by the binder
379-
// debug_assert!(!self_ty.has_escaping_bound_vars());
380-
381-
ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
382-
}
383-
}
384-
385-
impl<'tcx> IntoDiagArg for ExistentialTraitRef<'tcx> {
386-
fn into_diag_arg(self) -> DiagArgValue {
387-
self.to_string().into_diag_arg()
388-
}
389-
}
390-
391349
pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>;
392350

393351
impl<'tcx> PolyExistentialTraitRef<'tcx> {
@@ -404,62 +362,8 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
404362
}
405363
}
406364

407-
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
408-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
409-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
410-
pub struct ExistentialProjection<'tcx> {
411-
pub def_id: DefId,
412-
pub args: GenericArgsRef<'tcx>,
413-
pub term: Term<'tcx>,
414-
}
415-
416365
pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>;
417366

418-
impl<'tcx> ExistentialProjection<'tcx> {
419-
/// Extracts the underlying existential trait reference from this projection.
420-
/// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
421-
/// then this function would return an `exists T. T: Iterator` existential trait
422-
/// reference.
423-
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
424-
let def_id = tcx.parent(self.def_id);
425-
let args_count = tcx.generics_of(def_id).count() - 1;
426-
let args = tcx.mk_args(&self.args[..args_count]);
427-
ty::ExistentialTraitRef { def_id, args }
428-
}
429-
430-
pub fn with_self_ty(
431-
&self,
432-
tcx: TyCtxt<'tcx>,
433-
self_ty: Ty<'tcx>,
434-
) -> ty::ProjectionPredicate<'tcx> {
435-
// otherwise the escaping regions would be captured by the binders
436-
debug_assert!(!self_ty.has_escaping_bound_vars());
437-
438-
ty::ProjectionPredicate {
439-
projection_ty: AliasTy::new(
440-
tcx,
441-
self.def_id,
442-
[self_ty.into()].into_iter().chain(self.args),
443-
),
444-
term: self.term,
445-
}
446-
}
447-
448-
pub fn erase_self_ty(
449-
tcx: TyCtxt<'tcx>,
450-
projection_predicate: ty::ProjectionPredicate<'tcx>,
451-
) -> Self {
452-
// Assert there is a Self.
453-
projection_predicate.projection_ty.args.type_at(0);
454-
455-
Self {
456-
def_id: projection_predicate.projection_ty.def_id,
457-
args: tcx.mk_args(&projection_predicate.projection_ty.args[1..]),
458-
term: projection_predicate.term,
459-
}
460-
}
461-
}
462-
463367
impl<'tcx> PolyExistentialProjection<'tcx> {
464368
pub fn with_self_ty(
465369
&self,
@@ -628,43 +532,6 @@ pub struct CoercePredicate<'tcx> {
628532
}
629533
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
630534

631-
/// This kind of predicate has no *direct* correspondent in the
632-
/// syntax, but it roughly corresponds to the syntactic forms:
633-
///
634-
/// 1. `T: TraitRef<..., Item = Type>`
635-
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
636-
///
637-
/// In particular, form #1 is "desugared" to the combination of a
638-
/// normal trait predicate (`T: TraitRef<...>`) and one of these
639-
/// predicates. Form #2 is a broader form in that it also permits
640-
/// equality between arbitrary types. Processing an instance of
641-
/// Form #2 eventually yields one of these `ProjectionPredicate`
642-
/// instances to normalize the LHS.
643-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
644-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
645-
pub struct ProjectionPredicate<'tcx> {
646-
pub projection_ty: AliasTy<'tcx>,
647-
pub term: Term<'tcx>,
648-
}
649-
650-
impl<'tcx> ProjectionPredicate<'tcx> {
651-
pub fn self_ty(self) -> Ty<'tcx> {
652-
self.projection_ty.self_ty()
653-
}
654-
655-
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ProjectionPredicate<'tcx> {
656-
Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self }
657-
}
658-
659-
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
660-
self.projection_ty.trait_def_id(tcx)
661-
}
662-
663-
pub fn def_id(self) -> DefId {
664-
self.projection_ty.def_id
665-
}
666-
}
667-
668535
pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
669536

670537
impl<'tcx> PolyProjectionPredicate<'tcx> {

‎compiler/rustc_middle/src/ty/print/pretty.rs‎

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3087,14 +3087,6 @@ define_print! {
30873087
ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)),
30883088
}
30893089
}
3090-
}
3091-
3092-
define_print_and_forward_display! {
3093-
(self, cx):
3094-
3095-
&'tcx ty::List<Ty<'tcx>> {
3096-
p!("{{", comma_sep(self.iter()), "}}")
3097-
}
30983090

30993091
ty::ExistentialTraitRef<'tcx> {
31003092
// Use a type that can't appear in defaults of type parameters.
@@ -3108,6 +3100,20 @@ define_print_and_forward_display! {
31083100
p!(write("{} = ", name), print(self.term))
31093101
}
31103102

3103+
ty::ProjectionPredicate<'tcx> {
3104+
p!(print(self.projection_ty), " == ");
3105+
cx.reset_type_limit();
3106+
p!(print(self.term))
3107+
}
3108+
}
3109+
3110+
define_print_and_forward_display! {
3111+
(self, cx):
3112+
3113+
&'tcx ty::List<Ty<'tcx>> {
3114+
p!("{{", comma_sep(self.iter()), "}}")
3115+
}
3116+
31113117
ty::ExistentialPredicate<'tcx> {
31123118
match *self {
31133119
ty::ExistentialPredicate::Trait(x) => p!(print(x)),
@@ -3186,12 +3192,6 @@ define_print_and_forward_display! {
31863192
p!(print(self.b))
31873193
}
31883194

3189-
ty::ProjectionPredicate<'tcx> {
3190-
p!(print(self.projection_ty), " == ");
3191-
cx.reset_type_limit();
3192-
p!(print(self.term))
3193-
}
3194-
31953195
ty::NormalizesTo<'tcx> {
31963196
p!(print(self.alias), " normalizes-to ");
31973197
cx.reset_type_limit();

‎compiler/rustc_middle/src/ty/structural_impls.rs‎

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ impl fmt::Debug for ty::UpvarId {
5555
}
5656
}
5757

58-
impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
59-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60-
with_no_trimmed_paths!(fmt::Display::fmt(self, f))
61-
}
62-
}
63-
6458
impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
6559
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6660
write!(f, "{:?} -> {}", self.kind, self.target)
@@ -158,12 +152,6 @@ impl fmt::Debug for ty::ParamConst {
158152
}
159153
}
160154

161-
impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
162-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163-
write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term)
164-
}
165-
}
166-
167155
impl<'tcx> fmt::Debug for ty::NormalizesTo<'tcx> {
168156
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169157
write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)

‎compiler/rustc_middle/src/ty/sty.rs‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,36 @@ pub struct AliasTy<'tcx> {
11421142
_use_alias_ty_new_instead: (),
11431143
}
11441144

1145+
impl<'tcx> rustc_type_ir::inherent::AliasTy<TyCtxt<'tcx>> for AliasTy<'tcx> {
1146+
fn new(
1147+
interner: TyCtxt<'tcx>,
1148+
trait_def_id: DefId,
1149+
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
1150+
) -> Self {
1151+
AliasTy::new(interner, trait_def_id, args)
1152+
}
1153+
1154+
fn def_id(self) -> DefId {
1155+
self.def_id
1156+
}
1157+
1158+
fn args(self) -> ty::GenericArgsRef<'tcx> {
1159+
self.args
1160+
}
1161+
1162+
fn trait_def_id(self, interner: TyCtxt<'tcx>) -> DefId {
1163+
self.trait_def_id(interner)
1164+
}
1165+
1166+
fn self_ty(self) -> Ty<'tcx> {
1167+
self.self_ty()
1168+
}
1169+
1170+
fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
1171+
self.with_self_ty(tcx, self_ty)
1172+
}
1173+
}
1174+
11451175
impl<'tcx> AliasTy<'tcx> {
11461176
pub fn new(
11471177
tcx: TyCtxt<'tcx>,

‎compiler/rustc_type_ir/src/inherent.rs‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fmt::Debug;
22
use std::hash::Hash;
3+
use std::ops::Deref;
34

45
use crate::fold::TypeSuperFoldable;
56
use crate::visit::{Flags, TypeSuperVisitable};
@@ -50,7 +51,12 @@ pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
5051
}
5152

5253
pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
53-
Copy + DebugWithInfcx<I> + Hash + Eq + IntoIterator<Item = I::GenericArg>
54+
Copy
55+
+ DebugWithInfcx<I>
56+
+ Hash
57+
+ Eq
58+
+ IntoIterator<Item = I::GenericArg>
59+
+ Deref<Target: Deref<Target = [I::GenericArg]>>
5460
{
5561
fn type_at(self, i: usize) -> I::Ty;
5662

@@ -83,3 +89,23 @@ pub trait BoundVars<I: Interner> {
8389

8490
fn has_no_bound_vars(&self) -> bool;
8591
}
92+
93+
// TODO: Uplift `AliasTy`
94+
pub trait AliasTy<I: Interner>: Copy + DebugWithInfcx<I> + Hash + Eq + Sized {
95+
fn new(
96+
interner: I,
97+
trait_def_id: I::DefId,
98+
args: impl IntoIterator<Item: Into<I::GenericArg>>,
99+
) -> Self;
100+
101+
fn def_id(self) -> I::DefId;
102+
103+
fn args(self) -> I::GenericArgs;
104+
105+
fn trait_def_id(self, interner: I) -> I::DefId;
106+
107+
fn self_ty(self) -> I::Ty;
108+
109+
fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self;
110+
111+
}

‎compiler/rustc_type_ir/src/interner.rs‎

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,20 @@ use std::hash::Hash;
55
use crate::inherent::*;
66
use crate::ir_print::IrPrint;
77
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
8-
use crate::{CanonicalVarInfo, DebugWithInfcx, TraitPredicate, TraitRef};
9-
10-
pub trait Interner: Sized + Copy + IrPrint<TraitRef<Self>> + IrPrint<TraitPredicate<Self>> {
8+
use crate::{
9+
CanonicalVarInfo, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef,
10+
ProjectionPredicate, TraitPredicate, TraitRef,
11+
};
12+
13+
pub trait Interner:
14+
Sized
15+
+ Copy
16+
+ IrPrint<TraitRef<Self>>
17+
+ IrPrint<TraitPredicate<Self>>
18+
+ IrPrint<ExistentialTraitRef<Self>>
19+
+ IrPrint<ExistentialProjection<Self>>
20+
+ IrPrint<ProjectionPredicate<Self>>
21+
{
1122
type DefId: Copy + Debug + Hash + Eq;
1223
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
1324
type AdtDef: Copy + Debug + Hash + Eq;
@@ -25,7 +36,7 @@ pub trait Interner: Sized + Copy + IrPrint<TraitRef<Self>> + IrPrint<TraitPredic
2536
// Kinds of tys
2637
type Ty: Ty<Self>;
2738
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
28-
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Eq;
39+
type AliasTy: AliasTy<Self>;
2940
type ParamTy: Copy + Debug + Hash + Eq;
3041
type BoundTy: Copy + Debug + Hash + Eq;
3142
type PlaceholderTy: PlaceholderLike;
@@ -71,11 +82,15 @@ pub trait Interner: Sized + Copy + IrPrint<TraitRef<Self>> + IrPrint<TraitPredic
7182
type GenericsOf: GenericsOf<Self>;
7283
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
7384

85+
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
86+
7487
fn check_and_mk_args(
7588
self,
7689
def_id: Self::DefId,
7790
args: impl IntoIterator<Item: Into<Self::GenericArg>>,
7891
) -> Self::GenericArgs;
92+
93+
fn parent(self, def_id: Self::DefId) -> Self::DefId;
7994
}
8095

8196
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`

‎compiler/rustc_type_ir/src/ir_print.rs‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use std::fmt;
22

3-
use crate::{Interner, TraitPredicate, TraitRef};
3+
use crate::{
4+
ExistentialProjection, ExistentialTraitRef, Interner, ProjectionPredicate, TraitPredicate,
5+
TraitRef,
6+
};
47

58
pub trait IrPrint<T> {
69
fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
@@ -31,6 +34,12 @@ macro_rules! define_debug_via_print {
3134
}
3235
}
3336

34-
define_display_via_print!(TraitRef, TraitPredicate,);
37+
define_display_via_print!(
38+
TraitRef,
39+
TraitPredicate,
40+
ExistentialTraitRef,
41+
ExistentialProjection,
42+
ProjectionPredicate
43+
);
3544

36-
define_debug_via_print!(TraitRef,);
45+
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);

‎compiler/rustc_type_ir/src/lib.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ mod infcx;
3939
mod interner;
4040
mod predicate_kind;
4141
mod region_kind;
42-
mod trait_ref;
42+
mod predicate;
4343

4444
pub use canonical::*;
4545
#[cfg(feature = "nightly")]
@@ -51,7 +51,7 @@ pub use infcx::InferCtxtLike;
5151
pub use interner::*;
5252
pub use predicate_kind::*;
5353
pub use region_kind::*;
54-
pub use trait_ref::*;
54+
pub use predicate::*;
5555
pub use ty_info::*;
5656
pub use ty_kind::*;
5757
pub use AliasKind::*;
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
use std::fmt;
2+
3+
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
4+
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
5+
6+
use crate::inherent::*;
7+
use crate::visit::TypeVisitableExt as _;
8+
use crate::Interner;
9+
10+
/// A complete reference to a trait. These take numerous guises in syntax,
11+
/// but perhaps the most recognizable form is in a where-clause:
12+
/// ```ignore (illustrative)
13+
/// T: Foo<U>
14+
/// ```
15+
/// This would be represented by a trait-reference where the `DefId` is the
16+
/// `DefId` for the trait `Foo` and the args define `T` as parameter 0,
17+
/// and `U` as parameter 1.
18+
///
19+
/// Trait references also appear in object types like `Foo<U>`, but in
20+
/// that case the `Self` parameter is absent from the generic parameters.
21+
#[derive(derivative::Derivative)]
22+
#[derivative(
23+
Clone(bound = ""),
24+
Copy(bound = ""),
25+
Hash(bound = ""),
26+
PartialEq(bound = ""),
27+
Eq(bound = "")
28+
)]
29+
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
30+
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
31+
pub struct TraitRef<I: Interner> {
32+
pub def_id: I::DefId,
33+
pub args: I::GenericArgs,
34+
/// This field exists to prevent the creation of `TraitRef` without
35+
/// calling [`TraitRef::new`].
36+
_use_trait_ref_new_instead: (),
37+
}
38+
39+
impl<I: Interner> TraitRef<I> {
40+
pub fn new(
41+
interner: I,
42+
trait_def_id: I::DefId,
43+
args: impl IntoIterator<Item: Into<I::GenericArg>>,
44+
) -> Self {
45+
let args = interner.check_and_mk_args(trait_def_id, args);
46+
Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
47+
}
48+
49+
pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
50+
let generics = interner.generics_of(trait_id);
51+
TraitRef::new(interner, trait_id, args.into_iter().take(generics.count()))
52+
}
53+
54+
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
55+
/// are the parameters defined on trait.
56+
pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> {
57+
TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id))
58+
}
59+
60+
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
61+
TraitRef::new(
62+
interner,
63+
self.def_id,
64+
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
65+
)
66+
}
67+
68+
#[inline]
69+
pub fn self_ty(&self) -> I::Ty {
70+
self.args.type_at(0)
71+
}
72+
}
73+
74+
#[derive(derivative::Derivative)]
75+
#[derivative(
76+
Clone(bound = ""),
77+
Copy(bound = ""),
78+
Hash(bound = ""),
79+
PartialEq(bound = ""),
80+
Eq(bound = "")
81+
)]
82+
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
83+
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
84+
pub struct TraitPredicate<I: Interner> {
85+
pub trait_ref: TraitRef<I>,
86+
87+
/// If polarity is Positive: we are proving that the trait is implemented.
88+
///
89+
/// If polarity is Negative: we are proving that a negative impl of this trait
90+
/// exists. (Note that coherence also checks whether negative impls of supertraits
91+
/// exist via a series of predicates.)
92+
///
93+
/// If polarity is Reserved: that's a bug.
94+
pub polarity: PredicatePolarity,
95+
}
96+
97+
impl<I: Interner> TraitPredicate<I> {
98+
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
99+
Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity }
100+
}
101+
102+
pub fn def_id(self) -> I::DefId {
103+
self.trait_ref.def_id
104+
}
105+
106+
pub fn self_ty(self) -> I::Ty {
107+
self.trait_ref.self_ty()
108+
}
109+
}
110+
111+
impl<I: Interner> fmt::Debug for TraitPredicate<I> {
112+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113+
// FIXME(effects) printing?
114+
write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
115+
}
116+
}
117+
118+
/// Polarity for a trait predicate. May either be negative or positive.
119+
/// Distinguished from [`ImplPolarity`] since we never compute goals with
120+
/// "reservation" level.
121+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
122+
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
123+
pub enum PredicatePolarity {
124+
/// `Type: Trait`
125+
Positive,
126+
/// `Type: !Trait`
127+
Negative,
128+
}
129+
130+
impl PredicatePolarity {
131+
/// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`.
132+
pub fn flip(&self) -> PredicatePolarity {
133+
match self {
134+
PredicatePolarity::Positive => PredicatePolarity::Negative,
135+
PredicatePolarity::Negative => PredicatePolarity::Positive,
136+
}
137+
}
138+
}
139+
140+
impl fmt::Display for PredicatePolarity {
141+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142+
match self {
143+
Self::Positive => f.write_str("positive"),
144+
Self::Negative => f.write_str("negative"),
145+
}
146+
}
147+
}
148+
149+
/// An existential reference to a trait, where `Self` is erased.
150+
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
151+
/// ```ignore (illustrative)
152+
/// exists T. T: Trait<'a, 'b, X, Y>
153+
/// ```
154+
/// The generic parameters don't include the erased `Self`, only trait
155+
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
156+
#[derive(derivative::Derivative)]
157+
#[derivative(
158+
Clone(bound = ""),
159+
Copy(bound = ""),
160+
Hash(bound = ""),
161+
PartialEq(bound = ""),
162+
Eq(bound = "")
163+
)]
164+
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
165+
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
166+
pub struct ExistentialTraitRef<I: Interner> {
167+
pub def_id: I::DefId,
168+
pub args: I::GenericArgs,
169+
}
170+
171+
impl<I: Interner> ExistentialTraitRef<I> {
172+
pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
173+
// Assert there is a Self.
174+
trait_ref.args.type_at(0);
175+
176+
ExistentialTraitRef {
177+
def_id: trait_ref.def_id,
178+
args: interner.mk_args(&trait_ref.args[1..]),
179+
}
180+
}
181+
182+
/// Object types don't have a self type specified. Therefore, when
183+
/// we convert the principal trait-ref into a normal trait-ref,
184+
/// you must give *some* self type. A common choice is `mk_err()`
185+
/// or some placeholder type.
186+
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> {
187+
// otherwise the escaping vars would be captured by the binder
188+
// debug_assert!(!self_ty.has_escaping_bound_vars());
189+
190+
TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.into_iter()))
191+
}
192+
}
193+
194+
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
195+
#[derive(derivative::Derivative)]
196+
#[derivative(
197+
Clone(bound = ""),
198+
Copy(bound = ""),
199+
Hash(bound = ""),
200+
PartialEq(bound = ""),
201+
Eq(bound = "")
202+
)]
203+
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
204+
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
205+
pub struct ExistentialProjection<I: Interner> {
206+
pub def_id: I::DefId,
207+
pub args: I::GenericArgs,
208+
pub term: I::Term,
209+
}
210+
211+
impl<I: Interner> ExistentialProjection<I> {
212+
/// Extracts the underlying existential trait reference from this projection.
213+
/// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
214+
/// then this function would return an `exists T. T: Iterator` existential trait
215+
/// reference.
216+
pub fn trait_ref(&self, tcx: I) -> ExistentialTraitRef<I> {
217+
let def_id = tcx.parent(self.def_id);
218+
let args_count = tcx.generics_of(def_id).count() - 1;
219+
let args = tcx.mk_args(&self.args[..args_count]);
220+
ExistentialTraitRef { def_id, args }
221+
}
222+
223+
pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
224+
// otherwise the escaping regions would be captured by the binders
225+
debug_assert!(!self_ty.has_escaping_bound_vars());
226+
227+
ProjectionPredicate {
228+
projection_ty: I::AliasTy::new(
229+
tcx,
230+
self.def_id,
231+
[self_ty.into()].into_iter().chain(self.args),
232+
),
233+
term: self.term,
234+
}
235+
}
236+
237+
pub fn erase_self_ty(tcx: I, projection_predicate: ProjectionPredicate<I>) -> Self {
238+
// Assert there is a Self.
239+
projection_predicate.projection_ty.args().type_at(0);
240+
241+
Self {
242+
def_id: projection_predicate.projection_ty.def_id(),
243+
args: tcx.mk_args(&projection_predicate.projection_ty.args()[1..]),
244+
term: projection_predicate.term,
245+
}
246+
}
247+
}
248+
249+
/// This kind of predicate has no *direct* correspondent in the
250+
/// syntax, but it roughly corresponds to the syntactic forms:
251+
///
252+
/// 1. `T: TraitRef<..., Item = Type>`
253+
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
254+
///
255+
/// In particular, form #1 is "desugared" to the combination of a
256+
/// normal trait predicate (`T: TraitRef<...>`) and one of these
257+
/// predicates. Form #2 is a broader form in that it also permits
258+
/// equality between arbitrary types. Processing an instance of
259+
/// Form #2 eventually yields one of these `ProjectionPredicate`
260+
/// instances to normalize the LHS.
261+
#[derive(derivative::Derivative)]
262+
#[derivative(
263+
Clone(bound = ""),
264+
Copy(bound = ""),
265+
Hash(bound = ""),
266+
PartialEq(bound = ""),
267+
Eq(bound = "")
268+
)]
269+
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
270+
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
271+
pub struct ProjectionPredicate<I: Interner> {
272+
pub projection_ty: I::AliasTy,
273+
pub term: I::Term,
274+
}
275+
276+
impl<I: Interner> ProjectionPredicate<I> {
277+
pub fn self_ty(self) -> I::Ty {
278+
self.projection_ty.self_ty()
279+
}
280+
281+
pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
282+
Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self }
283+
}
284+
285+
pub fn trait_def_id(self, tcx: I) -> I::DefId {
286+
self.projection_ty.trait_def_id(tcx)
287+
}
288+
289+
pub fn def_id(self) -> I::DefId {
290+
self.projection_ty.def_id()
291+
}
292+
}
293+
294+
impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
295+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296+
write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term)
297+
}
298+
}

‎compiler/rustc_type_ir/src/trait_ref.rs‎

Lines changed: 0 additions & 146 deletions
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.