Skip to content

Commit 664c8ed

Browse files
committed
Always use the stronger outlives version for opaque types
1 parent 16e356e commit 664c8ed

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

src/librustc/infer/opaque_types/mod.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,18 +284,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
284284
debug!("constrain_opaque_type: def_id={:?}", def_id);
285285
debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn);
286286

287+
let tcx = self.tcx;
288+
287289
let concrete_ty = self.resolve_type_vars_if_possible(&opaque_defn.concrete_ty);
288290

289291
debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);
290292

291-
let abstract_type_generics = self.tcx.generics_of(def_id);
293+
let abstract_type_generics = tcx.generics_of(def_id);
292294

293-
let span = self.tcx.def_span(def_id);
295+
let span = tcx.def_span(def_id);
294296

295-
// If there are required region bounds, we can just skip
296-
// ahead. There will already be a registered region
297-
// obligation related `concrete_ty` to those regions.
297+
// If there are required region bounds, we can use them.
298298
if opaque_defn.has_required_region_bounds {
299+
let predicates_of = tcx.predicates_of(def_id);
300+
debug!(
301+
"constrain_opaque_type: predicates: {:#?}",
302+
predicates_of,
303+
);
304+
let bounds = predicates_of.instantiate(tcx, opaque_defn.substs);
305+
debug!("constrain_opaque_type: bounds={:#?}", bounds);
306+
let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs);
307+
308+
let required_region_bounds = tcx.required_region_bounds(
309+
opaque_type,
310+
bounds.predicates.clone(),
311+
);
312+
debug_assert!(!required_region_bounds.is_empty());
313+
314+
for region in required_region_bounds {
315+
concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {
316+
infcx: self,
317+
least_region: region,
318+
span,
319+
});
320+
}
299321
return;
300322
}
301323

@@ -371,7 +393,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
371393
}
372394
}
373395

374-
let least_region = least_region.unwrap_or(self.tcx.lifetimes.re_static);
396+
let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
375397
debug!("constrain_opaque_types: least_region={:?}", least_region);
376398

377399
concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {

src/test/ui/impl-trait/can-return-unconstrained-closure.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ fn make_identity() -> impl Sized {
1616
|x: &'static i32| x
1717
}
1818

19+
fn make_identity_static() -> impl Sized + 'static {
20+
|x: &'static i32| x
21+
}
22+
1923
fn main() {}

src/test/ui/impl-trait/issue-57464-unexpected-regions.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ fn wrapped_closure() -> impl Sized {
1717
A(f)
1818
}
1919

20+
fn wrapped_closure_with_bound() -> impl Sized + 'static {
21+
let f = |x| x;
22+
f(&0);
23+
A(f)
24+
}
25+
2026
fn main() {
2127
let x: Box<dyn Send> = Box::new(wrapped_closure());
28+
let y: Box<dyn Send> = Box::new(wrapped_closure_with_bound());
2229
}

0 commit comments

Comments
 (0)