Skip to content

Commit b40b710

Browse files
Cap closure kind, get rid of by_mut_body
1 parent 4a2fe44 commit b40b710

File tree

20 files changed

+62
-190
lines changed

20 files changed

+62
-190
lines changed

compiler/rustc_borrowck/src/type_check/input_output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
8888
self.tcx(),
8989
ty::CoroutineArgsParts {
9090
parent_args: args.parent_args(),
91-
kind_ty: Ty::from_closure_kind(self.tcx(), args.kind()),
91+
kind_ty: Ty::from_closure_kind(self.tcx(), args.kind().cap_for_coroutine()),
9292
return_ty: user_provided_sig.output(),
9393
tupled_upvars_ty,
9494
// For async closures, none of these can be annotated, so just fill

compiler/rustc_borrowck/src/universal_regions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
755755
tcx,
756756
args.as_coroutine_closure().parent_args(),
757757
tcx.coroutine_for_closure(def_id),
758-
closure_kind,
758+
closure_kind.cap_for_coroutine(),
759759
env_region,
760760
args.as_coroutine_closure().tupled_upvars_ty(),
761761
args.as_coroutine_closure().coroutine_captures_by_ref_ty(),

compiler/rustc_hir_typeck/src/callee.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
183183
kind: TypeVariableOriginKind::TypeInference,
184184
span: callee_expr.span,
185185
});
186+
// We may actually receive a coroutine back whose kind is different
187+
// from the closure that this dispatched from. This is because when
188+
// we have no captures, we automatically implement `FnOnce`. This
189+
// impl forces the closure kind to `FnOnce` i.e. `u8`.
190+
let kind_ty = self.next_ty_var(TypeVariableOrigin {
191+
kind: TypeVariableOriginKind::TypeInference,
192+
span: callee_expr.span,
193+
});
186194
let call_sig = self.tcx.mk_fn_sig(
187195
[coroutine_closure_sig.tupled_inputs_ty],
188196
coroutine_closure_sig.to_coroutine(
189197
self.tcx,
190198
closure_args.parent_args(),
191-
// Inherit the kind ty of the closure, since we're calling this
192-
// coroutine with the most relaxed `AsyncFn*` trait that we can.
193-
// We don't necessarily need to do this here, but it saves us
194-
// computing one more infer var that will get constrained later.
195-
closure_args.kind_ty(),
199+
kind_ty,
196200
self.tcx.coroutine_for_closure(def_id),
197201
tupled_upvars_ty,
198202
),

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
261261
},
262262
);
263263

264+
let coroutine_kind_ty = self.next_ty_var(TypeVariableOrigin {
265+
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
266+
kind: TypeVariableOriginKind::ClosureSynthetic,
267+
span: expr_span,
268+
});
264269
let coroutine_upvars_ty = self.next_ty_var(TypeVariableOrigin {
265270
kind: TypeVariableOriginKind::ClosureSynthetic,
266271
span: expr_span,
@@ -278,7 +283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
278283
sig.to_coroutine(
279284
tcx,
280285
parent_args,
281-
closure_kind_ty,
286+
coroutine_kind_ty,
282287
tcx.coroutine_for_closure(expr_def_id),
283288
coroutine_upvars_ty,
284289
)

compiler/rustc_hir_typeck/src/upvar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
410410
self.demand_eqtype(
411411
span,
412412
coroutine_args.as_coroutine().kind_ty(),
413-
Ty::from_closure_kind(self.tcx, closure_kind),
413+
Ty::from_closure_kind(self.tcx, closure_kind.cap_for_coroutine()),
414414
);
415415
}
416416

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,6 @@ pub struct CoroutineInfo<'tcx> {
274274
/// using `run_passes`.
275275
pub by_move_body: Option<Body<'tcx>>,
276276

277-
/// The body of the coroutine, modified to take its upvars by mutable ref rather than by
278-
/// immutable ref.
279-
///
280-
/// FIXME(async_closures): This is literally the same body as the parent body. Find a better
281-
/// way to represent the by-mut signature (or cap the closure-kind of the coroutine).
282-
pub by_mut_body: Option<Body<'tcx>>,
283-
284277
/// The layout of a coroutine. This field is populated after the state transform pass.
285278
pub coroutine_layout: Option<CoroutineLayout<'tcx>>,
286279

@@ -301,7 +294,6 @@ impl<'tcx> CoroutineInfo<'tcx> {
301294
yield_ty: Some(yield_ty),
302295
resume_ty: Some(resume_ty),
303296
by_move_body: None,
304-
by_mut_body: None,
305297
coroutine_drop: None,
306298
coroutine_layout: None,
307299
}
@@ -616,10 +608,6 @@ impl<'tcx> Body<'tcx> {
616608
self.coroutine.as_ref()?.by_move_body.as_ref()
617609
}
618610

619-
pub fn coroutine_by_mut_body(&self) -> Option<&Body<'tcx>> {
620-
self.coroutine.as_ref()?.by_mut_body.as_ref()
621-
}
622-
623611
#[inline]
624612
pub fn coroutine_kind(&self) -> Option<CoroutineKind> {
625613
self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind)

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,8 @@ macro_rules! make_mir_visitor {
345345
ty::InstanceDef::Virtual(_def_id, _) |
346346
ty::InstanceDef::ThreadLocalShim(_def_id) |
347347
ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
348-
ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, target_kind: _ } |
349-
ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id, target_kind: _ } |
348+
ty::InstanceDef::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id } |
349+
ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id } |
350350
ty::InstanceDef::DropGlue(_def_id, None) => {}
351351

352352
ty::InstanceDef::FnPtrShim(_def_id, ty) |

compiler/rustc_middle/src/ty/instance.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,24 +90,20 @@ pub enum InstanceDef<'tcx> {
9090
/// and dispatch to the `FnMut::call_mut` instance for the closure.
9191
ClosureOnceShim { call_once: DefId, track_caller: bool },
9292

93-
/// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once` or
94-
/// `<[Fn coroutine-closure] as FnMut>::call_mut`.
93+
/// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once`
9594
///
9695
/// The body generated here differs significantly from the `ClosureOnceShim`,
9796
/// since we need to generate a distinct coroutine type that will move the
9897
/// closure's upvars *out* of the closure.
99-
ConstructCoroutineInClosureShim {
100-
coroutine_closure_def_id: DefId,
101-
target_kind: ty::ClosureKind,
102-
},
98+
ConstructCoroutineInClosureShim { coroutine_closure_def_id: DefId },
10399

104100
/// `<[coroutine] as Future>::poll`, but for coroutines produced when `AsyncFnOnce`
105101
/// is called on a coroutine-closure whose closure kind greater than `FnOnce`, or
106102
/// similarly for `AsyncFnMut`.
107103
///
108104
/// This will select the body that is produced by the `ByMoveBody` transform, and thus
109105
/// take and use all of its upvars by-move rather than by-ref.
110-
CoroutineKindShim { coroutine_def_id: DefId, target_kind: ty::ClosureKind },
106+
CoroutineKindShim { coroutine_def_id: DefId },
111107

112108
/// Compiler-generated accessor for thread locals which returns a reference to the thread local
113109
/// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking
@@ -192,9 +188,8 @@ impl<'tcx> InstanceDef<'tcx> {
192188
| InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
193189
| ty::InstanceDef::ConstructCoroutineInClosureShim {
194190
coroutine_closure_def_id: def_id,
195-
target_kind: _,
196191
}
197-
| ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id, target_kind: _ }
192+
| ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id }
198193
| InstanceDef::DropGlue(def_id, _)
199194
| InstanceDef::CloneShim(def_id, _)
200195
| InstanceDef::FnPtrAddrShim(def_id, _) => def_id,
@@ -654,10 +649,7 @@ impl<'tcx> Instance<'tcx> {
654649
Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
655650
} else {
656651
Some(Instance {
657-
def: ty::InstanceDef::CoroutineKindShim {
658-
coroutine_def_id,
659-
target_kind: args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(),
660-
},
652+
def: ty::InstanceDef::CoroutineKindShim { coroutine_def_id },
661653
args,
662654
})
663655
}

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ impl<'tcx> CoroutineClosureSignature<'tcx> {
485485
self.to_coroutine(
486486
tcx,
487487
parent_args,
488-
Ty::from_closure_kind(tcx, goal_kind),
488+
Ty::from_closure_kind(tcx, goal_kind.cap_for_coroutine()),
489489
coroutine_def_id,
490490
tupled_upvars_ty,
491491
)

compiler/rustc_mir_transform/src/coroutine/by_move_body.rs

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -64,45 +64,10 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
6464
by_move_body.source = mir::MirSource {
6565
instance: InstanceDef::CoroutineKindShim {
6666
coroutine_def_id: coroutine_def_id.to_def_id(),
67-
target_kind: ty::ClosureKind::FnOnce,
6867
},
6968
promoted: None,
7069
};
7170
body.coroutine.as_mut().unwrap().by_move_body = Some(by_move_body);
72-
73-
// If this is coming from an `AsyncFn` coroutine-closure, we must also create a by-mut body.
74-
// This is actually just a copy of the by-ref body, but with a different self type.
75-
// FIXME(async_closures): We could probably unify this with the by-ref body somehow.
76-
if coroutine_kind == ty::ClosureKind::Fn {
77-
let by_mut_coroutine_ty = Ty::new_coroutine(
78-
tcx,
79-
coroutine_def_id.to_def_id(),
80-
ty::CoroutineArgs::new(
81-
tcx,
82-
ty::CoroutineArgsParts {
83-
parent_args: args.as_coroutine().parent_args(),
84-
kind_ty: Ty::from_closure_kind(tcx, ty::ClosureKind::FnMut),
85-
resume_ty: args.as_coroutine().resume_ty(),
86-
yield_ty: args.as_coroutine().yield_ty(),
87-
return_ty: args.as_coroutine().return_ty(),
88-
witness: args.as_coroutine().witness(),
89-
tupled_upvars_ty: args.as_coroutine().tupled_upvars_ty(),
90-
},
91-
)
92-
.args,
93-
);
94-
let mut by_mut_body = body.clone();
95-
by_mut_body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty = by_mut_coroutine_ty;
96-
dump_mir(tcx, false, "coroutine_by_mut", &0, &by_mut_body, |_, _| Ok(()));
97-
by_mut_body.source = mir::MirSource {
98-
instance: InstanceDef::CoroutineKindShim {
99-
coroutine_def_id: coroutine_def_id.to_def_id(),
100-
target_kind: ty::ClosureKind::FnMut,
101-
},
102-
promoted: None,
103-
};
104-
body.coroutine.as_mut().unwrap().by_mut_body = Some(by_mut_body);
105-
}
10671
}
10772
}
10873

0 commit comments

Comments
 (0)