tcx: TyCtxt<'_, 'gcx, 'tcx>,
location: Location,
closure_def_id: DefId,
- closure_substs: ty::ClosureSubsts<'tcx>,
+ closure_substs: &'tcx ty::subst::Substs<'tcx>,
) -> Vec<QueryRegionConstraint<'tcx>>;
fn subst_closure_mapping<T>(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
location: Location,
closure_def_id: DefId,
- closure_substs: ty::ClosureSubsts<'tcx>,
+ closure_substs: &'tcx ty::subst::Substs<'tcx>,
) -> Vec<QueryRegionConstraint<'tcx>> {
debug!(
"apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})",
location, closure_def_id, closure_substs
);
- // Get Tu.
- let user_closure_ty = tcx.mk_closure(closure_def_id, closure_substs);
- debug!("apply_requirements: user_closure_ty={:?}", user_closure_ty);
-
- // Extract the values of the free regions in `user_closure_ty`
+ // Extract the values of the free regions in `closure_substs`
// into a vector. These are the regions that we will be
// relating to one another.
let closure_mapping = &UniversalRegions::closure_mapping(
tcx,
- user_closure_ty,
+ closure_substs,
self.num_external_vids,
tcx.closure_base_def_id(closure_def_id),
);
use rustc::traits::query::{Fallible, NoSolution};
use rustc::traits::{ObligationCause, PredicateObligations};
use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::{Subst, UnpackedKind};
+use rustc::ty::subst::{Subst, Substs, UnpackedKind};
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
use std::rc::Rc;
use std::{fmt, iter};
// desugaring. A closure gets desugared to a struct, and
// these extra requirements are basically like where
// clauses on the struct.
- AggregateKind::Closure(def_id, substs) => {
- self.prove_closure_bounds(tcx, *def_id, *substs, location)
- }
-
- AggregateKind::Generator(def_id, substs, _) => {
- tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)
+ AggregateKind::Closure(def_id, ty::ClosureSubsts { substs })
+ | AggregateKind::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
+ self.prove_closure_bounds(tcx, *def_id, substs, location)
}
AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
&mut self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
def_id: DefId,
- substs: ty::ClosureSubsts<'tcx>,
+ substs: &'tcx Substs<'tcx>,
location: Location,
) -> ty::InstantiatedPredicates<'tcx> {
if let Some(closure_region_requirements) =
);
}
- tcx.predicates_of(def_id).instantiate(tcx, substs.substs)
+ tcx.predicates_of(def_id).instantiate(tcx, substs)
}
fn prove_trait_ref(
/// `V[1]: V[2]`.
pub fn closure_mapping(
tcx: TyCtxt<'_, '_, 'tcx>,
- closure_ty: Ty<'tcx>,
+ closure_substs: &'tcx Substs<'tcx>,
expected_num_vars: usize,
closure_base_def_id: DefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.types.re_static);
- tcx.for_each_free_region(&closure_ty, |fr| {
+ tcx.for_each_free_region(&closure_substs, |fr| {
region_mapping.push(fr);
});
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/generator-region-requirements.rs:15:51
+ |
+LL | fn dangle(x: &mut i32) -> &'static mut i32 {
+ | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
+...
+LL | GeneratorState::Complete(c) => return c,
+ | ^ lifetime `'static` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/generator-region-requirements.rs:11:9
+ |
+LL | fn dangle(x: &mut i32) -> &'static mut i32 {
+ | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
+...
+LL | x
+ | ^ lifetime `'static` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+// revisions: ast nll
+// ignore-compare-mode-nll
+
+#![feature(generators, generator_trait)]
+#![cfg_attr(nll, feature(nll))]
+use std::ops::{Generator, GeneratorState};
+
+fn dangle(x: &mut i32) -> &'static mut i32 {
+ let mut g = || {
+ yield;
+ x
+ };
+ loop {
+ match unsafe { g.resume() } {
+ GeneratorState::Complete(c) => return c,
+ GeneratorState::Yielded(_) => (),
+ }
+ }
+}
+
+fn main() {}