Skip to content

Commit 4325c63

Browse files
committed
Allow access of the state field before the generator transform. Fixes #47482, #46476
1 parent 77bc26f commit 4325c63

File tree

4 files changed

+38
-26
lines changed

4 files changed

+38
-26
lines changed

src/librustc/ty/sty.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,14 +390,21 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> {
390390
state.map(move |d| d.ty.subst(tcx, self.substs))
391391
}
392392

393+
/// This is the types of the fields of a generate which
394+
/// is available before the generator transformation.
395+
/// It includes the upvars and the state discriminant which is u32.
396+
pub fn pre_transforms_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
397+
impl Iterator<Item=Ty<'tcx>> + 'a
398+
{
399+
self.upvar_tys(def_id, tcx).chain(iter::once(tcx.types.u32))
400+
}
401+
393402
/// This is the types of all the fields stored in a generator.
394403
/// It includes the upvars, state types and the state discriminant which is u32.
395404
pub fn field_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
396405
impl Iterator<Item=Ty<'tcx>> + 'a
397406
{
398-
let upvars = self.upvar_tys(def_id, tcx);
399-
let state = self.state_tys(def_id, tcx);
400-
upvars.chain(iter::once(tcx.types.u32)).chain(state)
407+
self.pre_transforms_tys(def_id, tcx).chain(self.state_tys(def_id, tcx))
401408
}
402409
}
403410

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,15 +533,17 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
533533
}
534534
}
535535
ty::TyGenerator(def_id, substs, _) => {
536-
// Try upvars first. `field_tys` requires final optimized MIR.
537-
if let Some(ty) = substs.upvar_tys(def_id, tcx).nth(field.index()) {
536+
// Try pre-transform fields first (upvars and current state)
537+
if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field.index()) {
538538
return Ok(ty);
539539
}
540540

541+
// Then try `field_tys` which contains all the fields, but it
542+
// requires the final optimized MIR.
541543
return match substs.field_tys(def_id, tcx).nth(field.index()) {
542544
Some(ty) => Ok(ty),
543545
None => Err(FieldAccessError::OutOfRange {
544-
field_count: substs.field_tys(def_id, tcx).count() + 1,
546+
field_count: substs.field_tys(def_id, tcx).count(),
545547
}),
546548
};
547549
}
@@ -1233,13 +1235,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
12331235
}
12341236
}
12351237
AggregateKind::Generator(def_id, substs, _) => {
1236-
if let Some(ty) = substs.upvar_tys(def_id, tcx).nth(field_index) {
1238+
// Try pre-transform fields first (upvars and current state)
1239+
if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field_index) {
12371240
Ok(ty)
12381241
} else {
1242+
// Then try `field_tys` which contains all the fields, but it
1243+
// requires the final optimized MIR.
12391244
match substs.field_tys(def_id, tcx).nth(field_index) {
12401245
Some(ty) => Ok(ty),
12411246
None => Err(FieldAccessError::OutOfRange {
1242-
field_count: substs.field_tys(def_id, tcx).count() + 1,
1247+
field_count: substs.field_tys(def_id, tcx).count(),
12431248
}),
12441249
}
12451250
}

src/test/ui/generator/generator-with-nll.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
error[E0626]: borrow may still be in use when generator yields (Mir)
2-
--> $DIR/generator-with-nll.rs:20:17
3-
|
4-
20 | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
5-
| ^^^^^^^^^
6-
21 | //~^ borrow may still be in use when generator yields (Mir)
7-
22 | yield ();
8-
| -------- possible yield occurs here
9-
101
error[E0626]: borrow may still be in use when generator yields (Ast)
112
--> $DIR/generator-with-nll.rs:19:23
123
|
@@ -25,5 +16,14 @@ error[E0626]: borrow may still be in use when generator yields (Ast)
2516
22 | yield ();
2617
| -------- possible yield occurs here
2718

19+
error[E0626]: borrow may still be in use when generator yields (Mir)
20+
--> $DIR/generator-with-nll.rs:20:17
21+
|
22+
20 | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
23+
| ^^^^^^^^^
24+
21 | //~^ borrow may still be in use when generator yields (Mir)
25+
22 | yield ();
26+
| -------- possible yield occurs here
27+
2828
error: aborting due to 3 previous errors
2929

src/test/ui/generator/yield-while-local-borrowed.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
error[E0626]: borrow may still be in use when generator yields (Mir)
2-
--> $DIR/yield-while-local-borrowed.rs:24:17
3-
|
4-
24 | let a = &mut 3;
5-
| ^^^^^^
6-
...
7-
27 | yield();
8-
| ------- possible yield occurs here
9-
101
error[E0626]: borrow may still be in use when generator yields (Ast)
112
--> $DIR/yield-while-local-borrowed.rs:24:22
123
|
@@ -25,6 +16,15 @@ error[E0626]: borrow may still be in use when generator yields (Ast)
2516
55 | yield();
2617
| ------- possible yield occurs here
2718

19+
error[E0626]: borrow may still be in use when generator yields (Mir)
20+
--> $DIR/yield-while-local-borrowed.rs:24:17
21+
|
22+
24 | let a = &mut 3;
23+
| ^^^^^^
24+
...
25+
27 | yield();
26+
| ------- possible yield occurs here
27+
2828
error[E0626]: borrow may still be in use when generator yields (Mir)
2929
--> $DIR/yield-while-local-borrowed.rs:52:21
3030
|

0 commit comments

Comments
 (0)