Skip to content

Commit 90b6744

Browse files
committed
Also collect bounds from the ParamEnv for opaque types
1 parent 37928f5 commit 90b6744

File tree

4 files changed

+34
-59
lines changed

4 files changed

+34
-59
lines changed

compiler/rustc_infer/src/infer/outlives/obligations.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ where
318318
);
319319

320320
let generic = GenericKind::Param(param_ty);
321-
let verify_bound = self.verify_bound.generic_bound(generic);
321+
let verify_bound = self.verify_bound.param_bound(param_ty);
322322
self.delegate.push_verify(origin, generic, region, verify_bound);
323323
}
324324

@@ -476,7 +476,12 @@ where
476476
// projection outlive; in some cases, this may add insufficient
477477
// edges into the inference graph, leading to inference failures
478478
// even though a satisfactory solution exists.
479-
let verify_bound = self.verify_bound.generic_bound(generic);
479+
let verify_bound = self.verify_bound.projection_opaque_bounds(
480+
generic,
481+
def_id,
482+
substs,
483+
&mut Default::default(),
484+
);
480485
debug!("projection_must_outlive: pushing {:?}", verify_bound);
481486
self.delegate.push_verify(origin, generic, region, verify_bound);
482487
}

compiler/rustc_infer/src/infer/outlives/verify.rs

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
3838
Self { tcx, region_bound_pairs, implicit_region_bound, param_env }
3939
}
4040

41-
/// Returns a "verify bound" that encodes what we know about
42-
/// `generic` and the regions it outlives.
43-
pub fn generic_bound(&self, generic: GenericKind<'tcx>) -> VerifyBound<'tcx> {
44-
let mut visited = SsoHashSet::new();
45-
match generic {
46-
GenericKind::Param(param_ty) => self.param_bound(param_ty),
47-
GenericKind::Projection(projection_ty) => {
48-
self.projection_bound(projection_ty, &mut visited)
49-
}
50-
GenericKind::Opaque(def_id, substs) => self.opaque_bound(def_id, substs),
51-
}
52-
}
53-
5441
#[instrument(level = "debug", skip(self))]
55-
fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
42+
pub fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
5643
// Start with anything like `T: 'a` we can scrape from the
5744
// environment. If the environment contains something like
5845
// `for<'a> T: 'a`, then we know that `T` outlives everything.
@@ -116,20 +103,21 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
116103
}
117104

118105
#[instrument(level = "debug", skip(self, visited))]
119-
fn projection_bound(
106+
pub fn projection_opaque_bounds(
120107
&self,
121-
projection_ty: ty::ProjectionTy<'tcx>,
108+
generic: GenericKind<'tcx>,
109+
def_id: DefId,
110+
substs: SubstsRef<'tcx>,
122111
visited: &mut SsoHashSet<GenericArg<'tcx>>,
123112
) -> VerifyBound<'tcx> {
124-
let projection_ty_as_ty =
125-
self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
113+
let generic_ty = generic.to_ty(self.tcx);
126114

127115
// Search the env for where clauses like `P: 'a`.
128-
let env_bounds = self
129-
.approx_declared_bounds_from_env(GenericKind::Projection(projection_ty))
116+
let projection_opaque_bounds = self
117+
.approx_declared_bounds_from_env(generic)
130118
.into_iter()
131119
.map(|binder| {
132-
if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars() && ty == projection_ty_as_ty {
120+
if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars() && ty == generic_ty {
133121
// Micro-optimize if this is an exact match (this
134122
// occurs often when there are no region variables
135123
// involved).
@@ -139,35 +127,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
139127
VerifyBound::IfEq(verify_if_eq_b)
140128
}
141129
});
142-
143130
// Extend with bounds that we can find from the trait.
144-
let trait_bounds = self
145-
.bounds(projection_ty.item_def_id, projection_ty.substs)
146-
.map(|r| VerifyBound::OutlivedBy(r));
131+
let trait_bounds = self.bounds(def_id, substs).map(|r| VerifyBound::OutlivedBy(r));
147132

148133
// see the extensive comment in projection_must_outlive
149134
let recursive_bound = {
150135
let mut components = smallvec![];
151-
let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
152-
compute_components_recursive(self.tcx, ty.into(), &mut components, visited);
136+
compute_components_recursive(self.tcx, generic_ty.into(), &mut components, visited);
153137
self.bound_from_components(&components, visited)
154138
};
155139

156-
VerifyBound::AnyBound(env_bounds.chain(trait_bounds).collect()).or(recursive_bound)
157-
}
158-
159-
fn opaque_bound(&self, def_id: DefId, substs: SubstsRef<'tcx>) -> VerifyBound<'tcx> {
160-
let bounds: Vec<_> =
161-
self.bounds(def_id, substs).map(|r| VerifyBound::OutlivedBy(r)).collect();
162-
trace!("{:#?}", bounds);
163-
if bounds.is_empty() {
164-
// No bounds means the value must not have any lifetimes.
165-
// FIXME: should we implicitly add 'static to `tcx.item_bounds` for opaque types, just
166-
// like we add `Sized`?
167-
VerifyBound::OutlivedBy(self.tcx.lifetimes.re_static)
168-
} else {
169-
VerifyBound::AnyBound(bounds)
170-
}
140+
VerifyBound::AnyBound(projection_opaque_bounds.chain(trait_bounds).collect())
141+
.or(recursive_bound)
171142
}
172143

173144
fn bound_from_components(
@@ -199,8 +170,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
199170
match *component {
200171
Component::Region(lt) => VerifyBound::OutlivedBy(lt),
201172
Component::Param(param_ty) => self.param_bound(param_ty),
202-
Component::Opaque(did, substs) => self.opaque_bound(did, substs),
203-
Component::Projection(projection_ty) => self.projection_bound(projection_ty, visited),
173+
Component::Opaque(did, substs) => self.projection_opaque_bounds(
174+
GenericKind::Opaque(did, substs),
175+
did,
176+
substs,
177+
visited,
178+
),
179+
Component::Projection(projection_ty) => self.projection_opaque_bounds(
180+
GenericKind::Projection(projection_ty),
181+
projection_ty.item_def_id,
182+
projection_ty.substs,
183+
visited,
184+
),
204185
Component::EscapingProjection(ref components) => {
205186
self.bound_from_components(components, visited)
206187
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
// check-pass
2+
13
#![feature(type_alias_impl_trait)]
24

35
type Ty<'a, A> = impl Sized + 'a;
46
fn defining<'a, A>() -> Ty<'a, A> {}
57
fn assert_static<T: 'static>() {}
68
fn test<'a, A>() where Ty<'a, A>: 'static, { assert_static::<Ty<'a, A>>() }
7-
//~^ ERROR: may not live long enough
89

910
fn main() {}

src/test/ui/type-alias-impl-trait/implied_bounds2.stderr

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

0 commit comments

Comments
 (0)