Skip to content

Commit b97eb23

Browse files
committed
Box generator-related Body fields
1 parent 3b150b7 commit b97eb23

File tree

14 files changed

+89
-54
lines changed

14 files changed

+89
-54
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ fn generator_layout_and_saved_local_names(
14171417
def_id: DefId,
14181418
) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) {
14191419
let body = tcx.optimized_mir(def_id);
1420-
let generator_layout = body.generator_layout.as_ref().unwrap();
1420+
let generator_layout = body.generator_layout().unwrap();
14211421
let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys);
14221422

14231423
let state_arg = mir::Local::new(1);

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,22 @@ impl<'tcx> MirSource<'tcx> {
146146
}
147147
}
148148

149+
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
150+
pub struct GeneratorInfo<'tcx> {
151+
/// The yield type of the function, if it is a generator.
152+
pub yield_ty: Option<Ty<'tcx>>,
153+
154+
/// Generator drop glue.
155+
pub generator_drop: Option<Body<'tcx>>,
156+
157+
/// The layout of a generator. Produced by the state transformation.
158+
pub generator_layout: Option<GeneratorLayout<'tcx>>,
159+
160+
/// If this is a generator then record the type of source expression that caused this generator
161+
/// to be created.
162+
pub generator_kind: GeneratorKind,
163+
}
164+
149165
/// The lowered representation of a single function.
150166
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
151167
pub struct Body<'tcx> {
@@ -166,18 +182,7 @@ pub struct Body<'tcx> {
166182
/// and used for debuginfo. Indexed by a `SourceScope`.
167183
pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
168184

169-
/// The yield type of the function, if it is a generator.
170-
pub yield_ty: Option<Ty<'tcx>>,
171-
172-
/// Generator drop glue.
173-
pub generator_drop: Option<Box<Body<'tcx>>>,
174-
175-
/// The layout of a generator. Produced by the state transformation.
176-
pub generator_layout: Option<GeneratorLayout<'tcx>>,
177-
178-
/// If this is a generator then record the type of source expression that caused this generator
179-
/// to be created.
180-
pub generator_kind: Option<GeneratorKind>,
185+
pub generator: Option<Box<GeneratorInfo<'tcx>>>,
181186

182187
/// Declarations of locals.
183188
///
@@ -259,10 +264,14 @@ impl<'tcx> Body<'tcx> {
259264
source,
260265
basic_blocks,
261266
source_scopes,
262-
yield_ty: None,
263-
generator_drop: None,
264-
generator_layout: None,
265-
generator_kind,
267+
generator: generator_kind.map(|generator_kind| {
268+
Box::new(GeneratorInfo {
269+
yield_ty: None,
270+
generator_drop: None,
271+
generator_layout: None,
272+
generator_kind,
273+
})
274+
}),
266275
local_decls,
267276
user_type_annotations,
268277
arg_count,
@@ -289,16 +298,13 @@ impl<'tcx> Body<'tcx> {
289298
source: MirSource::item(DefId::local(CRATE_DEF_INDEX)),
290299
basic_blocks,
291300
source_scopes: IndexVec::new(),
292-
yield_ty: None,
293-
generator_drop: None,
294-
generator_layout: None,
301+
generator: None,
295302
local_decls: IndexVec::new(),
296303
user_type_annotations: IndexVec::new(),
297304
arg_count: 0,
298305
spread_arg: None,
299306
span: DUMMY_SP,
300307
required_consts: Vec::new(),
301-
generator_kind: None,
302308
var_debug_info: Vec::new(),
303309
is_polymorphic: false,
304310
predecessor_cache: PredecessorCache::new(),
@@ -480,6 +486,26 @@ impl<'tcx> Body<'tcx> {
480486
pub fn dominators(&self) -> Dominators<BasicBlock> {
481487
dominators(self)
482488
}
489+
490+
#[inline]
491+
pub fn yield_ty(&self) -> Option<Ty<'tcx>> {
492+
self.generator.as_ref().and_then(|generator| generator.yield_ty)
493+
}
494+
495+
#[inline]
496+
pub fn generator_layout(&self) -> Option<&GeneratorLayout<'tcx>> {
497+
self.generator.as_ref().and_then(|generator| generator.generator_layout.as_ref())
498+
}
499+
500+
#[inline]
501+
pub fn generator_drop(&self) -> Option<&Body<'tcx>> {
502+
self.generator.as_ref().and_then(|generator| generator.generator_drop.as_ref())
503+
}
504+
505+
#[inline]
506+
pub fn generator_kind(&self) -> Option<GeneratorKind> {
507+
self.generator.as_ref().map(|generator| generator.generator_kind)
508+
}
483509
}
484510

485511
#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,13 @@ macro_rules! make_mir_visitor {
241241
body: &$($mutability)? Body<'tcx>,
242242
) {
243243
let span = body.span;
244-
if let Some(yield_ty) = &$($mutability)? body.yield_ty {
245-
self.visit_ty(
246-
yield_ty,
247-
TyContext::YieldTy(SourceInfo::outermost(span))
248-
);
244+
if let Some(gen) = &$($mutability)? body.generator {
245+
if let Some(yield_ty) = &$($mutability)? gen.yield_ty {
246+
self.visit_ty(
247+
yield_ty,
248+
TyContext::YieldTy(SourceInfo::outermost(span))
249+
);
250+
}
249251
}
250252

251253
// for best performance, we want to use an iterator rather

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2998,7 +2998,7 @@ impl<'tcx> TyCtxt<'tcx> {
29982998
/// Returns layout of a generator. Layout might be unavailable if the
29992999
/// generator is tainted by errors.
30003000
pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> {
3001-
self.optimized_mir(def_id).generator_layout.as_ref()
3001+
self.optimized_mir(def_id).generator_layout()
30023002
}
30033003

30043004
/// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.

compiler/rustc_mir/src/borrow_check/type_check/input_output.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
103103
}
104104
}
105105

106-
assert!(
107-
body.yield_ty.is_some() && universal_regions.yield_ty.is_some()
108-
|| body.yield_ty.is_none() && universal_regions.yield_ty.is_none()
109-
);
110-
if let Some(mir_yield_ty) = body.yield_ty {
106+
assert!(body.yield_ty().is_some() == universal_regions.yield_ty.is_some());
107+
if let Some(mir_yield_ty) = body.yield_ty() {
111108
let ur_yield_ty = universal_regions.yield_ty.unwrap();
112109
let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
113110
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1651,7 +1651,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16511651
}
16521652
TerminatorKind::Yield { ref value, .. } => {
16531653
let value_ty = value.ty(body, tcx);
1654-
match body.yield_ty {
1654+
match body.yield_ty() {
16551655
None => span_mirbug!(self, term, "yield in non-generator"),
16561656
Some(ty) => {
16571657
if let Err(terr) = self.sub_types(

compiler/rustc_mir/src/shim.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
134134

135135
// Check if this is a generator, if so, return the drop glue for it
136136
if let Some(&ty::Generator(gen_def_id, substs, _)) = ty.map(|ty| ty.kind()) {
137-
let body = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
137+
let body = tcx.optimized_mir(gen_def_id).generator_drop().unwrap();
138138
return body.clone().subst(tcx, substs);
139139
}
140140

compiler/rustc_mir/src/transform/check_consts/validation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl Validator<'mir, 'tcx> {
222222

223223
// `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
224224
// no need to emit duplicate errors here.
225-
if is_async_fn(self.ccx) || body.generator_kind.is_some() {
225+
if is_async_fn(self.ccx) || body.generator.is_some() {
226226
tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`");
227227
return;
228228
}

compiler/rustc_mir/src/transform/const_prop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
140140
body.arg_count,
141141
Default::default(),
142142
body.span,
143-
body.generator_kind,
143+
body.generator_kind(),
144144
);
145145

146146
// FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold

compiler/rustc_mir/src/transform/generator.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,7 @@ fn create_generator_resume_function<'tcx>(
11111111
cases.insert(0, (UNRESUMED, BasicBlock::new(0)));
11121112

11131113
// Panic when resumed on the returned or poisoned state
1114-
let generator_kind = body.generator_kind.unwrap();
1114+
let generator_kind = body.generator_kind().unwrap();
11151115

11161116
if can_unwind {
11171117
cases.insert(
@@ -1236,14 +1236,14 @@ fn create_cases<'tcx>(
12361236

12371237
impl<'tcx> MirPass<'tcx> for StateTransform {
12381238
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
1239-
let yield_ty = if let Some(yield_ty) = body.yield_ty {
1239+
let yield_ty = if let Some(yield_ty) = body.yield_ty() {
12401240
yield_ty
12411241
} else {
12421242
// This only applies to generators
12431243
return;
12441244
};
12451245

1246-
assert!(body.generator_drop.is_none());
1246+
assert!(body.generator_drop().is_none());
12471247

12481248
// The first argument is the generator type passed by value
12491249
let gen_ty = body.local_decls.raw[1].ty;
@@ -1340,10 +1340,11 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
13401340
transform.visit_body(body);
13411341

13421342
// Update our MIR struct to reflect the changes we've made
1343-
body.yield_ty = None;
13441343
body.arg_count = 2; // self, resume arg
13451344
body.spread_arg = None;
1346-
body.generator_layout = Some(layout);
1345+
1346+
body.generator.as_mut().unwrap().yield_ty = None;
1347+
body.generator.as_mut().unwrap().generator_layout = Some(layout);
13471348

13481349
// Insert `drop(generator_struct)` which is used to drop upvars for generators in
13491350
// the unresumed state.
@@ -1362,7 +1363,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
13621363
// Create a copy of our MIR and use it to create the drop shim for the generator
13631364
let drop_shim = create_generator_drop_shim(tcx, &transform, gen_ty, body, drop_clean);
13641365

1365-
body.generator_drop = Some(box drop_shim);
1366+
body.generator.as_mut().unwrap().generator_drop = Some(drop_shim);
13661367

13671368
// Create the Generator::resume function
13681369
create_generator_resume_function(tcx, transform, body, can_return);

0 commit comments

Comments
 (0)