Skip to content

Commit

Permalink
Auto merge of rust-lang#60765 - matthewjasper:fix-more-escaping-resco…
Browse files Browse the repository at this point in the history
…pes, r=oli-obk

Fix more escaping ReScopes

Closes rust-lang#58840
  • Loading branch information
bors committed May 13, 2019
2 parents fe5f42c + 9a4f0ab commit 69ef8fb
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 10 deletions.
56 changes: 46 additions & 10 deletions src/librustc/infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
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 Expand Up @@ -589,10 +611,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx>
ty::ReLateBound(..) |

// ignore `'static`, as that can appear anywhere
ty::ReStatic |

// ignore `ReScope`, which may appear in impl Trait in bindings.
ty::ReScope(..) => return r,
ty::ReStatic => return r,

_ => { }
}
Expand Down Expand Up @@ -683,6 +702,23 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx>
self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs })
}

ty::Generator(def_id, substs, movability) => {
let generics = self.tcx.generics_of(def_id);
let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map(
|(index, &kind)| {
if index < generics.parent_count {
// Accommodate missing regions in the parent kinds...
self.fold_kind_mapping_missing_regions_to_empty(kind)
} else {
// ...but not elsewhere.
self.fold_kind_normally(kind)
}
},
));

self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability)
}

_ => ty.super_fold_with(self),
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/test/run-pass/impl-trait/lifetimes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// run-pass

#![allow(warnings)]
#![feature(generators)]

use std::fmt::Debug;

Expand Down Expand Up @@ -112,6 +113,11 @@ impl<'unnecessary_lifetime> MyVec {
fn iter_doesnt_capture_unnecessary_lifetime<'s>(&'s self) -> impl Iterator<Item = &'s u8> {
self.0.iter().flat_map(|inner_vec| inner_vec.iter())
}

fn generator_doesnt_capture_unnecessary_lifetime<'s: 's>() -> impl Sized {
|| yield
}
}


fn main() {}
4 changes: 4 additions & 0 deletions src/test/ui/impl-trait/can-return-unconstrained-closure.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 69ef8fb

Please sign in to comment.