diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 4431a2e8ec60d..68a33e64b587c 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -115,28 +115,26 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } + let body_yield_ty = body.yield_ty(self.tcx()); debug!( "equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}", - body.yield_ty(), - universal_regions.yield_ty + body_yield_ty, universal_regions.yield_ty ); // We will not have a universal_regions.yield_ty if we yield (by accident) // outside of a generator and return an `impl Trait`, so emit a delay_span_bug // because we don't want to panic in an assert here if we've already got errors. - if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() { + if body_yield_ty.is_some() != universal_regions.yield_ty.is_some() { self.tcx().sess.delay_span_bug( body.span, &format!( "Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})", - body.yield_ty(), - universal_regions.yield_ty, + body_yield_ty, universal_regions.yield_ty, ), ); } - if let (Some(mir_yield_ty), Some(ur_yield_ty)) = - (body.yield_ty(), universal_regions.yield_ty) + if let (Some(mir_yield_ty), Some(ur_yield_ty)) = (body_yield_ty, universal_regions.yield_ty) { let yield_span = body.local_decls[RETURN_PLACE].source_info.span; self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a620c987052ba..cf90388040d96 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1473,7 +1473,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_operand(value, term_location); let value_ty = value.ty(body, tcx); - match body.yield_ty() { + match body.yield_ty(tcx) { None => span_mirbug!(self, term, "yield in non-generator"), Some(ty) => { if let Err(terr) = self.sub_types( diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 163ccd9460c54..752fefd46c36c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1235,8 +1235,8 @@ fn generator_layout_and_saved_local_names<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, ) -> (&'tcx GeneratorLayout<'tcx>, IndexVec>) { + let generator_layout = &tcx.mir_generator_info(def_id).generator_layout; let body = tcx.optimized_mir(def_id); - let generator_layout = body.generator_layout().unwrap(); let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys); let state_arg = mir::Local::new(1); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index cbfdb47dd1a40..d7884b0170a75 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -222,7 +222,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's // no need to emit duplicate errors here. - if self.ccx.is_async() || body.generator.is_some() { + if self.ccx.is_async() || tcx.generator_kind(def_id).is_some() { tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`"); return; } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index f5ba408bee0e1..75b7c0272be84 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -973,7 +973,6 @@ pub fn promote_candidates<'tcx>( 0, vec![], body.span, - body.generator_kind(), body.tainted_by_errors, ); promoted.phase = MirPhase::Analysis(AnalysisPhase::Initial); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index b798862583952..78e5302e0d21e 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -65,6 +65,7 @@ impl<'tcx> MirPass<'tcx> for Validator { storage_liveness, place_cache: Vec::new(), value_cache: Vec::new(), + is_generator: tcx.generator_kind(def_id).is_some(), } .visit_body(body); } @@ -117,6 +118,7 @@ struct TypeChecker<'a, 'tcx> { storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive>, place_cache: Vec>, value_cache: Vec, + is_generator: bool, } impl<'a, 'tcx> TypeChecker<'a, 'tcx> { @@ -323,16 +325,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } &ty::Generator(def_id, substs, _) => { let f_ty = if let Some(var) = parent_ty.variant_index { - let gen_body = if def_id == self.body.source.def_id() { - self.body - } else { - self.tcx.optimized_mir(def_id) - }; - - let Some(layout) = gen_body.generator_layout() else { - self.fail(location, format!("No generator layout for {:?}", parent_ty)); - return; - }; + let generator_info = self.tcx.mir_generator_info(def_id); + let layout = &generator_info.generator_layout; let Some(&local) = layout.variant_fields[var].get(f) else { fail_out_of_bounds(self, location); @@ -836,10 +830,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } TerminatorKind::Yield { resume, drop, .. } => { - if self.body.generator.is_none() { + if !self.is_generator { self.fail(location, "`Yield` cannot appear outside generator bodies"); } - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.mir_phase >= MirPhase::Runtime(RuntimePhase::GeneratorsLowered) { self.fail(location, "`Yield` should have been replaced by generator lowering"); } self.check_edge(location, *resume, EdgeKind::Normal); @@ -878,10 +872,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } TerminatorKind::GeneratorDrop => { - if self.body.generator.is_none() { + if !self.is_generator { self.fail(location, "`GeneratorDrop` cannot appear outside generator bodies"); } - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.mir_phase >= MirPhase::Runtime(RuntimePhase::GeneratorsLowered) { self.fail( location, "`GeneratorDrop` should have been replaced by generator lowering", diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 6b447ebd99910..505ac9a94b384 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -203,6 +203,7 @@ provide! { tcx, def_id, other, cdata, thir_abstract_const => { table } optimized_mir => { table } mir_for_ctfe => { table } + mir_generator_info => { table } promoted_mir => { table } def_span => { table } def_ident_span => { table } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 039486ba02c37..da38d4608fa50 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1387,6 +1387,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); + + if let DefKind::Generator = self.tcx.def_kind(def_id) { + record!(self.tables.mir_generator_info[def_id.to_def_id()] <- tcx.mir_generator_info(def_id)); + } } if encode_const { record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id)); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 6f849a58580e6..fc7821dc0927e 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -361,6 +361,7 @@ define_tables! { object_lifetime_default: Table>, optimized_mir: Table>>, mir_for_ctfe: Table>>, + mir_generator_info: Table>>, promoted_mir: Table>>>, // FIXME(compiler-errors): Why isn't this a LazyArray? thir_abstract_const: Table]>>, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 65d5f755f7248..4fc574bc54fc3 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -13,6 +13,11 @@ macro_rules! arena_types { [] steal_thir: rustc_data_structures::steal::Steal>, [] steal_mir: rustc_data_structures::steal::Steal>, [decode] mir: rustc_middle::mir::Body<'tcx>, + [decode] generator_info: rustc_middle::mir::GeneratorInfo<'tcx>, + [] mir_generator_lowered: ( + rustc_data_structures::steal::Steal>, + Option>, + ), [] steal_promoted: rustc_data_structures::steal::Steal< rustc_index::vec::IndexVec< diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c5a450b0e2e53..81869f411fdca 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -179,18 +179,11 @@ impl<'tcx> MirSource<'tcx> { #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct GeneratorInfo<'tcx> { - /// The yield type of the function, if it is a generator. - pub yield_ty: Option>, - /// Generator drop glue. - pub generator_drop: Option>, + pub generator_drop: Body<'tcx>, /// The layout of a generator. Produced by the state transformation. - pub generator_layout: Option>, - - /// If this is a generator then record the type of source expression that caused this generator - /// to be created. - pub generator_kind: GeneratorKind, + pub generator_layout: GeneratorLayout<'tcx>, } /// The lowered representation of a single function. @@ -213,8 +206,6 @@ pub struct Body<'tcx> { /// and used for debuginfo. Indexed by a `SourceScope`. pub source_scopes: IndexVec>, - pub generator: Option>>, - /// Declarations of locals. /// /// The first local is the return value pointer, followed by `arg_count` @@ -279,7 +270,6 @@ impl<'tcx> Body<'tcx> { arg_count: usize, var_debug_info: Vec>, span: Span, - generator_kind: Option, tainted_by_errors: Option, ) -> Self { // We need `arg_count` locals, and one for the return place. @@ -295,14 +285,6 @@ impl<'tcx> Body<'tcx> { source, basic_blocks: BasicBlocks::new(basic_blocks), source_scopes, - generator: generator_kind.map(|generator_kind| { - Box::new(GeneratorInfo { - yield_ty: None, - generator_drop: None, - generator_layout: None, - generator_kind, - }) - }), local_decls, user_type_annotations, arg_count, @@ -328,7 +310,6 @@ impl<'tcx> Body<'tcx> { source: MirSource::item(CRATE_DEF_ID.to_def_id()), basic_blocks: BasicBlocks::new(basic_blocks), source_scopes: IndexVec::new(), - generator: None, local_decls: IndexVec::new(), user_type_annotations: IndexVec::new(), arg_count: 0, @@ -460,24 +441,15 @@ impl<'tcx> Body<'tcx> { .unwrap_or_else(|| Either::Right(block_data.terminator())) } - #[inline] - pub fn yield_ty(&self) -> Option> { - self.generator.as_ref().and_then(|generator| generator.yield_ty) - } - - #[inline] - pub fn generator_layout(&self) -> Option<&GeneratorLayout<'tcx>> { - self.generator.as_ref().and_then(|generator| generator.generator_layout.as_ref()) - } - - #[inline] - pub fn generator_drop(&self) -> Option<&Body<'tcx>> { - self.generator.as_ref().and_then(|generator| generator.generator_drop.as_ref()) - } - - #[inline] - pub fn generator_kind(&self) -> Option { - self.generator.as_ref().map(|generator| generator.generator_kind) + pub fn yield_ty(&self, tcx: TyCtxt<'_>) -> Option> { + if tcx.generator_kind(self.source.def_id()).is_none() { + return None; + }; + let gen_ty = self.local_decls.raw[1].ty; + match *gen_ty.kind() { + ty::Generator(_, substs, _) => Some(substs.as_generator().sig().yield_ty), + _ => None, + } } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 88c16189f1dc6..0001d98f7c32b 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -131,7 +131,10 @@ fn dump_matched_mir_node<'tcx, F>( Some(promoted) => write!(file, "::{:?}`", promoted)?, } writeln!(file, " {} {}", disambiguator, pass_name)?; - if let Some(ref layout) = body.generator_layout() { + // Trying to fetch the layout before it has been computed would create a query cycle. + if body.phase >= MirPhase::Runtime(RuntimePhase::GeneratorsLowered) + && let Some(layout) = tcx.generator_layout(body.source.def_id()) + { writeln!(file, "/* generator_layout = {:#?} */", layout)?; } writeln!(file)?; @@ -1003,7 +1006,7 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn Write) -> io::Res write!(w, ": {} =", body.return_ty())?; } - if let Some(yield_ty) = body.yield_ty() { + if let Some(yield_ty) = body.yield_ty(tcx) { writeln!(w)?; writeln!(w, "yields {}", yield_ty)?; } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index d7b9d59eced51..f1d652d6f7da4 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -112,8 +112,6 @@ pub enum RuntimePhase { /// In addition to the semantic changes, beginning with this phase, the following variants are /// disallowed: /// * [`TerminatorKind::DropAndReplace`] - /// * [`TerminatorKind::Yield`] - /// * [`TerminatorKind::GeneratorDrop`] /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array` /// /// And the following variants are allowed: @@ -126,7 +124,13 @@ pub enum RuntimePhase { /// Beginning with this phase, the following variant is disallowed: /// * [`ProjectionElem::Deref`] of `Box` PostCleanup = 1, - Optimized = 2, + /// Beginning with this phase, the following variant is disallowed: + /// * [`TerminatorKind::Yield`] + /// * [`TerminatorKind::GeneratorDrop`] + /// + /// Furthermore, `Copy` operands are allowed for non-`Copy` types. + GeneratorsLowered = 2, + Optimized = 3, } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 7bd65f42e3f92..4978b1ef58f95 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -979,16 +979,6 @@ macro_rules! extra_body_methods { macro_rules! super_body { ($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => { - let span = $body.span; - if let Some(gen) = &$($mutability)? $body.generator { - if let Some(yield_ty) = $(& $mutability)? gen.yield_ty { - $self.visit_ty( - yield_ty, - TyContext::YieldTy(SourceInfo::outermost(span)) - ); - } - } - for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) { $self.visit_basic_block_data(bb, data); } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 8e7bacca262e1..817852d92c1fe 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -423,6 +423,21 @@ rustc_queries! { } } + query mir_generator_lowered(key: LocalDefId) -> &'tcx ( + Steal>, + Option>, + + ) { + no_hash + desc { |tcx| "computing generator MIR for `{}`", tcx.def_path_str(key.to_def_id()) } + } + + query mir_generator_info(key: DefId) -> &'tcx mir::GeneratorInfo<'tcx> { + desc { |tcx| "generator glue MIR for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 51137c52659db..c5be020c25866 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -381,6 +381,7 @@ impl_decodable_via_ref! { &'tcx ty::List>>, &'tcx traits::ImplSource<'tcx, ()>, &'tcx mir::Body<'tcx>, + &'tcx mir::GeneratorInfo<'tcx>, &'tcx mir::UnsafetyCheckResult, &'tcx mir::BorrowCheckResult<'tcx>, &'tcx mir::coverage::CodeRegion, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a3f7880b9a568..cacacba6d2f0b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2291,7 +2291,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns layout of a generator. Layout might be unavailable if the /// generator is tainted by errors. pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> { - self.optimized_mir(def_id).generator_layout() + if self.generator_kind(def_id).is_some() { + Some(&self.mir_generator_info(def_id).generator_layout) + } else { + None + } } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index ca24c0d1ce386..3a5fa35df0302 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -2,7 +2,7 @@ use rustc_hir::def_id::DefId; use rustc_index::vec::{Idx, IndexVec}; use crate::middle::exported_symbols::ExportedSymbol; -use crate::mir::Body; +use crate::mir::{Body, GeneratorInfo}; use crate::ty::abstract_const::Node; use crate::ty::{ self, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty, @@ -117,6 +117,7 @@ parameterized_over_tcx! { Predicate, GeneratorDiagnosticData, Body, + GeneratorInfo, Node, ExportedSymbol, } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 763038c52d7fa..853b4f92ec8b0 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -199,18 +199,18 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ let arguments = implicit_argument.into_iter().chain(explicit_arguments); - let (yield_ty, return_ty) = if body.generator_kind.is_some() { + let return_ty = if body.generator_kind.is_some() { let gen_ty = tcx.typeck_body(body_id).node_type(id); let gen_sig = match gen_ty.kind() { ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(), _ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty), }; - (Some(gen_sig.yield_ty), gen_sig.return_ty) + gen_sig.return_ty } else { - (None, fn_sig.output()) + fn_sig.output() }; - let mut mir = build::construct_fn( + build::construct_fn( &thir, &infcx, def, @@ -223,11 +223,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ body, expr, span_with_body, - ); - if yield_ty.is_some() { - mir.generator.as_mut().unwrap().yield_ty = yield_ty; - } - mir + ) } else { // Get the revealed type of this const. This is *not* the adjusted // type of its body, which may be a subtype of this type. For @@ -273,8 +269,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ debug_assert!( !(body.local_decls.has_free_regions() || body.basic_blocks.has_free_regions() - || body.var_debug_info.has_free_regions() - || body.yield_ty().has_free_regions()), + || body.var_debug_info.has_free_regions()), "Unexpected free regions in MIR: {:?}", body, ); @@ -797,7 +792,7 @@ fn construct_error<'a, 'tcx>( } cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable); - let mut body = Body::new( + Body::new( MirSource::item(def.did.to_def_id()), cfg.basic_blocks, source_scopes, @@ -806,11 +801,8 @@ fn construct_error<'a, 'tcx>( num_params, vec![], span, - generator_kind, Some(err), - ); - body.generator.as_mut().map(|gen| gen.yield_ty = Some(ty)); - body + ) } impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -897,7 +889,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.arg_count, self.var_debug_info, self.fn_span, - self.generator_kind, self.typeck_results.tainted_by_errors, ) } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 53f33a7a0bad2..162a4e9a8c658 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -138,7 +138,6 @@ impl<'tcx> MirPass<'tcx> for ConstProp { body.arg_count, Default::default(), body.span, - body.generator_kind(), body.tainted_by_errors, ); diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 082d6c9f07e53..c8ea44e6b7840 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -113,7 +113,6 @@ impl<'tcx> MirLint<'tcx> for ConstProp { body.arg_count, Default::default(), body.span, - body.generator_kind(), body.tainted_by_errors, ); diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index dbff4a6bd696e..5e8aabe36356f 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -52,7 +52,6 @@ use crate::deref_separator::deref_finder; use crate::simplify; use crate::util::expand_aggregate; -use crate::MirPass; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; @@ -73,8 +72,6 @@ use rustc_target::abi::VariantIdx; use rustc_target::spec::PanicStrategy; use std::{iter, ops}; -pub struct StateTransform; - struct RenameLocalVisitor<'tcx> { from: Local, to: Local, @@ -970,9 +967,8 @@ fn create_generator_drop_shim<'tcx>( // Make sure we remove dead blocks to remove // unrelated code from the resume part of the function - simplify::remove_dead_blocks(tcx, &mut body); - - dump_mir(tcx, None, "generator_drop", &0, &body, |_, _| Ok(())); + simplify::simplify_cfg(tcx, &mut body); + simplify::simplify_locals(&mut body, tcx); body } @@ -1073,6 +1069,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { fn create_generator_resume_function<'tcx>( tcx: TyCtxt<'tcx>, + generator_kind: hir::GeneratorKind, transform: TransformVisitor<'tcx>, body: &mut Body<'tcx>, can_return: bool, @@ -1118,8 +1115,6 @@ fn create_generator_resume_function<'tcx>( cases.insert(0, (UNRESUMED, BasicBlock::new(0))); // Panic when resumed on the returned or poisoned state - let generator_kind = body.generator_kind().unwrap(); - if can_unwind { cases.insert( 1, @@ -1142,8 +1137,6 @@ fn create_generator_resume_function<'tcx>( // Make sure we remove dead blocks to remove // unrelated code from the drop part of the function simplify::remove_dead_blocks(tcx, body); - - dump_mir(tcx, None, "generator_resume", &0, body, |_, _| Ok(())); } fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { @@ -1239,141 +1232,146 @@ fn create_cases<'tcx>( .collect() } -impl<'tcx> MirPass<'tcx> for StateTransform { - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let Some(yield_ty) = body.yield_ty() else { - // This only applies to generators - return; - }; +pub(crate) fn state_transform_body_for_generator<'tcx>( + tcx: TyCtxt<'tcx>, + generator_kind: hir::GeneratorKind, + body: &mut Body<'tcx>, +) -> GeneratorInfo<'tcx> { + // The first argument is the generator type passed by value + let gen_ty = body.local_decls.raw[1].ty; - assert!(body.generator_drop().is_none()); - - // The first argument is the generator type passed by value - let gen_ty = body.local_decls.raw[1].ty; - - // Get the interior types and substs which typeck computed - let (upvars, interior, discr_ty, movable) = match *gen_ty.kind() { - ty::Generator(_, substs, movability) => { - let substs = substs.as_generator(); - ( - substs.upvar_tys().collect(), - substs.witness(), - substs.discr_ty(tcx), - movability == hir::Movability::Movable, - ) - } - _ => { - tcx.sess - .delay_span_bug(body.span, &format!("unexpected generator type {}", gen_ty)); - return; - } - }; + // Get the interior types and substs which typeck computed + let (yield_ty, return_ty, upvars, interior, discr_ty, movable) = match *gen_ty.kind() { + ty::Generator(_, substs, movability) => { + let substs = substs.as_generator(); + ( + substs.sig().yield_ty, + substs.sig().return_ty, + substs.upvar_tys().collect(), + substs.witness(), + substs.discr_ty(tcx), + movability == hir::Movability::Movable, + ) + } + _ => span_bug!(body.span, "unexpected generator type {}", gen_ty), + }; - // Compute GeneratorState - let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); - let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.intern_substs(&[yield_ty.into(), body.return_ty().into()]); - let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); - - // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local - // RETURN_PLACE then is a fresh unused local with type ret_ty. - let new_ret_local = replace_local(RETURN_PLACE, ret_ty, body, tcx); - - // We also replace the resume argument and insert an `Assign`. - // This is needed because the resume argument `_2` might be live across a `yield`, in which - // case there is no `Assign` to it that the transform can turn into a store to the generator - // state. After the yield the slot in the generator state would then be uninitialized. - let resume_local = Local::new(2); - let new_resume_local = - replace_local(resume_local, body.local_decls[resume_local].ty, body, tcx); - - // When first entering the generator, move the resume argument into its new local. - let source_info = SourceInfo::outermost(body.span); - let stmts = &mut body.basic_blocks_mut()[BasicBlock::new(0)].statements; - stmts.insert( - 0, - Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - new_resume_local.into(), - Rvalue::Use(Operand::Move(resume_local.into())), - ))), - }, - ); + // Compute GeneratorState + let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); + let state_adt_ref = tcx.adt_def(state_did); + let state_substs = tcx.intern_substs(&[yield_ty.into(), return_ty.into()]); + let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); + + // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local + // RETURN_PLACE then is a fresh unused local with type ret_ty. + let new_ret_local = replace_local(RETURN_PLACE, ret_ty, body, tcx); + + // We also replace the resume argument and insert an `Assign`. + // This is needed because the resume argument `_2` might be live across a `yield`, in which + // case there is no `Assign` to it that the transform can turn into a store to the generator + // state. After the yield the slot in the generator state would then be uninitialized. + let resume_local = Local::new(2); + let new_resume_local = + replace_local(resume_local, body.local_decls[resume_local].ty, body, tcx); + + // When first entering the generator, move the resume argument into its new local. + let source_info = SourceInfo::outermost(body.span); + let stmts = &mut body.basic_blocks_mut()[BasicBlock::new(0)].statements; + stmts.insert( + 0, + Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + new_resume_local.into(), + Rvalue::Use(Operand::Move(resume_local.into())), + ))), + }, + ); - let always_live_locals = always_storage_live_locals(&body); + let always_live_locals = always_storage_live_locals(&body); - let liveness_info = - locals_live_across_suspend_points(tcx, body, &always_live_locals, movable); + let liveness_info = locals_live_across_suspend_points(tcx, body, &always_live_locals, movable); - sanitize_witness(tcx, body, interior, upvars, &liveness_info.saved_locals); + sanitize_witness(tcx, body, interior, upvars, &liveness_info.saved_locals); - if tcx.sess.opts.unstable_opts.validate_mir { - let mut vis = EnsureGeneratorFieldAssignmentsNeverAlias { - assigned_local: None, - saved_locals: &liveness_info.saved_locals, - storage_conflicts: &liveness_info.storage_conflicts, - }; + if tcx.sess.opts.unstable_opts.validate_mir { + let mut vis = EnsureGeneratorFieldAssignmentsNeverAlias { + assigned_local: None, + saved_locals: &liveness_info.saved_locals, + storage_conflicts: &liveness_info.storage_conflicts, + }; - vis.visit_body(body); - } + vis.visit_body(body); + } - // Extract locals which are live across suspension point into `layout` - // `remap` gives a mapping from local indices onto generator struct indices - // `storage_liveness` tells us which locals have live storage at suspension points - let (remap, layout, storage_liveness) = compute_layout(liveness_info, body); - - let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id())); - - // Run the transformation which converts Places from Local to generator struct - // accesses for locals in `remap`. - // It also rewrites `return x` and `yield y` as writing a new generator state and returning - // GeneratorState::Complete(x) and GeneratorState::Yielded(y) respectively. - let mut transform = TransformVisitor { - tcx, - state_adt_ref, - state_substs, - remap, - storage_liveness, - always_live_locals, - suspension_points: Vec::new(), - new_ret_local, - discr_ty, - }; - transform.visit_body(body); + // Extract locals which are live across suspension point into `layout` + // `remap` gives a mapping from local indices onto generator struct indices + // `storage_liveness` tells us which locals have live storage at suspension points + let (remap, generator_layout, storage_liveness) = compute_layout(liveness_info, body); + + let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id())); + + // Run the transformation which converts Places from Local to generator struct + // accesses for locals in `remap`. + // It also rewrites `return x` and `yield y` as writing a new generator state and returning + // GeneratorState::Complete(x) and GeneratorState::Yielded(y) respectively. + let mut transform = TransformVisitor { + tcx, + state_adt_ref, + state_substs, + remap, + storage_liveness, + always_live_locals, + suspension_points: Vec::new(), + new_ret_local, + discr_ty, + }; + transform.visit_body(body); - // Update our MIR struct to reflect the changes we've made - body.arg_count = 2; // self, resume arg - body.spread_arg = None; + // Update our MIR struct to reflect the changes we've made + body.arg_count = 2; // self, resume arg + body.spread_arg = None; - body.generator.as_mut().unwrap().yield_ty = None; - body.generator.as_mut().unwrap().generator_layout = Some(layout); + // Insert `drop(generator_struct)` which is used to drop upvars for generators in + // the unresumed state. + // This is expanded to a drop ladder in `elaborate_generator_drops`. + let drop_clean = insert_clean_drop(body); - // Insert `drop(generator_struct)` which is used to drop upvars for generators in - // the unresumed state. - // This is expanded to a drop ladder in `elaborate_generator_drops`. - let drop_clean = insert_clean_drop(body); + dump_mir(tcx, None, "generator_pre-elab", &0, body, |_, _| Ok(())); - dump_mir(tcx, None, "generator_pre-elab", &0, body, |_, _| Ok(())); + // Expand `drop(generator_struct)` to a drop ladder which destroys upvars. + // If any upvars are moved out of, drop elaboration will handle upvar destruction. + // However we need to also elaborate the code generated by `insert_clean_drop`. + elaborate_generator_drops(tcx, body); - // Expand `drop(generator_struct)` to a drop ladder which destroys upvars. - // If any upvars are moved out of, drop elaboration will handle upvar destruction. - // However we need to also elaborate the code generated by `insert_clean_drop`. - elaborate_generator_drops(tcx, body); + dump_mir(tcx, None, "generator_post-transform", &0, body, |_, _| Ok(())); - dump_mir(tcx, None, "generator_post-transform", &0, body, |_, _| Ok(())); + // Create a copy of our MIR and use it to create the drop shim for the generator + let generator_drop = create_generator_drop_shim(tcx, &transform, gen_ty, body, drop_clean); - // Create a copy of our MIR and use it to create the drop shim for the generator - let drop_shim = create_generator_drop_shim(tcx, &transform, gen_ty, body, drop_clean); + dump_mir(tcx, None, "generator_drop", &0, &generator_drop, |position, file| { + if let PassWhere::BeforeCFG = position { + writeln!(file, "/* generator_layout = {:#?} */", generator_layout)?; + writeln!(file)?; + } + Ok(()) + }); - body.generator.as_mut().unwrap().generator_drop = Some(drop_shim); + // Create the Generator::resume function + create_generator_resume_function(tcx, generator_kind, transform, body, can_return); - // Create the Generator::resume function - create_generator_resume_function(tcx, transform, body, can_return); + dump_mir(tcx, None, "generator_resume", &0, body, |position, file| { + if let PassWhere::BeforeCFG = position { + writeln!(file, "/* generator_layout = {:#?} */", generator_layout)?; + writeln!(file)?; + } + Ok(()) + }); - // Run derefer to fix Derefs that are not in the first place - deref_finder(tcx, body); - } + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, body); + + GeneratorInfo { generator_drop, generator_layout } } /// Looks for any assignments between locals (e.g., `_4 = _5`) that will both be converted to fields diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index ba00f16308eae..c6c4f9701294f 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -79,12 +79,6 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { if body.source.promoted.is_some() { return false; } - // Avoid inlining into generators, since their `optimized_mir` is used for layout computation, - // which can create a cycle, even when no attempt is made to inline the function in the other - // direction. - if body.generator.is_some() { - return false; - } let param_env = tcx.param_env_reveal_all_normalized(def_id); @@ -888,16 +882,8 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } &ty::Generator(def_id, substs, _) => { let f_ty = if let Some(var) = parent_ty.variant_index { - let gen_body = if def_id == self.callee_body.source.def_id() { - self.callee_body - } else { - self.tcx.optimized_mir(def_id) - }; - - let Some(layout) = gen_body.generator_layout() else { - self.validation = Err("malformed MIR"); - return; - }; + let generator_info = self.tcx.mir_generator_info(def_id); + let layout = &generator_info.generator_layout; let Some(&local) = layout.variant_fields[var].get(f) else { self.validation = Err("malformed MIR"); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 162f7d969b181..0933e5f8ba42b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -28,9 +28,9 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_index::vec::IndexVec; use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{ - traversal, AnalysisPhase, Body, ConstQualifs, Constant, LocalDecl, MirPass, MirPhase, Operand, - Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo, Statement, StatementKind, - TerminatorKind, + traversal, AnalysisPhase, Body, ConstQualifs, Constant, GeneratorInfo, LocalDecl, MirPass, + MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo, + Statement, StatementKind, TerminatorKind, }; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; @@ -140,6 +140,8 @@ pub fn provide(providers: &mut Providers) { promoted_mir_of_const_arg: |tcx, (did, param_did)| { promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) }, + mir_generator_lowered, + mir_generator_info, ..*providers }; } @@ -519,7 +521,6 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late, // but before optimizations begin. &elaborate_box_derefs::ElaborateBoxDerefs, - &generator::StateTransform, &add_retag::AddRetag, // Deaggregator is necessary for const prop. We may want to consider implementing // CTFE support for aggregates. @@ -542,6 +543,42 @@ fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { pm::run_passes(tcx, body, passes); } +fn mir_generator_lowered<'tcx>( + tcx: TyCtxt<'tcx>, + did: LocalDefId, +) -> &'tcx (Steal>, Option>) { + assert_eq!(ty::WithOptConstParam::try_lookup(did, tcx), None); + + debug!("about to call mir_drops_elaborated..."); + let body = + tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal(); + let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst); + debug!("body: {:#?}", body); + + debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR"); + debug_assert_eq!(body.phase, MirPhase::Runtime(RuntimePhase::PostCleanup)); + + rustc_middle::mir::dump_mir(tcx, None, "StateTransform", &"before", &body, |_, _| Ok(())); + + let generator_info = if let Some(generator_kind) = tcx.generator_kind(did) { + Some(generator::state_transform_body_for_generator(tcx, generator_kind, &mut body)) + } else { + None + }; + + rustc_middle::mir::dump_mir(tcx, None, "StateTransform", &"after", &body, |_, _| Ok(())); + // Mark phase after dumping MIR since `dump_mir` inspects it to know whether calling + // `mir_generator_info` is safe. + body.phase = MirPhase::Runtime(RuntimePhase::GeneratorsLowered); + + tcx.arena.alloc((Steal::new(body), generator_info)) +} + +fn mir_generator_info<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx GeneratorInfo<'tcx> { + let did = did.expect_local(); + tcx.mir_generator_lowered(did).1.as_ref().unwrap() +} + fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn o1(x: T) -> WithMinOptLevel { WithMinOptLevel(1, x) @@ -621,10 +658,8 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { None => {} Some(other) => panic!("do not use `optimized_mir` for constants: {:?}", other), } - debug!("about to call mir_drops_elaborated..."); - let body = - tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal(); - let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst); + debug!("about to call mir_generator_lowered..."); + let mut body = tcx.mir_generator_lowered(did).0.steal(); debug!("body: {:#?}", body); run_optimization_passes(tcx, &mut body); diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index abe6cb285f505..88be81a2c60df 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -14,10 +14,6 @@ impl<'tcx> MirPass<'tcx> for RevealAll { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Do not apply this transformation to generators. - if body.generator.is_some() { - return; - } - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body); } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 2b21fbe0a617f..fe969a962c7ad 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -69,7 +69,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' // FIXME(#91576): Drop shims for generators aren't subject to the MIR passes at the end // of this function. Is this intentional? if let Some(ty::Generator(gen_def_id, substs, _)) = ty.map(Ty::kind) { - let body = tcx.optimized_mir(*gen_def_id).generator_drop().unwrap(); + let body = &tcx.mir_generator_info(*gen_def_id).generator_drop; let body = EarlyBinder(body.clone()).subst(tcx, substs); debug!("make_shim({:?}) = {:?}", instance, body); return body; @@ -235,7 +235,6 @@ fn new_body<'tcx>( arg_count, vec![], span, - None, // FIXME(compiler-errors): is this correct? None, ) diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir index 0d10f9b5ffb4d..6b2d59dc098ef 100644 --- a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir +++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir @@ -1,4 +1,5 @@ // MIR for `main::{closure#0}` 0 generator_drop + /* generator_layout = GeneratorLayout { field_tys: { _0: std::string::String, @@ -16,69 +17,33 @@ fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 10:17]) -> () { let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - let mut _2: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - let _3: std::string::String; // in scope 0 at $DIR/generator-drop-cleanup.rs:11:13: 11:15 - let _4: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:12:9: 12:14 - let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:12:9: 12:14 - let mut _6: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:10:18: 10:18 - let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + let mut _2: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 scope 1 { debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:11:13: 11:15 } bb0: { - _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + _2 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + switchInt(move _2) -> [0_u32: bb3, 3_u32: bb4, otherwise: bb5]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 } bb1: { - StorageDead(_5); // scope 1 at $DIR/generator-drop-cleanup.rs:12:13: 12:14 - StorageDead(_4); // scope 1 at $DIR/generator-drop-cleanup.rs:12:14: 12:15 - drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/generator-drop-cleanup.rs:13:5: 13:6 - } - - bb2: { - nop; // scope 0 at $DIR/generator-drop-cleanup.rs:13:5: 13:6 - goto -> bb8; // scope 0 at $DIR/generator-drop-cleanup.rs:13:5: 13:6 - } - - bb3: { return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 } - bb4 (cleanup): { + bb2 (cleanup): { resume; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 } - bb5 (cleanup): { - nop; // scope 0 at $DIR/generator-drop-cleanup.rs:13:5: 13:6 - goto -> bb4; // scope 0 at $DIR/generator-drop-cleanup.rs:13:5: 13:6 - } - - bb6: { + bb3: { return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 } - bb7: { - goto -> bb9; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - } - - bb8: { - goto -> bb3; // scope 0 at $DIR/generator-drop-cleanup.rs:13:5: 13:6 - } - - bb9: { - goto -> bb6; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - } - - bb10: { - StorageLive(_4); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - StorageLive(_5); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 - goto -> bb1; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + bb4: { + drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/generator-drop-cleanup.rs:13:5: 13:6 } - bb11: { + bb5: { return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 } } diff --git a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir index 94f4a5a63178d..5f677eafeb7f2 100644 --- a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir +++ b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir @@ -21,13 +21,15 @@ yields () bb0: { StorageLive(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:23:13: 23:14 - _3 = Foo(const 5_i32); // scope 0 at $DIR/generator-storage-dead-unwind.rs:23:17: 23:23 + Deinit(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:23:17: 23:23 + (_3.0: i32) = const 5_i32; // scope 0 at $DIR/generator-storage-dead-unwind.rs:23:17: 23:23 StorageLive(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:24:13: 24:14 - _4 = Bar(const 6_i32); // scope 1 at $DIR/generator-storage-dead-unwind.rs:24:17: 24:23 + Deinit(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:24:17: 24:23 + (_4.0: i32) = const 6_i32; // scope 1 at $DIR/generator-storage-dead-unwind.rs:24:17: 24:23 StorageLive(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14 StorageLive(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14 - _6 = (); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14 - _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14 + Deinit(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14 + _5 = yield(move _6) -> [resume: bb1, drop: bb5]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:9: 25:14 } bb1: { @@ -36,7 +38,7 @@ yields () StorageLive(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:9: 26:16 StorageLive(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:14: 26:15 _8 = move _3; // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:14: 26:15 - _7 = take::(move _8) -> [return: bb2, unwind: bb10]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:9: 26:16 + _7 = take::(move _8) -> [return: bb2, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:9: 26:16 // mir::Constant // + span: $DIR/generator-storage-dead-unwind.rs:26:9: 26:13 // + literal: Const { ty: fn(Foo) {take::}, val: Value() } @@ -48,7 +50,7 @@ yields () StorageLive(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:9: 27:16 StorageLive(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:14: 27:15 _10 = move _4; // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:14: 27:15 - _9 = take::(move _10) -> [return: bb3, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:9: 27:16 + _9 = take::(move _10) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:9: 27:16 // mir::Constant // + span: $DIR/generator-storage-dead-unwind.rs:27:9: 27:13 // + literal: Const { ty: fn(Bar) {take::}, val: Value() } @@ -59,66 +61,54 @@ yields () StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:16: 27:17 _0 = const (); // scope 0 at $DIR/generator-storage-dead-unwind.rs:22:19: 28:6 StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - goto -> bb4; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - } - - bb4: { StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 + drop(_1) -> [return: bb4, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 } - bb5: { + bb4: { return; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:18: +0:18 } - bb6: { + bb5: { StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:13: 25:14 StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:25:14: 25:15 StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - drop(_3) -> [return: bb7, unwind: bb15]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 + drop(_3) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 } - bb7: { + bb6: { StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 + drop(_1) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 } - bb8: { + bb7: { generator_drop; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18 } - bb9 (cleanup): { + bb8 (cleanup): { StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:15: 27:16 StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:16: 27:17 - goto -> bb12; // scope 2 at no-location + goto -> bb10; // scope 2 at no-location } - bb10 (cleanup): { - goto -> bb11; // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:15: 26:16 - } - - bb11 (cleanup): { + bb9 (cleanup): { StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:15: 26:16 StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:16: 26:17 - goto -> bb12; // scope 2 at no-location + goto -> bb10; // scope 2 at no-location } - bb12 (cleanup): { + bb10 (cleanup): { StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - goto -> bb13; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - } - - bb13 (cleanup): { StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 + drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 } - bb14 (cleanup): { + bb11 (cleanup): { resume; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18 } - bb15 (cleanup): { + bb12 (cleanup): { StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 - drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 + drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 } } diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir index 927f10242d2fe..160c4f8547f7a 100644 --- a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir +++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir @@ -1,4 +1,5 @@ // MIR for `main::{closure#0}` 0 generator_resume + /* generator_layout = GeneratorLayout { field_tys: { _0: HasDrop, @@ -38,7 +39,7 @@ fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24 bb1: { _10 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 nop; // scope 0 at $DIR/generator-tiny.rs:20:13: 20:15 - (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = HasDrop; // scope 0 at $DIR/generator-tiny.rs:20:18: 20:25 + Deinit((((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop)); // scope 0 at $DIR/generator-tiny.rs:20:18: 20:25 StorageLive(_4); // scope 1 at $DIR/generator-tiny.rs:21:9: 24:10 goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:21:9: 24:10 } @@ -46,7 +47,7 @@ fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24 bb2: { StorageLive(_6); // scope 1 at $DIR/generator-tiny.rs:22:13: 22:18 StorageLive(_7); // scope 1 at $DIR/generator-tiny.rs:22:13: 22:18 - _7 = (); // scope 1 at $DIR/generator-tiny.rs:22:13: 22:18 + Deinit(_7); // scope 1 at $DIR/generator-tiny.rs:22:13: 22:18 Deinit(_0); // scope 1 at $DIR/generator-tiny.rs:22:13: 22:18 ((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator-tiny.rs:22:13: 22:18 discriminant(_0) = 0; // scope 1 at $DIR/generator-tiny.rs:22:13: 22:18 diff --git a/src/test/mir-opt/inline/inline-async.rs b/src/test/mir-opt/inline/inline-async.rs index 5c838159b986c..079ef5ded8767 100644 --- a/src/test/mir-opt/inline/inline-async.rs +++ b/src/test/mir-opt/inline/inline-async.rs @@ -1,5 +1,4 @@ // Checks that inliner doesn't introduce cycles when optimizing generators. -// The outcome of optimization is not verfied, just the absence of the cycle. // Regression test for #76181. // // edition:2018 @@ -8,11 +7,13 @@ pub struct S; -impl S { - pub async fn g(&mut self) { - self.h(); - } - pub fn h(&mut self) { - let _ = self.g(); - } +// EMIT_MIR inline_async.g.Inline.diff +pub async fn g(s: &mut S) { + h(s); +} + +// EMIT_MIR inline_async.h.Inline.diff +#[inline(always)] +pub fn h(s: &mut S) { + let _ = g(s); } diff --git a/src/test/mir-opt/inline/inline_async.g.Inline.diff b/src/test/mir-opt/inline/inline_async.g.Inline.diff new file mode 100644 index 0000000000000..1c4cbcf052abc --- /dev/null +++ b/src/test/mir-opt/inline/inline_async.g.Inline.diff @@ -0,0 +1,34 @@ +- // MIR for `g` before Inline ++ // MIR for `g` after Inline + + fn g(_1: &mut S) -> std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]> { + debug s => _1; // in scope 0 at $DIR/inline-async.rs:+0:16: +0:17 + let mut _0: std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]>; // return place in scope 0 at $DIR/inline-async.rs:+0:27: +0:27 + let mut _2: [static generator@$DIR/inline-async.rs:11:27: 13:2]; // in scope 0 at $DIR/inline-async.rs:+0:27: +2:2 ++ scope 1 (inlined std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>) { // at $DIR/inline-async.rs:11:27: 13:2 ++ debug gen => _2; // in scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL ++ let mut _3: [static generator@$DIR/inline-async.rs:11:27: 13:2]; // in scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-async.rs:+0:27: +2:2 + Deinit(_2); // scope 0 at $DIR/inline-async.rs:+0:27: +2:2 + (_2.0: &mut S) = move _1; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2 + discriminant(_2) = 0; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2 +- _0 = std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>(move _2) -> bb1; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2 +- // mir::Constant +- // + span: $DIR/inline-async.rs:11:27: 13:2 +- // + literal: Const { ty: fn([static generator@$DIR/inline-async.rs:11:27: 13:2]) -> impl Future {std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>}, val: Value() } +- } +- +- bb1: { ++ StorageLive(_3); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL ++ _3 = move _2; // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL ++ Deinit(_0); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL ++ (_0.0: [static generator@$DIR/inline-async.rs:11:27: 13:2]) = move _3; // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL ++ StorageDead(_3); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/inline-async.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline-async.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_async.h.Inline.diff b/src/test/mir-opt/inline/inline_async.h.Inline.diff new file mode 100644 index 0000000000000..f0e13389f2387 --- /dev/null +++ b/src/test/mir-opt/inline/inline_async.h.Inline.diff @@ -0,0 +1,29 @@ +- // MIR for `h` before Inline ++ // MIR for `h` after Inline + + fn h(_1: &mut S) -> () { + debug s => _1; // in scope 0 at $DIR/inline-async.rs:+0:10: +0:11 + let mut _0: (); // return place in scope 0 at $DIR/inline-async.rs:+0:21: +0:21 + let mut _2: std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]>; // in scope 0 at $DIR/inline-async.rs:+1:13: +1:17 + let mut _3: &mut S; // in scope 0 at $DIR/inline-async.rs:+1:15: +1:16 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-async.rs:+1:13: +1:17 + StorageLive(_3); // scope 0 at $DIR/inline-async.rs:+1:15: +1:16 + _3 = &mut (*_1); // scope 0 at $DIR/inline-async.rs:+1:15: +1:16 + _2 = g(move _3) -> bb1; // scope 0 at $DIR/inline-async.rs:+1:13: +1:17 + // mir::Constant + // + span: $DIR/inline-async.rs:18:13: 18:14 + // + literal: Const { ty: for<'r> fn(&'r mut S) -> impl for<'r> Future {g}, val: Value() } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/inline-async.rs:+1:16: +1:17 + StorageDead(_2); // scope 0 at $DIR/inline-async.rs:+1:17: +1:18 + _0 = const (); // scope 0 at $DIR/inline-async.rs:+0:21: +2:2 + return; // scope 0 at $DIR/inline-async.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff deleted file mode 100644 index 28536dc28a722..0000000000000 --- a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff +++ /dev/null @@ -1,146 +0,0 @@ -- // MIR for `identity` before ConstProp -+ // MIR for `identity` after ConstProp - - fn identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53 - let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _3: std::ops::ControlFlow, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _4: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let _6: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let mut _8: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 1 { - debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - scope 9 { - debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - scope 10 (inlined >::from) { // at $SRC_DIR/core/src/result.rs:LL:COL - debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - } - } - } - } - scope 3 { - debug val => _9; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 4 { - } - } - scope 5 (inlined as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _14: std::result::Result; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - } - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb1: { - StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _2 = _9; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - } - - bb3: { - StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _6 = ((_3 as Break).0: std::result::Result); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } - - bb4: { - StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_14 as Err).0: i32) = move _15; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_14) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Break).0: std::result::Result) = move _14; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 -- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ _5 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ switchInt(const 1_isize) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - } - - bb5: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb6: { - StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Continue).0: i32) = move _12; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 -- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ _5 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ switchInt(const 0_isize) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - } - } - diff --git a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir deleted file mode 100644 index df20f0ed36b60..0000000000000 --- a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir +++ /dev/null @@ -1,124 +0,0 @@ -// MIR for `identity` after PreCodegen - -fn identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53 - let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _3: std::ops::ControlFlow, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _4: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - let _5: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let mut _6: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 1 { - debug residual => _5; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug residual => _6; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let _14: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _15: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - scope 9 { - debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - scope 10 (inlined >::from) { // at $SRC_DIR/core/src/result.rs:LL:COL - debug t => _16; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - } - } - } - } - scope 3 { - debug val => _7; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 4 { - } - } - scope 5 (inlined as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _8: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _9: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _10: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _12: std::result::Result; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug v => _9; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - debug e => _11; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - } - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _8 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _8) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb1: { - StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _11 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _13 = move _11; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_12 as Err).0: i32) = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_12) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Break).0: std::result::Result) = move _12; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _5 = ((_3 as Break).0: std::result::Result); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _6 = _5; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - _14 = move ((_6 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _16 = move _14; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _15 = move _16; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - ((_0 as Err).0: i32) = move _15; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } - - bb2: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb3: { - StorageLive(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _9 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - _10 = move _9; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Continue).0: i32) = move _10; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _7 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _2 = _7; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } -} diff --git a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff deleted file mode 100644 index 28269165e1c27..0000000000000 --- a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff +++ /dev/null @@ -1,103 +0,0 @@ -- // MIR for `too_complex` before ConstProp -+ // MIR for `too_complex` after ConstProp - - fn too_complex(_1: Result) -> Option { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17 - let mut _0: std::option::Option; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53 - let mut _2: std::ops::ControlFlow; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18 - let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45 - let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - let mut _7: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43 - let mut _8: isize; // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33 - let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - let mut _10: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43 - let _11: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - scope 1 { - debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17 - } - scope 2 { - debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18 - } - scope 3 { - debug v => _9; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32 - } - scope 4 { - debug r => _11; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 - } - - bb1: { - StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - _6 = ((_1 as Err).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - StorageLive(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 - _7 = _6; // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 - Deinit(_2); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 - ((_2 as Break).0: usize) = move _7; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 - discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 - StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44 - StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 -- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -- switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 -+ _8 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -+ switchInt(const 1_isize) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 - } - - bb2: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - } - - bb3: { - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46 - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 -- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -- switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 -+ _8 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -+ switchInt(const 0_isize) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 - } - - bb4: { - StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - } - - bb5: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - } - - bb6: { - StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - _10 = _9; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - ((_0 as Some).0: i32) = move _10; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 - StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - } - - bb7: { - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 - } - } - diff --git a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir deleted file mode 100644 index 0ee070619e79d..0000000000000 --- a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir +++ /dev/null @@ -1,73 +0,0 @@ -// MIR for `too_complex` after PreCodegen - -fn too_complex(_1: Result) -> Option { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17 - let mut _0: std::option::Option; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53 - let mut _2: std::ops::ControlFlow; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18 - let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45 - let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - let mut _8: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43 - let _9: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - scope 1 { - debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17 - } - scope 2 { - debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18 - } - scope 3 { - debug v => _7; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32 - } - scope 4 { - debug r => _9; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 - } - - bb1: { - StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 - StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - goto -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - } - - bb2: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - } - - bb3: { - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46 - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 - StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - _7 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - StorageLive(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - _8 = _7; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - ((_0 as Some).0: i32) = move _8; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - StorageDead(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 - StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - goto -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - } - - bb4: { - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 - } -} diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 0ae7bfa86bc76..1524be8c9864b 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -30,8 +30,9 @@ LL | let x: &'static i32 = &X; query stack during panic: #0 [mir_drops_elaborated_and_const_checked] elaborating drops for `main` -#1 [optimized_mir] optimizing MIR for `main` -#2 [collect_and_partition_mono_items] collect_and_partition_mono_items +#1 [mir_generator_lowered] computing generator MIR for `main` +#2 [optimized_mir] optimizing MIR for `main` +#3 [collect_and_partition_mono_items] collect_and_partition_mono_items end of query stack Future incompatibility report: Future breakage diagnostic: warning: any use of this value will cause an error