Skip to content

Commit

Permalink
Always use the stronger outlives version for opaque types
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewjasper committed May 12, 2019
1 parent 16e356e commit 664c8ed
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
34 changes: 28 additions & 6 deletions src/librustc/infer/opaque_types/mod.rs
Expand Up @@ -284,18 +284,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
debug!("constrain_opaque_type: def_id={:?}", def_id);
debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn);

let tcx = self.tcx;

let concrete_ty = self.resolve_type_vars_if_possible(&opaque_defn.concrete_ty);

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

let abstract_type_generics = self.tcx.generics_of(def_id);
let abstract_type_generics = tcx.generics_of(def_id);

let span = self.tcx.def_span(def_id);
let span = tcx.def_span(def_id);

// If there are required region bounds, we can just skip
// ahead. There will already be a registered region
// obligation related `concrete_ty` to those regions.
// If there are required region bounds, we can use them.
if opaque_defn.has_required_region_bounds {
let predicates_of = tcx.predicates_of(def_id);
debug!(
"constrain_opaque_type: predicates: {:#?}",
predicates_of,
);
let bounds = predicates_of.instantiate(tcx, opaque_defn.substs);
debug!("constrain_opaque_type: bounds={:#?}", bounds);
let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs);

let required_region_bounds = tcx.required_region_bounds(
opaque_type,
bounds.predicates.clone(),
);
debug_assert!(!required_region_bounds.is_empty());

for region in required_region_bounds {
concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {
infcx: self,
least_region: region,
span,
});
}
return;
}

Expand Down Expand Up @@ -371,7 +393,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}

let least_region = least_region.unwrap_or(self.tcx.lifetimes.re_static);
let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
debug!("constrain_opaque_types: least_region={:?}", least_region);

concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/impl-trait/can-return-unconstrained-closure.rs
Expand Up @@ -16,4 +16,8 @@ fn make_identity() -> impl Sized {
|x: &'static i32| x
}

fn make_identity_static() -> impl Sized + 'static {
|x: &'static i32| x
}

fn main() {}
7 changes: 7 additions & 0 deletions src/test/ui/impl-trait/issue-57464-unexpected-regions.rs
Expand Up @@ -17,6 +17,13 @@ fn wrapped_closure() -> impl Sized {
A(f)
}

fn wrapped_closure_with_bound() -> impl Sized + 'static {
let f = |x| x;
f(&0);
A(f)
}

fn main() {
let x: Box<dyn Send> = Box::new(wrapped_closure());
let y: Box<dyn Send> = Box::new(wrapped_closure_with_bound());
}

0 comments on commit 664c8ed

Please sign in to comment.