Skip to content

Commit 0724efd

Browse files
committed
Rollup merge of rust-lang#55013 - matthewjasper:propagate-generator-bounds, r=nikomatsakis
[NLL] Propagate bounds from generators This used to only be done for closures.
2 parents 4763c22 + ef1a40d commit 0724efd

File tree

6 files changed

+57
-19
lines changed

6 files changed

+57
-19
lines changed

Diff for: src/librustc_mir/borrow_check/nll/region_infer/mod.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ pub trait ClosureRegionRequirementsExt<'gcx, 'tcx> {
12681268
tcx: TyCtxt<'_, 'gcx, 'tcx>,
12691269
location: Location,
12701270
closure_def_id: DefId,
1271-
closure_substs: ty::ClosureSubsts<'tcx>,
1271+
closure_substs: &'tcx ty::subst::Substs<'tcx>,
12721272
) -> Vec<QueryRegionConstraint<'tcx>>;
12731273

12741274
fn subst_closure_mapping<T>(
@@ -1299,23 +1299,19 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
12991299
tcx: TyCtxt<'_, 'gcx, 'tcx>,
13001300
location: Location,
13011301
closure_def_id: DefId,
1302-
closure_substs: ty::ClosureSubsts<'tcx>,
1302+
closure_substs: &'tcx ty::subst::Substs<'tcx>,
13031303
) -> Vec<QueryRegionConstraint<'tcx>> {
13041304
debug!(
13051305
"apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})",
13061306
location, closure_def_id, closure_substs
13071307
);
13081308

1309-
// Get Tu.
1310-
let user_closure_ty = tcx.mk_closure(closure_def_id, closure_substs);
1311-
debug!("apply_requirements: user_closure_ty={:?}", user_closure_ty);
1312-
1313-
// Extract the values of the free regions in `user_closure_ty`
1309+
// Extract the values of the free regions in `closure_substs`
13141310
// into a vector. These are the regions that we will be
13151311
// relating to one another.
13161312
let closure_mapping = &UniversalRegions::closure_mapping(
13171313
tcx,
1318-
user_closure_ty,
1314+
closure_substs,
13191315
self.num_external_vids,
13201316
tcx.closure_base_def_id(closure_def_id),
13211317
);

Diff for: src/librustc_mir/borrow_check/nll/type_check/mod.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp;
4242
use rustc::traits::query::{Fallible, NoSolution};
4343
use rustc::traits::{ObligationCause, PredicateObligations};
4444
use rustc::ty::fold::TypeFoldable;
45-
use rustc::ty::subst::{Subst, UnpackedKind};
45+
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
4646
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
4747
use std::rc::Rc;
4848
use std::{fmt, iter};
@@ -2075,12 +2075,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
20752075
// desugaring. A closure gets desugared to a struct, and
20762076
// these extra requirements are basically like where
20772077
// clauses on the struct.
2078-
AggregateKind::Closure(def_id, substs) => {
2079-
self.prove_closure_bounds(tcx, *def_id, *substs, location)
2080-
}
2081-
2082-
AggregateKind::Generator(def_id, substs, _) => {
2083-
tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)
2078+
AggregateKind::Closure(def_id, ty::ClosureSubsts { substs })
2079+
| AggregateKind::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
2080+
self.prove_closure_bounds(tcx, *def_id, substs, location)
20842081
}
20852082

20862083
AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
@@ -2096,7 +2093,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
20962093
&mut self,
20972094
tcx: TyCtxt<'a, 'gcx, 'tcx>,
20982095
def_id: DefId,
2099-
substs: ty::ClosureSubsts<'tcx>,
2096+
substs: &'tcx Substs<'tcx>,
21002097
location: Location,
21012098
) -> ty::InstantiatedPredicates<'tcx> {
21022099
if let Some(closure_region_requirements) =
@@ -2155,7 +2152,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
21552152
);
21562153
}
21572154

2158-
tcx.predicates_of(def_id).instantiate(tcx, substs.substs)
2155+
tcx.predicates_of(def_id).instantiate(tcx, substs)
21592156
}
21602157

21612158
fn prove_trait_ref(

Diff for: src/librustc_mir/borrow_check/nll/universal_regions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,13 @@ impl<'tcx> UniversalRegions<'tcx> {
232232
/// `V[1]: V[2]`.
233233
pub fn closure_mapping(
234234
tcx: TyCtxt<'_, '_, 'tcx>,
235-
closure_ty: Ty<'tcx>,
235+
closure_substs: &'tcx Substs<'tcx>,
236236
expected_num_vars: usize,
237237
closure_base_def_id: DefId,
238238
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
239239
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
240240
region_mapping.push(tcx.types.re_static);
241-
tcx.for_each_free_region(&closure_ty, |fr| {
241+
tcx.for_each_free_region(&closure_substs, |fr| {
242242
region_mapping.push(fr);
243243
});
244244

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0621]: explicit lifetime required in the type of `x`
2+
--> $DIR/generator-region-requirements.rs:15:51
3+
|
4+
LL | fn dangle(x: &mut i32) -> &'static mut i32 {
5+
| -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
6+
...
7+
LL | GeneratorState::Complete(c) => return c,
8+
| ^ lifetime `'static` required
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0621`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0621]: explicit lifetime required in the type of `x`
2+
--> $DIR/generator-region-requirements.rs:11:9
3+
|
4+
LL | fn dangle(x: &mut i32) -> &'static mut i32 {
5+
| -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
6+
...
7+
LL | x
8+
| ^ lifetime `'static` required
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0621`.
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// revisions: ast nll
2+
// ignore-compare-mode-nll
3+
4+
#![feature(generators, generator_trait)]
5+
#![cfg_attr(nll, feature(nll))]
6+
use std::ops::{Generator, GeneratorState};
7+
8+
fn dangle(x: &mut i32) -> &'static mut i32 {
9+
let mut g = || {
10+
yield;
11+
x
12+
};
13+
loop {
14+
match unsafe { g.resume() } {
15+
GeneratorState::Complete(c) => return c,
16+
GeneratorState::Yielded(_) => (),
17+
}
18+
}
19+
}
20+
21+
fn main() {}

0 commit comments

Comments
 (0)