Skip to content

Commit 91c52c7

Browse files
committed
feat: Add ViewKind as a mirror on TyKind
But it instead provies "view" types when possible
1 parent 043f260 commit 91c52c7

File tree

9 files changed

+108
-114
lines changed

9 files changed

+108
-114
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
602602
continue;
603603
}
604604

605-
let verify_kind_ty = verify.kind.to_ty(self.tcx());
605+
let verify_kind_ty = verify.kind.as_ty();
606606
if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) {
607607
continue;
608608
}

src/librustc/infer/outlives/obligations.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ where
337337
&mut self,
338338
origin: infer::SubregionOrigin<'tcx>,
339339
region: ty::Region<'tcx>,
340-
projection_ty: ty::ProjectionTy<'tcx>,
340+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
341341
) {
342342
debug!(
343343
"projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})",
@@ -376,8 +376,8 @@ where
376376
// #55756) in cases where you have e.g., `<T as Foo<'a>>::Item:
377377
// 'a` in the environment but `trait Foo<'b> { type Item: 'b
378378
// }` in the trait definition.
379-
approx_env_bounds.retain(|bound| match bound.0.kind {
380-
ty::Projection(projection_ty) => self
379+
approx_env_bounds.retain(|bound| match bound.0.into() {
380+
ty::view::Projection(projection_ty) => self
381381
.verify_bound
382382
.projection_declared_bounds_from_trait(projection_ty)
383383
.all(|r| r != bound.1),

src/librustc/infer/outlives/verify.rs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
3939
}
4040

4141
fn type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
42-
match ty.kind {
43-
ty::Param(_) => self.param_bound(View::new(ty).unwrap()),
44-
ty::Projection(data) => self.projection_bound(data),
42+
match ty.into() {
43+
ty::view::Param(p) => self.param_bound(p),
44+
ty::view::Projection(data) => self.projection_bound(data),
4545
_ => self.recursive_type_bound(ty),
4646
}
4747
}
@@ -78,9 +78,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
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
) -> Vec<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
83-
let projection_ty = GenericKind::Projection(projection_ty).to_ty(self.tcx);
83+
let projection_ty = projection_ty.as_ty();
8484
let erased_projection_ty = self.tcx.erase_regions(&projection_ty);
8585
self.declared_generic_bounds_from_env_with_compare_fn(|ty| {
8686
if let ty::Projection(..) = ty.kind {
@@ -97,32 +97,37 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
9797
/// exact match.
9898
pub fn projection_declared_bounds_from_trait(
9999
&self,
100-
projection_ty: ty::ProjectionTy<'tcx>,
100+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
101101
) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'tcx> {
102102
self.declared_projection_bounds_from_trait(projection_ty)
103103
}
104104

105-
pub fn projection_bound(&self, projection_ty: ty::ProjectionTy<'tcx>) -> VerifyBound<'tcx> {
105+
pub fn projection_bound(
106+
&self,
107+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
108+
) -> VerifyBound<'tcx> {
106109
debug!("projection_bound(projection_ty={:?})", projection_ty);
107110

108-
let projection_ty_as_ty =
109-
self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
111+
let projection_ty_as_ty = projection_ty.as_ty();
112+
113+
let mut bounds = Vec::new();
110114

111115
// Search the env for where clauses like `P: 'a`.
112-
let env_bounds = self
113-
.projection_approx_declared_bounds_from_env(projection_ty)
114-
.into_iter()
115-
.map(|ty::OutlivesPredicate(ty, r)| {
116-
let vb = VerifyBound::OutlivedBy(r);
117-
if ty == projection_ty_as_ty {
118-
// Micro-optimize if this is an exact match (this
119-
// occurs often when there are no region variables
120-
// involved).
121-
vb
122-
} else {
123-
VerifyBound::IfEq(ty, Box::new(vb))
124-
}
125-
});
116+
bounds.extend(
117+
self.projection_approx_declared_bounds_from_env(projection_ty).into_iter().map(
118+
|ty::OutlivesPredicate(ty, r)| {
119+
let vb = VerifyBound::OutlivedBy(r);
120+
if ty == projection_ty_as_ty {
121+
// Micro-optimize if this is an exact match (this
122+
// occurs often when there are no region variables
123+
// involved).
124+
vb
125+
} else {
126+
VerifyBound::IfEq(ty, Box::new(vb))
127+
}
128+
},
129+
),
130+
);
126131

127132
// Extend with bounds that we can find from the trait.
128133
let trait_bounds = self
@@ -198,7 +203,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
198203
"declared_generic_bounds_from_env_with_compare_fn: region_bound_pair = {:?}",
199204
(r, p)
200205
);
201-
let p_ty = p.to_ty(tcx);
206+
let p_ty = p.as_ty();
202207
compare_ty(p_ty).then_some(ty::OutlivesPredicate(p_ty, r))
203208
});
204209

@@ -227,7 +232,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
227232
/// `region_bounds_declared_on_associated_item`.
228233
fn declared_projection_bounds_from_trait(
229234
&self,
230-
projection_ty: ty::ProjectionTy<'tcx>,
235+
projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>,
231236
) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'tcx> {
232237
debug!("projection_bounds(projection_ty={:?})", projection_ty);
233238
let tcx = self.tcx;

src/librustc/infer/region_constraints/mod.rs

Lines changed: 14 additions & 9 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
}
@@ -904,13 +904,18 @@ impl<'tcx> VerifyBound<'tcx> {
904904
}
905905
}
906906

907-
pub fn or(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> {
908-
if self.must_hold() || vb.cannot_hold() {
907+
pub fn or(self, vb: impl FnOnce() -> VerifyBound<'tcx>) -> VerifyBound<'tcx> {
908+
if self.must_hold() {
909909
self
910-
} else if self.cannot_hold() || vb.must_hold() {
911-
vb
912910
} else {
913-
VerifyBound::AnyBound(vec![self, vb])
911+
let vb = vb();
912+
if vb.cannot_hold() {
913+
self
914+
} else if self.cannot_hold() || vb.must_hold() {
915+
vb
916+
} else {
917+
VerifyBound::AnyBound(vec![self, vb])
918+
}
914919
}
915920
}
916921

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: 31 additions & 31 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
@@ -61,13 +61,13 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
6161
// in the `subtys` iterator (e.g., when encountering a
6262
// projection).
6363
match ty.kind {
64-
ty::Closure(def_id, ref substs) => {
64+
ty::view::Closure(def_id, ref substs) => {
6565
for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) {
6666
compute_components(tcx, upvar_ty, out);
6767
}
6868
}
6969

70-
ty::Generator(def_id, ref substs, _) => {
70+
ty::view::Generator(def_id, ref substs, _) => {
7171
// Same as the closure case
7272
for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) {
7373
compute_components(tcx, upvar_ty, out);
@@ -78,12 +78,12 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
7878
}
7979

8080
// All regions are bound inside a witness
81-
ty::GeneratorWitness(..) => (),
81+
ty::view::GeneratorWitness(..) => (),
8282

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

8989
// For projections, we prefer to generate an obligation like
@@ -94,15 +94,15 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
9494
// trait-ref. Therefore, if we see any higher-ranke regions,
9595
// we simply fallback to the most restrictive rule, which
9696
// requires that `Pi: 'a` for all `i`.
97-
ty::Projection(ref data) => {
97+
ty::view::Projection(data) => {
9898
if !data.has_escaping_bound_vars() {
9999
// best case: no escaping regions, so push the
100100
// projection and skip the subtree (thus generating no
101101
// constraints for Pi). This defers the choice between
102102
// the rules OutlivesProjectionEnv,
103103
// OutlivesProjectionTraitDef, and
104104
// OutlivesProjectionComponents to regionck.
105-
out.push(Component::Projection(*data));
105+
out.push(Component::Projection(data));
106106
} else {
107107
// fallback case: hard code
108108
// OutlivesProjectionComponents. Continue walking
@@ -112,12 +112,12 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
112112
}
113113
}
114114

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

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

@@ -127,27 +127,27 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
127127
// the type and then visits the types that are lexically
128128
// contained within. (The comments refer to relevant rules
129129
// from RFC1214.)
130-
ty::Bool | // OutlivesScalar
131-
ty::Char | // OutlivesScalar
132-
ty::Int(..) | // OutlivesScalar
133-
ty::Uint(..) | // OutlivesScalar
134-
ty::Float(..) | // OutlivesScalar
135-
ty::Never | // ...
136-
ty::Adt(..) | // OutlivesNominalType
137-
ty::Opaque(..) | // OutlivesNominalType (ish)
138-
ty::Foreign(..) | // OutlivesNominalType
139-
ty::Str | // OutlivesScalar (ish)
140-
ty::Array(..) | // ...
141-
ty::Slice(..) | // ...
142-
ty::RawPtr(..) | // ...
143-
ty::Ref(..) | // OutlivesReference
144-
ty::Tuple(..) | // ...
145-
ty::FnDef(..) | // OutlivesFunction (*)
146-
ty::FnPtr(_) | // OutlivesFunction (*)
147-
ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
148-
ty::Placeholder(..) |
149-
ty::Bound(..) |
150-
ty::Error => {
130+
ty::view::Bool | // OutlivesScalar
131+
ty::view::Char | // OutlivesScalar
132+
ty::view::Int(..) | // OutlivesScalar
133+
ty::view::Uint(..) | // OutlivesScalar
134+
ty::view::Float(..) | // OutlivesScalar
135+
ty::view::Never | // ...
136+
ty::view::Adt(..) | // OutlivesNominalType
137+
ty::view::Opaque(..) | // OutlivesNominalType (ish)
138+
ty::view::Foreign(..) | // OutlivesNominalType
139+
ty::view::Str | // OutlivesScalar (ish)
140+
ty::view::Array(..) | // ...
141+
ty::view::Slice(..) | // ...
142+
ty::view::RawPtr(..) | // ...
143+
ty::view::Ref(..) | // OutlivesReference
144+
ty::view::Tuple(..) | // ...
145+
ty::view::FnDef(..) | // OutlivesFunction (*)
146+
ty::view::FnPtr(_) | // OutlivesFunction (*)
147+
ty::view::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
148+
ty::view::Placeholder(..) |
149+
ty::view::Bound(..) |
150+
ty::view::Error => {
151151
// (*) Bare functions and traits are both binders. In the
152152
// RFC, this means we would add the bound regions to the
153153
// "bound regions list". In our representation, no such

0 commit comments

Comments
 (0)