Skip to content

Commit 8010cf8

Browse files
committed
feat: Add ViewKind as a mirror on TyKind
But it instead provies "view" types when possible
1 parent d9bbf2a commit 8010cf8

File tree

8 files changed

+73
-92
lines changed

8 files changed

+73
-92
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
606606
continue;
607607
}
608608

609-
let verify_kind_ty = verify.kind.to_ty(self.tcx());
609+
let verify_kind_ty = verify.kind.as_ty();
610610
if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) {
611611
continue;
612612
}

src/librustc/infer/outlives/obligations.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ where
348348
&mut self,
349349
origin: infer::SubregionOrigin<'tcx>,
350350
region: ty::Region<'tcx>,
351-
projection_ty: ty::ProjectionTy<'tcx>,
351+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
352352
) where
353353
'tcx: 'e,
354354
{
@@ -389,8 +389,8 @@ where
389389
// #55756) in cases where you have e.g., `<T as Foo<'a>>::Item:
390390
// 'a` in the environment but `trait Foo<'b> { type Item: 'b
391391
// }` in the trait definition.
392-
approx_env_bounds.retain(|bound| match bound.0.kind {
393-
ty::Projection(projection_ty) => self
392+
approx_env_bounds.retain(|bound| match bound.0.into() {
393+
ty::view::Projection(projection_ty) => self
394394
.verify_bound
395395
.projection_declared_bounds_from_trait(projection_ty)
396396
.all(|r| r != bound.1),

src/librustc/infer/outlives/verify.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
4141
}
4242

4343
fn type_bound(&mut self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
44-
match ty.kind {
45-
ty::Param(_) => self.param_bound(View::new(ty).unwrap()),
46-
ty::Projection(data) => self.projection_bound(data),
44+
match ty.into() {
45+
ty::view::Param(p) => self.param_bound(p),
46+
ty::view::Projection(data) => self.projection_bound(data),
4747
_ => self.recursive_type_bound(ty),
4848
}
4949
}
@@ -78,12 +78,12 @@ impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
7878
/// this list.
7979
pub fn projection_approx_declared_bounds_from_env(
8080
&self,
81-
projection_ty: ty::ProjectionTy<'tcx>,
81+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
8282
) -> impl Iterator<Item = ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> + Captures2<'cx, 'tcx>
8383
{
8484
let tcx = self.tcx;
8585

86-
let projection_ty = GenericKind::Projection(projection_ty).to_ty(tcx);
86+
let projection_ty = projection_ty.as_ty();
8787
let erased_projection_ty = tcx.erase_regions(&projection_ty);
8888
self.declared_generic_bounds_from_env_with_compare_fn(move |ty| {
8989
if let ty::Projection(..) = ty.kind {
@@ -100,16 +100,18 @@ impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
100100
/// exact match.
101101
pub fn projection_declared_bounds_from_trait<'a>(
102102
&'a mut self,
103-
projection_ty: ty::ProjectionTy<'tcx>,
103+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
104104
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
105105
self.declared_projection_bounds_from_trait(projection_ty)
106106
}
107107

108-
pub fn projection_bound(&mut self, projection_ty: ty::ProjectionTy<'tcx>) -> VerifyBound<'tcx> {
108+
pub fn projection_bound(
109+
&mut self,
110+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
111+
) -> VerifyBound<'tcx> {
109112
debug!("projection_bound(projection_ty={:?})", projection_ty);
110113

111-
let projection_ty_as_ty =
112-
self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
114+
let projection_ty_as_ty = projection_ty.as_ty();
113115

114116
// Search the env for where clauses like `P: 'a`.
115117
let mut bounds = Vec::new();
@@ -136,7 +138,7 @@ impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
136138

137139
VerifyBound::AnyBound(bounds).or(|| {
138140
// see the extensive comment in projection_must_outlive
139-
let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
141+
let ty = projection_ty.as_ty();
140142
self.recursive_type_bound(ty)
141143
})
142144
}
@@ -178,8 +180,6 @@ impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
178180
compare_ty: impl Fn(Ty<'tcx>) -> bool + Clone + 'tcx + Captures<'cx>,
179181
) -> impl Iterator<Item = ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> + Captures2<'cx, 'tcx>
180182
{
181-
let tcx = self.tcx;
182-
183183
// To start, collect bounds from user environment. Note that
184184
// parameter environments are already elaborated, so we don't
185185
// have to worry about that. Comparing using `==` is a bit
@@ -205,7 +205,7 @@ impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
205205
"declared_generic_bounds_from_env_with_compare_fn: region_bound_pair = {:?}",
206206
(r, p)
207207
);
208-
let p_ty = p.to_ty(tcx);
208+
let p_ty = p.as_ty();
209209
compare_ty(p_ty).then_some(ty::OutlivesPredicate(p_ty, r))
210210
});
211211

@@ -231,7 +231,7 @@ impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
231231
/// `region_bounds_declared_on_associated_item`.
232232
fn declared_projection_bounds_from_trait<'a>(
233233
&'a mut self,
234-
projection_ty: ty::ProjectionTy<'tcx>,
234+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
235235
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
236236
debug!("projection_bounds(projection_ty={:?})", projection_ty);
237237
let tcx = self.tcx;

src/librustc/infer/region_constraints/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ pub struct Verify<'tcx> {
185185
#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable)]
186186
pub enum GenericKind<'tcx> {
187187
Param(ty::View<'tcx, ty::ParamTy>),
188-
Projection(ty::ProjectionTy<'tcx>),
188+
Projection(ty::View<'tcx, ty::ProjectionTy<'tcx>>),
189189
}
190190

191191
/// Describes the things that some `GenericKind` value `G` is known to
@@ -875,10 +875,10 @@ impl<'tcx> fmt::Display for GenericKind<'tcx> {
875875
}
876876

877877
impl<'tcx> GenericKind<'tcx> {
878-
pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
878+
pub fn as_ty(&self) -> Ty<'tcx> {
879879
match *self {
880-
GenericKind::Param(ref p) => p.to_ty(tcx),
881-
GenericKind::Projection(ref p) => tcx.mk_projection(p.item_def_id, p.substs),
880+
GenericKind::Param(ref p) => p.as_ty(),
881+
GenericKind::Projection(ref p) => p.as_ty(),
882882
}
883883
}
884884
}

src/librustc/traits/query/outlives_bounds.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::mem;
2121
pub enum OutlivesBound<'tcx> {
2222
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
2323
RegionSubParam(ty::Region<'tcx>, ty::View<'tcx, ty::ParamTy>),
24-
RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>),
24+
RegionSubProjection(ty::Region<'tcx>, ty::View<'tcx, ty::ProjectionTy<'tcx>>),
2525
}
2626

2727
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OutlivesBound<'tcx> {

src/librustc/ty/outlives.rs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub enum Component<'tcx> {
2020
// is not in a position to judge which is the best technique, so
2121
// we just product the projection as a component and leave it to
2222
// the consumer to decide (but see `EscapingProjection` below).
23-
Projection(ty::ProjectionTy<'tcx>),
23+
Projection(ty::View<'tcx, ty::ProjectionTy<'tcx>>),
2424

2525
// In the case where a projection has escaping regions -- meaning
2626
// regions bound within the type itself -- we always use
@@ -63,14 +63,14 @@ impl<'tcx> TyCtxt<'tcx> {
6363
// with `collect()` because of the need to sometimes skip subtrees
6464
// in the `subtys` iterator (e.g., when encountering a
6565
// projection).
66-
match ty.kind {
67-
ty::Closure(def_id, ref substs) => {
66+
match ty.into() {
67+
ty::view::Closure(def_id, ref substs) => {
6868
for upvar_ty in substs.as_closure().upvar_tys(def_id, *self) {
6969
self.compute_components(upvar_ty, out);
7070
}
7171
}
7272

73-
ty::Generator(def_id, ref substs, _) => {
73+
ty::view::Generator(def_id, ref substs, _) => {
7474
// Same as the closure case
7575
for upvar_ty in substs.as_generator().upvar_tys(def_id, *self) {
7676
self.compute_components(upvar_ty, out);
@@ -81,12 +81,12 @@ impl<'tcx> TyCtxt<'tcx> {
8181
}
8282

8383
// All regions are bound inside a witness
84-
ty::GeneratorWitness(..) => (),
84+
ty::view::GeneratorWitness(..) => (),
8585

8686
// OutlivesTypeParameterEnv -- the actual checking that `X:'a`
8787
// is implied by the environment is done in regionck.
88-
ty::Param(_) => {
89-
out.push(Component::Param(ty::View::new(ty).unwrap()));
88+
ty::view::Param(p) => {
89+
out.push(Component::Param(p));
9090
}
9191

9292
// For projections, we prefer to generate an obligation like
@@ -97,15 +97,15 @@ impl<'tcx> TyCtxt<'tcx> {
9797
// trait-ref. Therefore, if we see any higher-ranke regions,
9898
// we simply fallback to the most restrictive rule, which
9999
// requires that `Pi: 'a` for all `i`.
100-
ty::Projection(ref data) => {
100+
ty::view::Projection(data) => {
101101
if !data.has_escaping_bound_vars() {
102102
// best case: no escaping regions, so push the
103103
// projection and skip the subtree (thus generating no
104104
// constraints for Pi). This defers the choice between
105105
// the rules OutlivesProjectionEnv,
106106
// OutlivesProjectionTraitDef, and
107107
// OutlivesProjectionComponents to regionck.
108-
out.push(Component::Projection(*data));
108+
out.push(Component::Projection(data));
109109
} else {
110110
// fallback case: hard code
111111
// OutlivesProjectionComponents. Continue walking
@@ -115,12 +115,12 @@ impl<'tcx> TyCtxt<'tcx> {
115115
}
116116
}
117117

118-
ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
118+
ty::view::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
119119

120120
// We assume that inference variables are fully resolved.
121121
// So, if we encounter an inference variable, just record
122122
// the unresolved variable as a component.
123-
ty::Infer(infer_ty) => {
123+
ty::view::Infer(infer_ty) => {
124124
out.push(Component::UnresolvedInferenceVariable(infer_ty));
125125
}
126126

@@ -130,27 +130,27 @@ impl<'tcx> TyCtxt<'tcx> {
130130
// the type and then visits the types that are lexically
131131
// contained within. (The comments refer to relevant rules
132132
// from RFC1214.)
133-
ty::Bool | // OutlivesScalar
134-
ty::Char | // OutlivesScalar
135-
ty::Int(..) | // OutlivesScalar
136-
ty::Uint(..) | // OutlivesScalar
137-
ty::Float(..) | // OutlivesScalar
138-
ty::Never | // ...
139-
ty::Adt(..) | // OutlivesNominalType
140-
ty::Opaque(..) | // OutlivesNominalType (ish)
141-
ty::Foreign(..) | // OutlivesNominalType
142-
ty::Str | // OutlivesScalar (ish)
143-
ty::Array(..) | // ...
144-
ty::Slice(..) | // ...
145-
ty::RawPtr(..) | // ...
146-
ty::Ref(..) | // OutlivesReference
147-
ty::Tuple(..) | // ...
148-
ty::FnDef(..) | // OutlivesFunction (*)
149-
ty::FnPtr(_) | // OutlivesFunction (*)
150-
ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
151-
ty::Placeholder(..) |
152-
ty::Bound(..) |
153-
ty::Error => {
133+
ty::view::Bool | // OutlivesScalar
134+
ty::view::Char | // OutlivesScalar
135+
ty::view::Int(..) | // OutlivesScalar
136+
ty::view::Uint(..) | // OutlivesScalar
137+
ty::view::Float(..) | // OutlivesScalar
138+
ty::view::Never | // ...
139+
ty::view::Adt(..) | // OutlivesNominalType
140+
ty::view::Opaque(..) | // OutlivesNominalType (ish)
141+
ty::view::Foreign(..) | // OutlivesNominalType
142+
ty::view::Str | // OutlivesScalar (ish)
143+
ty::view::Array(..) | // ...
144+
ty::view::Slice(..) | // ...
145+
ty::view::RawPtr(..) | // ...
146+
ty::view::Ref(..) | // OutlivesReference
147+
ty::view::Tuple(..) | // ...
148+
ty::view::FnDef(..) | // OutlivesFunction (*)
149+
ty::view::FnPtr(_) | // OutlivesFunction (*)
150+
ty::view::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
151+
ty::view::Placeholder(..) |
152+
ty::view::Bound(..) |
153+
ty::view::Error => {
154154
// (*) Bare functions and traits are both binders. In the
155155
// RFC, this means we would add the bound regions to the
156156
// "bound regions list". In our representation, no such

src/librustc/ty/view.rs

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -79,70 +79,51 @@ pub unsafe trait TyDeref<'tcx>: Sized {
7979
fn ty_deref(ty: Ty<'tcx>) -> Option<&'tcx Self>;
8080
}
8181

82-
unsafe impl<'tcx> TyDeref<'tcx> for ty::ParamTy {
83-
fn ty_deref(ty: Ty<'tcx>) -> Option<&'tcx Self> {
84-
match &ty.kind {
85-
ty::Param(p) => Some(p),
86-
_ => None,
82+
macro_rules! impl_ty_deref {
83+
($ty: ty, $variant: ident) => {
84+
unsafe impl<'tcx> TyDeref<'tcx> for $ty {
85+
fn ty_deref(ty: Ty<'tcx>) -> Option<&'tcx Self> {
86+
match &ty.kind {
87+
ty::$variant(p) => Some(p),
88+
_ => None,
89+
}
90+
}
8791
}
88-
}
92+
};
8993
}
9094

95+
impl_ty_deref! { ty::ParamTy, Param }
96+
impl_ty_deref! { ty::ProjectionTy<'tcx>, Projection }
97+
98+
/// Mirror of `TyKind`, but with `View` fields where there is need for it
9199
pub enum ViewKind<'tcx> {
92100
Bool,
93-
94101
Char,
95-
96102
Int(ast::IntTy),
97-
98103
Uint(ast::UintTy),
99-
100104
Float(ast::FloatTy),
101-
102105
Adt(&'tcx AdtDef, SubstsRef<'tcx>),
103-
104106
Foreign(DefId),
105-
106107
Str,
107-
108108
Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),
109-
110109
Slice(Ty<'tcx>),
111-
112110
RawPtr(TypeAndMut<'tcx>),
113-
114111
Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability),
115-
116112
FnDef(DefId, SubstsRef<'tcx>),
117-
118113
FnPtr(PolyFnSig<'tcx>),
119-
120114
Dynamic(Binder<&'tcx List<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
121-
122115
Closure(DefId, SubstsRef<'tcx>),
123-
124116
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
125-
126117
GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>),
127-
128118
Never,
129-
130119
Tuple(SubstsRef<'tcx>),
131-
132-
Projection(ProjectionTy<'tcx>),
133-
120+
Projection(View<'tcx, ProjectionTy<'tcx>>),
134121
UnnormalizedProjection(ProjectionTy<'tcx>),
135-
136122
Opaque(DefId, SubstsRef<'tcx>),
137-
138123
Param(View<'tcx, ParamTy>),
139-
140124
Bound(ty::DebruijnIndex, BoundTy),
141-
142125
Placeholder(ty::PlaceholderType),
143-
144126
Infer(InferTy),
145-
146127
Error,
147128
}
148129

@@ -161,7 +142,7 @@ impl<'tcx> From<Ty<'tcx>> for ViewKind<'tcx> {
161142
ty::Generator(did, substs, movability) => Self::Generator(did, substs, movability),
162143
ty::GeneratorWitness(types) => Self::GeneratorWitness(types),
163144
ty::Closure(did, substs) => Self::Closure(did, substs),
164-
ty::Projection(data) => Self::Projection(data),
145+
ty::Projection(_) => Self::Projection(View::new(ty).unwrap()),
165146
ty::UnnormalizedProjection(data) => Self::UnnormalizedProjection(data),
166147
ty::Opaque(did, substs) => Self::Opaque(did, substs),
167148
ty::Bool => Self::Bool,

src/librustc_mir/borrow_check/region_infer/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
815815
for type_test in &self.type_tests {
816816
debug!("check_type_test: {:?}", type_test);
817817

818-
let generic_ty = type_test.generic_kind.to_ty(tcx);
818+
let generic_ty = type_test.generic_kind.as_ty();
819819
if self.eval_verify_bound(
820820
tcx,
821821
body,
@@ -910,7 +910,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
910910

911911
let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test;
912912

913-
let generic_ty = generic_kind.to_ty(tcx);
913+
let generic_ty = generic_kind.as_ty();
914914
let subject = match self.try_promote_type_test_subject(infcx, generic_ty) {
915915
Some(s) => s,
916916
None => return false,

0 commit comments

Comments
 (0)