Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fa1b622

Browse files
committedNov 1, 2022
Separate generator info from MIR body.
1 parent 024207a commit fa1b622

File tree

27 files changed

+264
-257
lines changed

27 files changed

+264
-257
lines changed
 

‎compiler/rustc_borrowck/src/type_check/input_output.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -110,28 +110,26 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
110110
}
111111
}
112112

113+
let body_yield_ty = body.yield_ty(self.tcx());
113114
debug!(
114115
"equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}",
115-
body.yield_ty(),
116-
universal_regions.yield_ty
116+
body_yield_ty, universal_regions.yield_ty
117117
);
118118

119119
// We will not have a universal_regions.yield_ty if we yield (by accident)
120120
// outside of a generator and return an `impl Trait`, so emit a delay_span_bug
121121
// because we don't want to panic in an assert here if we've already got errors.
122-
if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() {
122+
if body_yield_ty.is_some() != universal_regions.yield_ty.is_some() {
123123
self.tcx().sess.delay_span_bug(
124124
body.span,
125125
&format!(
126126
"Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})",
127-
body.yield_ty(),
128-
universal_regions.yield_ty,
127+
body_yield_ty, universal_regions.yield_ty,
129128
),
130129
);
131130
}
132131

133-
if let (Some(mir_yield_ty), Some(ur_yield_ty)) =
134-
(body.yield_ty(), universal_regions.yield_ty)
132+
if let (Some(mir_yield_ty), Some(ur_yield_ty)) = (body_yield_ty, universal_regions.yield_ty)
135133
{
136134
let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
137135
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);

‎compiler/rustc_borrowck/src/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1507,7 +1507,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15071507
self.check_operand(value, term_location);
15081508

15091509
let value_ty = value.ty(body, tcx);
1510-
match body.yield_ty() {
1510+
match body.yield_ty(tcx) {
15111511
None => span_mirbug!(self, term, "yield in non-generator"),
15121512
Some(ty) => {
15131513
if let Err(terr) = self.sub_types(

‎compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1235,8 +1235,8 @@ fn generator_layout_and_saved_local_names<'tcx>(
12351235
tcx: TyCtxt<'tcx>,
12361236
def_id: DefId,
12371237
) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) {
1238+
let generator_layout = &tcx.mir_generator_info(def_id).generator_layout;
12381239
let body = tcx.optimized_mir(def_id);
1239-
let generator_layout = body.generator_layout().unwrap();
12401240
let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys);
12411241

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

‎compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
225225

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

‎compiler/rustc_const_eval/src/transform/promote_consts.rs

-1
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,6 @@ pub fn promote_candidates<'tcx>(
964964
0,
965965
vec![],
966966
body.span,
967-
body.generator_kind(),
968967
body.tainted_by_errors,
969968
);
970969
promoted.phase = MirPhase::Analysis(AnalysisPhase::Initial);

‎compiler/rustc_const_eval/src/transform/validate.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
6565
storage_liveness,
6666
place_cache: Vec::new(),
6767
value_cache: Vec::new(),
68+
is_generator: tcx.generator_kind(def_id).is_some(),
6869
}
6970
.visit_body(body);
7071
}
@@ -118,6 +119,7 @@ struct TypeChecker<'a, 'tcx> {
118119
storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive>,
119120
place_cache: Vec<PlaceRef<'tcx>>,
120121
value_cache: Vec<u128>,
122+
is_generator: bool,
121123
}
122124

123125
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@@ -323,16 +325,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
323325
}
324326
&ty::Generator(def_id, substs, _) => {
325327
let f_ty = if let Some(var) = parent_ty.variant_index {
326-
let gen_body = if def_id == self.body.source.def_id() {
327-
self.body
328-
} else {
329-
self.tcx.optimized_mir(def_id)
330-
};
331-
332-
let Some(layout) = gen_body.generator_layout() else {
333-
self.fail(location, format!("No generator layout for {:?}", parent_ty));
334-
return;
335-
};
328+
let generator_info = self.tcx.mir_generator_info(def_id);
329+
let layout = &generator_info.generator_layout;
336330

337331
let Some(&local) = layout.variant_fields[var].get(f) else {
338332
fail_out_of_bounds(self, location);
@@ -861,7 +855,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
861855
}
862856
}
863857
TerminatorKind::Yield { resume, drop, .. } => {
864-
if self.body.generator.is_none() {
858+
if !self.is_generator {
865859
self.fail(location, "`Yield` cannot appear outside generator bodies");
866860
}
867861
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
@@ -903,7 +897,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
903897
}
904898
}
905899
TerminatorKind::GeneratorDrop => {
906-
if self.body.generator.is_none() {
900+
if !self.is_generator {
907901
self.fail(location, "`GeneratorDrop` cannot appear outside generator bodies");
908902
}
909903
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {

‎compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ provide! { tcx, def_id, other, cdata,
202202
thir_abstract_const => { table }
203203
optimized_mir => { table }
204204
mir_for_ctfe => { table }
205+
mir_generator_info => { table }
205206
promoted_mir => { table }
206207
def_span => { table }
207208
def_ident_span => { table }

‎compiler/rustc_metadata/src/rmeta/encoder.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1426,6 +1426,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14261426
debug!("EntryBuilder::encode_mir({:?})", def_id);
14271427
if encode_opt {
14281428
record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
1429+
1430+
if let DefKind::Generator = self.tcx.def_kind(def_id) {
1431+
record!(self.tables.mir_generator_info[def_id.to_def_id()] <- tcx.mir_generator_info(def_id));
1432+
}
14291433
}
14301434
if encode_const {
14311435
record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id));

‎compiler/rustc_metadata/src/rmeta/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ define_tables! {
363363
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
364364
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
365365
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
366+
mir_generator_info: Table<DefIndex, LazyValue<mir::GeneratorInfo<'static>>>,
366367
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
367368
// FIXME(compiler-errors): Why isn't this a LazyArray?
368369
thir_abstract_const: Table<DefIndex, LazyValue<&'static [ty::abstract_const::Node<'static>]>>,

‎compiler/rustc_middle/src/arena.rs

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ macro_rules! arena_types {
1313
[] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<'tcx>>,
1414
[] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
1515
[decode] mir: rustc_middle::mir::Body<'tcx>,
16+
[decode] generator_info: rustc_middle::mir::GeneratorInfo<'tcx>,
17+
[] mir_generator_lowered: (
18+
rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
19+
Option<rustc_middle::mir::GeneratorInfo<'tcx>>,
20+
),
1621
[] steal_promoted:
1722
rustc_data_structures::steal::Steal<
1823
rustc_index::vec::IndexVec<

‎compiler/rustc_middle/src/mir/mod.rs

+11-39
Original file line numberDiff line numberDiff line change
@@ -203,18 +203,11 @@ impl<'tcx> MirSource<'tcx> {
203203

204204
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)]
205205
pub struct GeneratorInfo<'tcx> {
206-
/// The yield type of the function, if it is a generator.
207-
pub yield_ty: Option<Ty<'tcx>>,
208-
209206
/// Generator drop glue.
210-
pub generator_drop: Option<Body<'tcx>>,
207+
pub generator_drop: Body<'tcx>,
211208

212209
/// The layout of a generator. Produced by the state transformation.
213-
pub generator_layout: Option<GeneratorLayout<'tcx>>,
214-
215-
/// If this is a generator then record the type of source expression that caused this generator
216-
/// to be created.
217-
pub generator_kind: GeneratorKind,
210+
pub generator_layout: GeneratorLayout<'tcx>,
218211
}
219212

220213
/// The lowered representation of a single function.
@@ -240,8 +233,6 @@ pub struct Body<'tcx> {
240233
/// and used for debuginfo. Indexed by a `SourceScope`.
241234
pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
242235

243-
pub generator: Option<Box<GeneratorInfo<'tcx>>>,
244-
245236
/// Declarations of locals.
246237
///
247238
/// The first local is the return value pointer, followed by `arg_count`
@@ -306,7 +297,6 @@ impl<'tcx> Body<'tcx> {
306297
arg_count: usize,
307298
var_debug_info: Vec<VarDebugInfo<'tcx>>,
308299
span: Span,
309-
generator_kind: Option<GeneratorKind>,
310300
tainted_by_errors: Option<ErrorGuaranteed>,
311301
) -> Self {
312302
// We need `arg_count` locals, and one for the return place.
@@ -323,14 +313,6 @@ impl<'tcx> Body<'tcx> {
323313
source,
324314
basic_blocks: BasicBlocks::new(basic_blocks),
325315
source_scopes,
326-
generator: generator_kind.map(|generator_kind| {
327-
Box::new(GeneratorInfo {
328-
yield_ty: None,
329-
generator_drop: None,
330-
generator_layout: None,
331-
generator_kind,
332-
})
333-
}),
334316
local_decls,
335317
user_type_annotations,
336318
arg_count,
@@ -357,7 +339,6 @@ impl<'tcx> Body<'tcx> {
357339
source: MirSource::item(CRATE_DEF_ID.to_def_id()),
358340
basic_blocks: BasicBlocks::new(basic_blocks),
359341
source_scopes: IndexVec::new(),
360-
generator: None,
361342
local_decls: IndexVec::new(),
362343
user_type_annotations: IndexVec::new(),
363344
arg_count: 0,
@@ -489,24 +470,15 @@ impl<'tcx> Body<'tcx> {
489470
.unwrap_or_else(|| Either::Right(block_data.terminator()))
490471
}
491472

492-
#[inline]
493-
pub fn yield_ty(&self) -> Option<Ty<'tcx>> {
494-
self.generator.as_ref().and_then(|generator| generator.yield_ty)
495-
}
496-
497-
#[inline]
498-
pub fn generator_layout(&self) -> Option<&GeneratorLayout<'tcx>> {
499-
self.generator.as_ref().and_then(|generator| generator.generator_layout.as_ref())
500-
}
501-
502-
#[inline]
503-
pub fn generator_drop(&self) -> Option<&Body<'tcx>> {
504-
self.generator.as_ref().and_then(|generator| generator.generator_drop.as_ref())
505-
}
506-
507-
#[inline]
508-
pub fn generator_kind(&self) -> Option<GeneratorKind> {
509-
self.generator.as_ref().map(|generator| generator.generator_kind)
473+
pub fn yield_ty(&self, tcx: TyCtxt<'_>) -> Option<Ty<'tcx>> {
474+
if tcx.generator_kind(self.source.def_id()).is_none() {
475+
return None;
476+
};
477+
let gen_ty = self.local_decls.raw[1].ty;
478+
match *gen_ty.kind() {
479+
ty::Generator(_, substs, _) => Some(substs.as_generator().sig().yield_ty),
480+
_ => None,
481+
}
510482
}
511483
}
512484

‎compiler/rustc_middle/src/mir/pretty.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,6 @@ fn dump_matched_mir_node<'tcx, F>(
131131
Some(promoted) => write!(file, "::{:?}`", promoted)?,
132132
}
133133
writeln!(file, " {} {}", disambiguator, pass_name)?;
134-
if let Some(ref layout) = body.generator_layout() {
135-
writeln!(file, "/* generator_layout = {:#?} */", layout)?;
136-
}
137134
writeln!(file)?;
138135
extra_data(PassWhere::BeforeCFG, &mut file)?;
139136
write_user_type_annotations(tcx, body, &mut file)?;
@@ -1012,7 +1009,7 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn Write) -> io::Res
10121009
write!(w, ": {} =", body.return_ty())?;
10131010
}
10141011

1015-
if let Some(yield_ty) = body.yield_ty() {
1012+
if let Some(yield_ty) = body.yield_ty(tcx) {
10161013
writeln!(w)?;
10171014
writeln!(w, "yields {}", yield_ty)?;
10181015
}

‎compiler/rustc_middle/src/mir/visit.rs

-10
Original file line numberDiff line numberDiff line change
@@ -970,16 +970,6 @@ macro_rules! extra_body_methods {
970970

971971
macro_rules! super_body {
972972
($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => {
973-
let span = $body.span;
974-
if let Some(gen) = &$($mutability)? $body.generator {
975-
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
976-
$self.visit_ty(
977-
yield_ty,
978-
TyContext::YieldTy(SourceInfo::outermost(span))
979-
);
980-
}
981-
}
982-
983973
for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) {
984974
$self.visit_basic_block_data(bb, data);
985975
}

‎compiler/rustc_middle/src/query/mod.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,10 @@ rustc_queries! {
419419
}
420420
}
421421

422-
query mir_drops_elaborated_and_const_checked(
423-
key: ty::WithOptConstParam<LocalDefId>
424-
) -> &'tcx Steal<mir::Body<'tcx>> {
422+
query mir_drops_elaborated_and_const_checked(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx (
423+
Steal<mir::Body<'tcx>>,
424+
Option<mir::GeneratorInfo<'tcx>>,
425+
) {
425426
no_hash
426427
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) }
427428
}
@@ -465,6 +466,12 @@ rustc_queries! {
465466
}
466467
}
467468

469+
query mir_generator_info(key: DefId) -> &'tcx mir::GeneratorInfo<'tcx> {
470+
desc { |tcx| "generator glue MIR for `{}`", tcx.def_path_str(key) }
471+
cache_on_disk_if { key.is_local() }
472+
separate_provide_extern
473+
}
474+
468475
/// MIR after our optimization passes have run. This is MIR that is ready
469476
/// for codegen. This is also the only query that can fetch non-local MIR, at present.
470477
query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> {

‎compiler/rustc_middle/src/ty/codec.rs

+1
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ impl_decodable_via_ref! {
381381
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
382382
&'tcx traits::ImplSource<'tcx, ()>,
383383
&'tcx mir::Body<'tcx>,
384+
&'tcx mir::GeneratorInfo<'tcx>,
384385
&'tcx mir::UnsafetyCheckResult,
385386
&'tcx mir::BorrowCheckResult<'tcx>,
386387
&'tcx mir::coverage::CodeRegion,

‎compiler/rustc_middle/src/ty/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2509,7 +2509,11 @@ impl<'tcx> TyCtxt<'tcx> {
25092509
/// Returns layout of a generator. Layout might be unavailable if the
25102510
/// generator is tainted by errors.
25112511
pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> {
2512-
self.optimized_mir(def_id).generator_layout()
2512+
if self.generator_kind(def_id).is_some() {
2513+
Some(&self.mir_generator_info(def_id).generator_layout)
2514+
} else {
2515+
None
2516+
}
25132517
}
25142518

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

‎compiler/rustc_middle/src/ty/parameterized.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_hir::def_id::{DefId, DefIndex};
33
use rustc_index::vec::{Idx, IndexVec};
44

55
use crate::middle::exported_symbols::ExportedSymbol;
6-
use crate::mir::Body;
6+
use crate::mir::{Body, GeneratorInfo};
77
use crate::ty::abstract_const::Node;
88
use crate::ty::{
99
self, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty,
@@ -124,6 +124,7 @@ parameterized_over_tcx! {
124124
Predicate,
125125
GeneratorDiagnosticData,
126126
Body,
127+
GeneratorInfo,
127128
Node,
128129
ExportedSymbol,
129130
}

0 commit comments

Comments
 (0)
Please sign in to comment.