diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3bb8353f49e84..e09810e55d733 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2651,11 +2651,11 @@ rustc_queries! { } query generics_require_sized_self(def_id: DefId) -> bool { - desc { "check whether the item has a `where Self: Sized` bound" } + desc { |tcx| "check whether `{}` has a `where Self: Sized` bound", tcx.def_path_str(def_id) } } query cross_crate_inlinable(def_id: DefId) -> bool { - desc { "whether the item should be made inlinable across crates" } + desc { |tcx| "whether `{}` should be made inlinable across crates", tcx.def_path_str(def_id) } separate_provide_extern } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 761d5461a996f..bf1404a89132b 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -68,7 +68,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{CoroutineDesugaring, CoroutineKind}; use rustc_index::bit_set::{BitMatrix, DenseBitSet, GrowableBitSet}; use rustc_index::{Idx, IndexVec}; -use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ @@ -111,6 +111,8 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> { fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { if *local == self.from { *local = self.to; + } else if *local == self.to { + *local = self.from; } } @@ -160,6 +162,7 @@ impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> { } } +#[tracing::instrument(level = "trace", skip(tcx))] fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtxt<'tcx>) { place.local = new_base.local; @@ -167,6 +170,7 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx new_projection.append(&mut place.projection.to_vec()); place.projection = tcx.mk_place_elems(&new_projection); + tracing::trace!(?place); } const SELF_ARG: Local = Local::from_u32(1); @@ -205,8 +209,8 @@ struct TransformVisitor<'tcx> { // The set of locals that have no `StorageLive`/`StorageDead` annotations. always_live_locals: DenseBitSet, - // The original RETURN_PLACE local - old_ret_local: Local, + // New local we just create to hold the `CoroutineState` value. + new_ret_local: Local, old_yield_ty: Ty<'tcx>, @@ -271,6 +275,7 @@ impl<'tcx> TransformVisitor<'tcx> { // `core::ops::CoroutineState` only has single element tuple variants, // so we can just write to the downcasted first field and then set the // discriminant to the appropriate variant. + #[tracing::instrument(level = "trace", skip(self, statements))] fn make_state( &self, val: Operand<'tcx>, @@ -344,11 +349,12 @@ impl<'tcx> TransformVisitor<'tcx> { statements.push(Statement::new( source_info, - StatementKind::Assign(Box::new((Place::return_place(), rvalue))), + StatementKind::Assign(Box::new((self.new_ret_local.into(), rvalue))), )); } // Create a Place referencing a coroutine struct field + #[tracing::instrument(level = "trace", skip(self), ret)] fn make_field(&self, variant_index: VariantIdx, idx: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> { let self_place = Place::from(SELF_ARG); let base = self.tcx.mk_place_downcast_unnamed(self_place, variant_index); @@ -359,6 +365,7 @@ impl<'tcx> TransformVisitor<'tcx> { } // Create a statement which changes the discriminant + #[tracing::instrument(level = "trace", skip(self))] fn set_discr(&self, state_disc: VariantIdx, source_info: SourceInfo) -> Statement<'tcx> { let self_place = Place::from(SELF_ARG); Statement::new( @@ -371,6 +378,7 @@ impl<'tcx> TransformVisitor<'tcx> { } // Create a statement which reads the discriminant into a temporary + #[tracing::instrument(level = "trace", skip(self, body))] fn get_discr(&self, body: &mut Body<'tcx>) -> (Statement<'tcx>, Place<'tcx>) { let temp_decl = LocalDecl::new(self.discr_ty, body.span); let local_decls_len = body.local_decls.push(temp_decl); @@ -383,6 +391,27 @@ impl<'tcx> TransformVisitor<'tcx> { ); (assign, temp) } + + /// Allocates a new local and replaces all references of `local` with it. Returns the new local. + /// + /// `local` will be changed to a new local decl with type `ty`. + /// + /// Note that the new local will be uninitialized. It is the caller's responsibility to assign some + /// valid value to it before its first use. + #[tracing::instrument(level = "trace", skip(self, body))] + fn replace_local(&mut self, local: Local, new_local: Local, body: &mut Body<'tcx>) -> Local { + body.local_decls.swap(local, new_local); + + let mut visitor = RenameLocalVisitor { from: local, to: new_local, tcx: self.tcx }; + visitor.visit_body(body); + for suspension in &mut self.suspension_points { + let ctxt = PlaceContext::MutatingUse(MutatingUseContext::Yield); + let location = Location { block: START_BLOCK, statement_index: 0 }; + visitor.visit_place(&mut suspension.resume_arg, ctxt, location); + } + + new_local + } } impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { @@ -390,22 +419,20 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { self.tcx } - fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { + #[tracing::instrument(level = "trace", skip(self), ret)] + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _location: Location) { assert!(!self.remap.contains(*local)); } - fn visit_place( - &mut self, - place: &mut Place<'tcx>, - _context: PlaceContext, - _location: Location, - ) { + #[tracing::instrument(level = "trace", skip(self), ret)] + fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, _location: Location) { // Replace an Local in the remap with a coroutine struct access if let Some(&Some((ty, variant_index, idx))) = self.remap.get(place.local) { replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); } } + #[tracing::instrument(level = "trace", skip(self, data), ret)] fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { // Remove StorageLive and StorageDead statements for remapped locals for s in &mut data.statements { @@ -416,29 +443,35 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { } } - let ret_val = match data.terminator().kind { + for (statement_index, statement) in data.statements.iter_mut().enumerate() { + let location = Location { block, statement_index }; + self.visit_statement(statement, location); + } + + let location = Location { block, statement_index: data.statements.len() }; + let mut terminator = data.terminator.take().unwrap(); + let source_info = terminator.source_info; + match terminator.kind { TerminatorKind::Return => { - Some((true, None, Operand::Move(Place::from(self.old_ret_local)), None)) - } - TerminatorKind::Yield { ref value, resume, resume_arg, drop } => { - Some((false, Some((resume, resume_arg)), value.clone(), drop)) + let mut v = Operand::Move(Place::return_place()); + self.visit_operand(&mut v, location); + // We must assign the value first in case it gets declared dead below + self.make_state(v, source_info, true, &mut data.statements); + // State for returned + let state = VariantIdx::new(CoroutineArgs::RETURNED); + data.statements.push(self.set_discr(state, source_info)); + terminator.kind = TerminatorKind::Return; } - _ => None, - }; - - if let Some((is_return, resume, v, drop)) = ret_val { - let source_info = data.terminator().source_info; - // We must assign the value first in case it gets declared dead below - self.make_state(v, source_info, is_return, &mut data.statements); - let state = if let Some((resume, mut resume_arg)) = resume { - // Yield - let state = CoroutineArgs::RESERVED_VARIANTS + self.suspension_points.len(); - + TerminatorKind::Yield { mut value, resume, mut resume_arg, drop } => { // The resume arg target location might itself be remapped if its base local is // live across a yield. - if let Some(&Some((ty, variant, idx))) = self.remap.get(resume_arg.local) { - replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx); - } + self.visit_operand(&mut value, location); + let ctxt = PlaceContext::MutatingUse(MutatingUseContext::Yield); + self.visit_place(&mut resume_arg, ctxt, location); + // We must assign the value first in case it gets declared dead below + self.make_state(value.clone(), source_info, false, &mut data.statements); + // Yield + let state = CoroutineArgs::RESERVED_VARIANTS + self.suspension_points.len(); let storage_liveness: GrowableBitSet = self.storage_liveness[block].clone().unwrap().into(); @@ -453,7 +486,6 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { .push(Statement::new(source_info, StatementKind::StorageDead(l))); } } - self.suspension_points.push(SuspensionPoint { state, resume, @@ -462,16 +494,13 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { storage_liveness, }); - VariantIdx::new(state) - } else { - // Return - VariantIdx::new(CoroutineArgs::RETURNED) // state for returned - }; - data.statements.push(self.set_discr(state, source_info)); - data.terminator_mut().kind = TerminatorKind::Return; - } - - self.super_basic_block_data(block, data); + let state = VariantIdx::new(state); + data.statements.push(self.set_discr(state, source_info)); + terminator.kind = TerminatorKind::Return; + } + _ => self.visit_terminator(&mut terminator, location), + }; + data.terminator = Some(terminator); } } @@ -484,6 +513,7 @@ fn make_aggregate_adt<'tcx>( Rvalue::Aggregate(Box::new(AggregateKind::Adt(def_id, variant_idx, args, None, None)), operands) } +#[tracing::instrument(level = "trace", skip(tcx, body))] fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let coroutine_ty = body.local_decls.raw[1].ty; @@ -496,6 +526,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo SelfArgVisitor::new(tcx, ProjectionElem::Deref).visit_body(body); } +#[tracing::instrument(level = "trace", skip(tcx, body))] fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let ref_coroutine_ty = body.local_decls.raw[1].ty; @@ -512,27 +543,6 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body .visit_body(body); } -/// Allocates a new local and replaces all references of `local` with it. Returns the new local. -/// -/// `local` will be changed to a new local decl with type `ty`. -/// -/// Note that the new local will be uninitialized. It is the caller's responsibility to assign some -/// valid value to it before its first use. -fn replace_local<'tcx>( - local: Local, - ty: Ty<'tcx>, - body: &mut Body<'tcx>, - tcx: TyCtxt<'tcx>, -) -> Local { - let new_decl = LocalDecl::new(ty, body.span); - let new_local = body.local_decls.push(new_decl); - body.local_decls.swap(local, new_local); - - RenameLocalVisitor { from: local, to: new_local, tcx }.visit_body(body); - - new_local -} - /// Transforms the `body` of the coroutine applying the following transforms: /// /// - Eliminates all the `get_context` calls that async lowering created. @@ -554,6 +564,7 @@ fn replace_local<'tcx>( /// The async lowering step and the type / lifetime inference / checking are /// still using the `ResumeTy` indirection for the time being, and that indirection /// is removed here. After this transform, the coroutine body only knows about `&mut Context<'_>`. +#[tracing::instrument(level = "trace", skip(tcx, body), ret)] fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty<'tcx> { let context_mut_ref = Ty::new_task_context(tcx); @@ -607,6 +618,7 @@ fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local } #[cfg_attr(not(debug_assertions), allow(unused))] +#[tracing::instrument(level = "trace", skip(tcx, body), ret)] fn replace_resume_ty_local<'tcx>( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, @@ -617,7 +629,7 @@ fn replace_resume_ty_local<'tcx>( // We have to replace the `ResumeTy` that is used for type and borrow checking // with `&mut Context<'_>` in MIR. #[cfg(debug_assertions)] - { + if local_ty != context_mut_ref { if let ty::Adt(resume_ty_adt, _) = local_ty.kind() { let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, body.span)); assert_eq!(*resume_ty_adt, expected_adt); @@ -671,6 +683,7 @@ struct LivenessInfo { /// case none exist, the local is considered to be always live. /// - a local has to be stored if it is either directly used after the /// the suspend point, or if it is live and has been previously borrowed. +#[tracing::instrument(level = "trace", skip(tcx, body))] fn locals_live_across_suspend_points<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, @@ -946,6 +959,7 @@ impl StorageConflictVisitor<'_, '_> { } } +#[tracing::instrument(level = "trace", skip(liveness, body))] fn compute_layout<'tcx>( liveness: LivenessInfo, body: &Body<'tcx>, @@ -1050,7 +1064,9 @@ fn compute_layout<'tcx>( variant_source_info, storage_conflicts, }; + debug!(?remap); debug!(?layout); + debug!(?storage_liveness); (remap, layout, storage_liveness) } @@ -1222,6 +1238,7 @@ fn generate_poison_block_and_redirect_unwinds_there<'tcx>( } } +#[tracing::instrument(level = "trace", skip(tcx, transform, body))] fn create_coroutine_resume_function<'tcx>( tcx: TyCtxt<'tcx>, transform: TransformVisitor<'tcx>, @@ -1298,7 +1315,7 @@ fn create_coroutine_resume_function<'tcx>( } /// An operation that can be performed on a coroutine. -#[derive(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone, Debug)] enum Operation { Resume, Drop, @@ -1313,6 +1330,7 @@ impl Operation { } } +#[tracing::instrument(level = "trace", skip(transform, body))] fn create_cases<'tcx>( body: &mut Body<'tcx>, transform: &TransformVisitor<'tcx>, @@ -1437,11 +1455,14 @@ fn check_field_tys_sized<'tcx>( } impl<'tcx> crate::MirPass<'tcx> for StateTransform { + #[tracing::instrument(level = "trace", skip(self, tcx, body))] fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let Some(old_yield_ty) = body.yield_ty() else { // This only applies to coroutines return; }; + tracing::trace!(def_id = ?body.source.def_id()); + let old_ret_ty = body.return_ty(); assert!(body.coroutine_drop().is_none() && body.coroutine_drop_async().is_none()); @@ -1486,10 +1507,6 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { } }; - // We rename RETURN_PLACE which has type mir.return_ty to old_ret_local - // RETURN_PLACE then is a fresh unused local with type ret_ty. - let old_ret_local = replace_local(RETURN_PLACE, new_ret_ty, body, tcx); - // We need to insert clean drop for unresumed state and perform drop elaboration // (finally in open_drop_for_tuple) before async drop expansion. // Async drops, produced by this drop elaboration, will be expanded, @@ -1511,13 +1528,18 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { cleanup_async_drops(body); } + // 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 = body.local_decls.push(LocalDecl::new(new_ret_ty, body.span)); + tracing::trace!(?new_ret_local); + // 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 coroutine // state. After the yield the slot in the coroutine state would then be uninitialized. - let resume_local = CTX_ARG; - let resume_ty = body.local_decls[resume_local].ty; - let old_resume_local = replace_local(resume_local, resume_ty, body, tcx); + let resume_ty = body.local_decls[CTX_ARG].ty; + let new_resume_local = body.local_decls.push(LocalDecl::new(resume_ty, body.span)); + tracing::trace!(?new_resume_local); // When first entering the coroutine, move the resume argument into its old local // (which is now a generator interior). @@ -1528,8 +1550,8 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { Statement::new( source_info, StatementKind::Assign(Box::new(( - old_resume_local.into(), - Rvalue::Use(Operand::Move(resume_local.into())), + CTX_ARG.into(), + Rvalue::Use(Operand::Move(new_resume_local.into())), ))), ), ); @@ -1569,13 +1591,16 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { storage_liveness, always_live_locals, suspension_points: Vec::new(), - old_ret_local, discr_ty, + new_ret_local, old_ret_ty, old_yield_ty, }; transform.visit_body(body); + transform.replace_local(RETURN_PLACE, new_ret_local, body); + transform.replace_local(CTX_ARG, new_resume_local, body); + // Update our MIR struct to reflect the changes we've made body.arg_count = 2; // self, resume arg body.spread_arg = None; diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 1a314e029f4a7..389b11cffedff 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -126,6 +126,7 @@ fn build_pin_fut<'tcx>( // Ready() => ready_block // Pending => yield_block //} +#[tracing::instrument(level = "trace", skip(tcx, body), ret)] fn build_poll_switch<'tcx>( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, @@ -179,6 +180,7 @@ fn build_poll_switch<'tcx>( } // Gather blocks, reachable through 'drop' targets of Yield and Drop terminators (chained) +#[tracing::instrument(level = "trace", skip(body), ret)] fn gather_dropline_blocks<'tcx>(body: &mut Body<'tcx>) -> DenseBitSet { let mut dropline: DenseBitSet = DenseBitSet::new_empty(body.basic_blocks.len()); for (bb, data) in traversal::reverse_postorder(body) { @@ -249,6 +251,7 @@ pub(super) fn has_expandable_async_drops<'tcx>( } /// Expand Drop terminator for async drops into mainline poll-switch and dropline poll-switch +#[tracing::instrument(level = "trace", skip(tcx, body), ret)] pub(super) fn expand_async_drops<'tcx>( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, @@ -259,6 +262,7 @@ pub(super) fn expand_async_drops<'tcx>( let dropline = gather_dropline_blocks(body); // Clean drop and async_fut fields if potentially async drop is not expanded (stays sync) let remove_asyncness = |block: &mut BasicBlockData<'tcx>| { + tracing::trace!("remove_asyncness"); if let TerminatorKind::Drop { place: _, target: _, @@ -273,6 +277,7 @@ pub(super) fn expand_async_drops<'tcx>( } }; for bb in START_BLOCK..body.basic_blocks.next_index() { + tracing::trace!(?bb); // Drops in unwind path (cleanup blocks) are not expanded to async drops, only sync drops in unwind path if body[bb].is_cleanup { remove_asyncness(&mut body[bb]); @@ -461,6 +466,7 @@ pub(super) fn expand_async_drops<'tcx>( } } +#[tracing::instrument(level = "trace", skip(tcx, body))] pub(super) fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { use crate::elaborate_drop::{Unwind, elaborate_drop}; use crate::patch::MirPatch; @@ -519,6 +525,7 @@ pub(super) fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body elaborator.patch.apply(body); } +#[tracing::instrument(level = "trace", skip(tcx, body), ret)] pub(super) fn insert_clean_drop<'tcx>( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, @@ -550,6 +557,7 @@ pub(super) fn insert_clean_drop<'tcx>( .push(BasicBlockData::new(Some(Terminator { source_info, kind: term }), false)) } +#[tracing::instrument(level = "trace", skip(tcx, transform, body))] pub(super) fn create_coroutine_drop_shim<'tcx>( tcx: TyCtxt<'tcx>, transform: &TransformVisitor<'tcx>, @@ -619,6 +627,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>( } // Create async drop shim function to drop coroutine itself +#[tracing::instrument(level = "trace", skip(tcx, transform, body))] pub(super) fn create_coroutine_drop_shim_async<'tcx>( tcx: TyCtxt<'tcx>, transform: &TransformVisitor<'tcx>, diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 03fdf9fbac538..d07e020cee766 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -92,6 +92,11 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { InliningThreshold::Never => return false, }; + // Avoid inlining coroutines, since that does not make any sense. + if tcx.is_coroutine(def_id.to_def_id()) { + return false; + } + let mir = tcx.optimized_mir(def_id); let mut checker = CostChecker { tcx, callee_body: mir, calls: 0, statements: 0, landing_pads: 0, resumes: 0 }; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index fe53de31f7583..7a8acb66003c2 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -46,6 +46,12 @@ impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp { return; } + // Avoid computing layout inside coroutines, since their `optimized_mir` is used for layout + // computation, which can create a cycle. + if body.coroutine.is_some() { + return; + } + // We want to have a somewhat linear runtime w.r.t. the number of statements/terminators. // Let's call this number `n`. Dataflow analysis has `O(h*n)` transfer function // applications, where `h` is the height of the lattice. Because the height of our lattice @@ -241,9 +247,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { TerminatorKind::Drop { place, .. } => { state.flood_with(place.as_ref(), &self.map, FlatSet::::BOTTOM); } - TerminatorKind::Yield { .. } => { - // They would have an effect, but are not allowed in this phase. - bug!("encountered disallowed terminator"); + TerminatorKind::Yield { resume_arg, .. } => { + state.flood_with(resume_arg.as_ref(), &self.map, FlatSet::::BOTTOM); } TerminatorKind::SwitchInt { discr, targets } => { return self.handle_switch_int(discr, targets, state); diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 4c94a6c524e00..de6f7a9208a5f 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -639,6 +639,10 @@ impl WriteInfo { self.add_operand(&arg.node); } } + TerminatorKind::Yield { resume_arg, value, .. } => { + self.add_place(*resume_arg); + self.add_operand(value); + } TerminatorKind::InlineAsm { operands, .. } => { for asm_operand in operands { match asm_operand { @@ -669,14 +673,12 @@ impl WriteInfo { | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return + | TerminatorKind::CoroutineDrop | TerminatorKind::Unreachable { .. } => (), TerminatorKind::Drop { .. } => { // `Drop`s create a `&mut` and so are not considered } - TerminatorKind::Yield { .. } - | TerminatorKind::CoroutineDrop - | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } => { + TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => { bug!("{:?} not found in this MIR phase", terminator) } } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 952da2cdf7253..1be2c10913b7c 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1767,14 +1767,18 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> { } fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { - if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator { - if let Some(local) = destination.as_local() - && self.ssa.is_ssa(local) - { - let ty = self.local_decls[local].ty; - let opaque = self.new_opaque(ty); - self.assign(local, opaque); - } + let destination = match terminator.kind { + TerminatorKind::Call { destination, .. } => Some(destination), + TerminatorKind::Yield { resume_arg, .. } => Some(resume_arg), + _ => None, + }; + if let Some(destination) = destination + && let Some(local) = destination.as_local() + && self.ssa.is_ssa(local) + { + let ty = self.local_decls[local].ty; + let opaque = self.new_opaque(ty); + self.assign(local, opaque); } // Function calls and ASM may invalidate (nested) derefs. We must handle them carefully. // Currently, only preserving derefs for trivial terminators like SwitchInt and Goto. diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 3d49eb4e8ef75..0388652eb3476 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -349,14 +349,7 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> { } } - fn check_caller_mir_body(&self, body: &Body<'tcx>) -> bool { - // Avoid inlining into coroutines, 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.coroutine.is_some() { - return false; - } - + fn check_caller_mir_body(&self, _: &Body<'tcx>) -> bool { true } @@ -709,6 +702,11 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( return Err("self-recursion"); } + // Avoid inlining coroutines, since that does not make any sense. + if inliner.tcx().is_coroutine(callee_def_id) { + return Err("coroutine"); + } + match callee.def { InstanceKind::Item(_) => { // If there is no MIR available (either because it was not in metadata or diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 7f9234d1dc891..f886af0fd6301 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -94,6 +94,15 @@ fn process<'tcx>( continue; } + // Avoid inlining into coroutines, 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 tcx.is_coroutine(callee.def_id()) { + reaches_root = true; + seen.insert(callee, true); + continue; + } + if tcx.is_constructor(callee.def_id()) { trace!("constructors always have MIR"); // Constructor functions cannot cause a query cycle. diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index f9e642e28ebd7..0aeb77121cc2d 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -612,9 +612,9 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { | TerminatorKind::Unreachable | TerminatorKind::CoroutineDrop => bug!("{term:?} has no terminators"), // Disallowed during optimizations. - TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::Yield { .. } => bug!("{term:?} invalid"), + TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => { + bug!("{term:?} invalid") + } // Cannot reason about inline asm. TerminatorKind::InlineAsm { .. } => return, // `SwitchInt` is handled specially. @@ -623,6 +623,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { TerminatorKind::Goto { .. } => None, // Flood the overwritten place, and progress through. TerminatorKind::Drop { place: destination, .. } + | TerminatorKind::Yield { resume_arg: destination, .. } | TerminatorKind::Call { destination, .. } => Some(destination), // Ignore, as this can be a no-op at codegen time. TerminatorKind::Assert { .. } => None, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 08f25276cecc1..8af4dc2b4b40b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -616,7 +616,6 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Otherwise it should run fairly late, but before optimizations begin. &add_retag::AddRetag, &elaborate_box_derefs::ElaborateBoxDerefs, - &coroutine::StateTransform, &Lint(known_panics_lint::KnownPanicsLint), ]; pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial))); @@ -722,6 +721,7 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<' &simplify::SimplifyLocals::Final, &multiple_return_terminators::MultipleReturnTerminators, &large_enums::EnumSizeOpt { discrepancy: 128 }, + &coroutine::StateTransform, // Some cleanup necessary at least for LLVM and potentially other codegen backends. &add_call_guards::CriticalCallEdges, // Cleanup for human readability, off by default. diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index c6760b3583f20..82b9e9788a217 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -149,7 +149,6 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< tcx, &mut body, &[ - &mentioned_items::MentionedItems, &abort_unwinding_calls::AbortUnwindingCalls, &add_call_guards::CriticalCallEdges, ], diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 18d09473c191e..0c679e1063055 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -216,6 +216,7 @@ fn build_adrop_for_coroutine_shim<'tcx>( body.source.instance = instance; body.phase = MirPhase::Runtime(RuntimePhase::Initial); body.var_debug_info.clear(); + body.mentioned_items = None; let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let args = tcx.mk_args(&[proxy_ref.into()]); let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args); diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index cd9a7f4a39dfe..e7acdf42f2a4c 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -228,6 +228,11 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_, 'tcx> { match ctxt { PlaceContext::MutatingUse(MutatingUseContext::Projection) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(), + // Count drops as moves. + PlaceContext::MutatingUse(MutatingUseContext::Drop) => { + self.check_dominates(local, loc); + self.direct_uses[local] += 1; + } // Anything can happen with raw pointers, so remove them. PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) | PlaceContext::MutatingUse(_) => { diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 99e4782e4700c..c4f5f74c70964 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -450,7 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { if self.body.coroutine.is_none() { self.fail(location, "`Yield` cannot appear outside coroutine bodies"); } - if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Optimized) { self.fail(location, "`Yield` should have been replaced by coroutine lowering"); } self.check_edge(location, *resume, EdgeKind::Normal); @@ -488,7 +488,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { if self.body.coroutine.is_none() { self.fail(location, "`CoroutineDrop` cannot appear outside coroutine bodies"); } - if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Optimized) { self.fail( location, "`CoroutineDrop` should have been replaced by coroutine lowering", diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir index 347e4119cd0e0..10b674edad48f 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir @@ -10,16 +10,16 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _6: std::pin::Pin<&mut T>; let mut _7: &mut T; let mut _8: *mut T; - let mut _9: (); - let mut _10: std::task::Poll<()>; - let mut _11: &mut std::task::Context<'_>; - let mut _12: &mut impl std::future::Future; - let mut _13: std::pin::Pin<&mut impl std::future::Future>; - let mut _14: isize; - let mut _15: &mut std::task::Context<'_>; - let mut _16: &mut impl std::future::Future; - let mut _17: std::pin::Pin<&mut impl std::future::Future>; - let mut _18: isize; + let mut _9: std::task::Poll<()>; + let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut impl std::future::Future>; + let mut _13: isize; + let mut _14: &mut std::task::Context<'_>; + let mut _15: &mut impl std::future::Future; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: isize; + let mut _18: (); let mut _19: &mut std::task::Context<'_>; let mut _20: u32; scope 1 { @@ -28,72 +28,68 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb0: { _20 = discriminant((*(_1.0: &mut {async fn body of a()}))); - switchInt(move _20) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14]; + switchInt(move _20) -> [0: bb8, 3: bb11, 4: bb12, otherwise: bb13]; } bb1: { nop; nop; - goto -> bb2; - } - - bb2: { _0 = Poll::<()>::Ready(const ()); return; } - bb3: { + bb2: { _0 = Poll::<()>::Pending; discriminant((*(_1.0: &mut {async fn body of a()}))) = 4; return; } + bb3: { + StorageLive(_16); + _15 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); + _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb6, unwind unreachable]; + } + bb4: { - StorageLive(_17); - _16 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); - _17 = Pin::<&mut impl Future>::new_unchecked(move _16) -> [return: bb7, unwind unreachable]; + unreachable; } bb5: { - unreachable; + StorageDead(_16); + _17 = discriminant(_9); + switchInt(move _17) -> [0: bb1, 1: bb2, otherwise: bb4]; } bb6: { - StorageDead(_17); - _18 = discriminant(_10); - switchInt(move _18) -> [0: bb1, 1: bb3, otherwise: bb5]; + _9 = as Future>::poll(move _16, move _14) -> [return: bb5, unwind unreachable]; } bb7: { - _10 = as Future>::poll(move _17, move _15) -> [return: bb6, unwind unreachable]; + _0 = Poll::<()>::Ready(const ()); + return; } bb8: { - _0 = Poll::<()>::Ready(const ()); - return; + goto -> bb10; } bb9: { - goto -> bb11; + goto -> bb7; } bb10: { - goto -> bb8; + drop(((*(_1.0: &mut {async fn body of a()})).0: T)) -> [return: bb9, unwind unreachable]; } bb11: { - drop(((*(_1.0: &mut {async fn body of a()})).0: T)) -> [return: bb10, unwind unreachable]; + goto -> bb3; } bb12: { - goto -> bb4; + goto -> bb3; } bb13: { - goto -> bb4; - } - - bb14: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir index b1cf5373f9191..ec6c4399c6fbf 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir @@ -10,16 +10,16 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _6: std::pin::Pin<&mut T>; let mut _7: &mut T; let mut _8: *mut T; - let mut _9: (); - let mut _10: std::task::Poll<()>; - let mut _11: &mut std::task::Context<'_>; - let mut _12: &mut impl std::future::Future; - let mut _13: std::pin::Pin<&mut impl std::future::Future>; - let mut _14: isize; - let mut _15: &mut std::task::Context<'_>; - let mut _16: &mut impl std::future::Future; - let mut _17: std::pin::Pin<&mut impl std::future::Future>; - let mut _18: isize; + let mut _9: std::task::Poll<()>; + let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut impl std::future::Future>; + let mut _13: isize; + let mut _14: &mut std::task::Context<'_>; + let mut _15: &mut impl std::future::Future; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: isize; + let mut _18: (); let mut _19: &mut std::task::Context<'_>; let mut _20: u32; scope 1 { @@ -28,95 +28,81 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) bb0: { _20 = discriminant((*(_1.0: &mut {async fn body of a()}))); - switchInt(move _20) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19]; + switchInt(move _20) -> [0: bb8, 2: bb15, 3: bb13, 4: bb14, otherwise: bb16]; } bb1: { nop; nop; - goto -> bb2; + _0 = Poll::<()>::Ready(const ()); + return; } bb2: { - _0 = Poll::<()>::Ready(const ()); + _0 = Poll::<()>::Pending; + discriminant((*(_1.0: &mut {async fn body of a()}))) = 4; return; } - bb3 (cleanup): { - nop; - nop; - goto -> bb5; + bb3: { + StorageLive(_16); + _15 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); + _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb6, unwind: bb12]; } - bb4 (cleanup): { - goto -> bb15; + bb4: { + unreachable; } - bb5 (cleanup): { - goto -> bb4; + bb5: { + StorageDead(_16); + _17 = discriminant(_9); + switchInt(move _17) -> [0: bb1, 1: bb2, otherwise: bb4]; } bb6: { - _0 = Poll::<()>::Pending; - discriminant((*(_1.0: &mut {async fn body of a()}))) = 4; - return; + _9 = as Future>::poll(move _16, move _14) -> [return: bb5, unwind: bb12]; } bb7: { - StorageLive(_17); - _16 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); - _17 = Pin::<&mut impl Future>::new_unchecked(move _16) -> [return: bb10, unwind: bb15]; + _0 = Poll::<()>::Ready(const ()); + return; } bb8: { - unreachable; + goto -> bb11; } - bb9: { - StorageDead(_17); - _18 = discriminant(_10); - switchInt(move _18) -> [0: bb1, 1: bb6, otherwise: bb8]; + bb9 (cleanup): { + goto -> bb12; } bb10: { - _10 = as Future>::poll(move _17, move _15) -> [return: bb9, unwind: bb3]; + goto -> bb7; } bb11: { - _0 = Poll::<()>::Ready(const ()); - return; + drop(((*(_1.0: &mut {async fn body of a()})).0: T)) -> [return: bb10, unwind: bb9]; } - bb12: { - goto -> bb14; + bb12 (cleanup): { + discriminant((*(_1.0: &mut {async fn body of a()}))) = 2; + resume; } bb13: { - goto -> bb11; + goto -> bb3; } bb14: { - drop(((*(_1.0: &mut {async fn body of a()})).0: T)) -> [return: bb13, unwind: bb4]; + goto -> bb3; } - bb15 (cleanup): { - discriminant((*(_1.0: &mut {async fn body of a()}))) = 2; - resume; + bb15: { + assert(const false, "`async fn` resumed after panicking") -> [success: bb15, unwind continue]; } bb16: { - goto -> bb7; - } - - bb17: { - goto -> bb7; - } - - bb18: { - assert(const false, "`async fn` resumed after panicking") -> [success: bb18, unwind continue]; - } - - bb19: { _0 = Poll::<()>::Ready(const ()); return; } diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir index 9bff257e06392..64c846018409b 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -104,7 +104,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb0: { _39 = discriminant((*(_1.0: &mut {async fn body of b()}))); - switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8]; + switchInt(move _39) -> [0: bb1, 1: bb27, 3: bb25, 4: bb26, otherwise: bb8]; } bb1: { @@ -121,7 +121,6 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb3: { StorageDead(_5); - PlaceMention(_4); nop; (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}) = move _4; goto -> bb4; @@ -157,7 +156,6 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb7: { StorageDead(_13); StorageDead(_10); - PlaceMention(_9); _16 = discriminant(_9); switchInt(move _16) -> [0: bb10, 1: bb9, otherwise: bb8]; } @@ -206,30 +204,25 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb12: { nop; - goto -> bb13; - } - - bb13: { StorageDead(_4); StorageDead(_3); StorageLive(_21); StorageLive(_22); - _22 = a() -> [return: bb14, unwind unreachable]; + _22 = a() -> [return: bb13, unwind unreachable]; } - bb14: { - _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; + bb13: { + _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb14, unwind unreachable]; } - bb15: { + bb14: { StorageDead(_22); - PlaceMention(_21); nop; (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}) = move _21; - goto -> bb16; + goto -> bb15; } - bb16: { + bb15: { StorageLive(_24); StorageLive(_25); StorageLive(_26); @@ -237,34 +230,33 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageLive(_28); _28 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}); _27 = &mut (*_28); - _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; + _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb16, unwind unreachable]; } - bb17: { + bb16: { StorageDead(_27); StorageLive(_29); StorageLive(_30); StorageLive(_31); _31 = copy _38; _30 = move _31; - goto -> bb18; + goto -> bb17; } - bb18: { + bb17: { _29 = &mut (*_30); StorageDead(_31); - _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; + _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb18, unwind unreachable]; } - bb19: { + bb18: { StorageDead(_29); StorageDead(_26); - PlaceMention(_25); _32 = discriminant(_25); - switchInt(move _32) -> [0: bb21, 1: bb20, otherwise: bb8]; + switchInt(move _32) -> [0: bb20, 1: bb19, otherwise: bb8]; } - bb20: { + bb19: { _24 = const (); StorageDead(_30); StorageDead(_28); @@ -281,7 +273,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> return; } - bb21: { + bb20: { StorageLive(_33); _33 = copy ((_25 as Ready).0: ()); _37 = copy _33; @@ -290,38 +282,34 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageDead(_28); StorageDead(_25); StorageDead(_24); - drop((((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()})) -> [return: bb23, unwind unreachable]; + drop((((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()})) -> [return: bb22, unwind unreachable]; } - bb22: { + bb21: { StorageDead(_36); _38 = move _35; StorageDead(_35); _7 = const (); - goto -> bb16; + goto -> bb15; } - bb23: { + bb22: { nop; - goto -> bb24; - } - - bb24: { StorageDead(_21); - goto -> bb26; + goto -> bb24; } - bb25: { + bb23: { _0 = Poll::<()>::Ready(move _37); discriminant((*(_1.0: &mut {async fn body of b()}))) = 1; return; } - bb26: { - goto -> bb25; + bb24: { + goto -> bb23; } - bb27: { + bb25: { StorageLive(_3); StorageLive(_4); StorageLive(_19); @@ -330,15 +318,15 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> goto -> bb11; } - bb28: { + bb26: { StorageLive(_21); StorageLive(_35); StorageLive(_36); _35 = move _2; - goto -> bb22; + goto -> bb21; } - bb29: { - assert(const false, "`async fn` resumed after completion") -> [success: bb29, unwind unreachable]; + bb27: { + assert(const false, "`async fn` resumed after completion") -> [success: bb27, unwind unreachable]; } } diff --git a/tests/mir-opt/building/async_await.rs b/tests/mir-opt/building/async_await.rs index 6c44570d109c2..b909553258861 100644 --- a/tests/mir-opt/building/async_await.rs +++ b/tests/mir-opt/building/async_await.rs @@ -4,7 +4,7 @@ // related to `yield` are `&mut Context`, and its return type is `Poll`. //@ edition:2018 -//@ compile-flags: -C panic=abort +//@ compile-flags: -C panic=abort -Z mir-opt-level=0 #![crate_type = "lib"] diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff index f43c0cca9ad28..6f33229ce7a27 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff @@ -30,16 +30,21 @@ } bb1: { - StorageLive(_7); +- StorageLive(_7); ++ nop; _7 = ShallowInitBox(move _6, i32); _8 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); (*_8) = const 42_i32; - _3 = move _7; - StorageDead(_7); - _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_9); +- _3 = move _7; +- StorageDead(_7); +- _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- _2 = copy (*_9); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); ++ _3 = copy _7; ++ nop; ++ _9 = copy _8; ++ _2 = copy (*_8); + _1 = copy _2; + nop; drop(_3) -> [return: bb2, unwind unreachable]; diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff index 2c903b6d85349..008f3d96962f9 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff @@ -30,16 +30,21 @@ } bb1: { - StorageLive(_7); +- StorageLive(_7); ++ nop; _7 = ShallowInitBox(move _6, i32); _8 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); (*_8) = const 42_i32; - _3 = move _7; - StorageDead(_7); - _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_9); +- _3 = move _7; +- StorageDead(_7); +- _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- _2 = copy (*_9); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); ++ _3 = copy _7; ++ nop; ++ _9 = copy _8; ++ _2 = copy (*_8); + _1 = copy _2; + nop; drop(_3) -> [return: bb2, unwind: bb3]; diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir index 7e033916fd348..58f33cdb57996 100644 --- a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir +++ b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir @@ -7,19 +7,17 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12 let _4: (); let mut _5: (); let mut _6: (); - let mut _7: (); - let mut _8: u32; + let mut _7: u32; scope 1 { debug _s => (((*_1) as variant#3).0: std::string::String); } bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb5, 3: bb8, otherwise: bb9]; + _7 = discriminant((*_1)); + switchInt(move _7) -> [0: bb5, 3: bb8, otherwise: bb9]; } bb1: { - StorageDead(_5); StorageDead(_4); drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind unreachable]; } @@ -51,7 +49,6 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12 bb8: { StorageLive(_4); - StorageLive(_5); goto -> bb1; } diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir index 613ef2909b5e4..99fe1e3460d87 100644 --- a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir +++ b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir @@ -7,19 +7,17 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12 let _4: (); let mut _5: (); let mut _6: (); - let mut _7: (); - let mut _8: u32; + let mut _7: u32; scope 1 { debug _s => (((*_1) as variant#3).0: std::string::String); } bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb7, 3: bb10, otherwise: bb11]; + _7 = discriminant((*_1)); + switchInt(move _7) -> [0: bb7, 3: bb10, otherwise: bb11]; } bb1: { - StorageDead(_5); StorageDead(_4); drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; } @@ -60,7 +58,6 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12 bb10: { StorageLive(_4); - StorageLive(_5); goto -> bb1; } diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir index 4731aed335d9f..1f389761317f6 100644 --- a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir +++ b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir @@ -6,11 +6,9 @@ yields () let mut _0: (); let _3: Foo; let _5: (); - let mut _6: (); - let _7: (); - let mut _8: Foo; - let _9: (); - let mut _10: Bar; + let _6: (); + let mut _7: Foo; + let _8: (); scope 1 { debug a => _3; let _4: Bar; @@ -22,62 +20,48 @@ yields () bb0: { StorageLive(_3); _3 = Foo(const 5_i32); - StorageLive(_4); _4 = Bar(const 6_i32); StorageLive(_5); - StorageLive(_6); - _6 = (); - _5 = yield(move _6) -> [resume: bb1, drop: bb6]; + _5 = yield(const ()) -> [resume: bb1, drop: bb5]; } bb1: { - StorageDead(_6); StorageDead(_5); + StorageLive(_6); StorageLive(_7); - StorageLive(_8); - _8 = move _3; - _7 = take::(move _8) -> [return: bb2, unwind unreachable]; + _7 = move _3; + _6 = take::(move _7) -> [return: bb2, unwind unreachable]; } bb2: { - StorageDead(_8); StorageDead(_7); - StorageLive(_9); - StorageLive(_10); - _10 = move _4; - _9 = take::(move _10) -> [return: bb3, unwind unreachable]; + StorageDead(_6); + StorageLive(_8); + _8 = take::(move _4) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_10); - StorageDead(_9); + StorageDead(_8); _0 = const (); - StorageDead(_4); - goto -> bb4; - } - - bb4: { StorageDead(_3); - drop(_1) -> [return: bb5, unwind unreachable]; + drop(_1) -> [return: bb4, unwind unreachable]; } - bb5: { + bb4: { return; } - bb6: { - StorageDead(_6); + bb5: { StorageDead(_5); - StorageDead(_4); - drop(_3) -> [return: bb7, unwind unreachable]; + drop(_3) -> [return: bb6, unwind unreachable]; } - bb7: { + bb6: { StorageDead(_3); - drop(_1) -> [return: bb8, unwind unreachable]; + drop(_1) -> [return: bb7, unwind unreachable]; } - bb8: { + bb7: { coroutine_drop; } } diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir index 14e1782b86016..a77a9c9a96341 100644 --- a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir +++ b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir @@ -6,11 +6,9 @@ yields () let mut _0: (); let _3: Foo; let _5: (); - let mut _6: (); - let _7: (); - let mut _8: Foo; - let _9: (); - let mut _10: Bar; + let _6: (); + let mut _7: Foo; + let _8: (); scope 1 { debug a => _3; let _4: Bar; @@ -22,97 +20,73 @@ yields () bb0: { StorageLive(_3); _3 = Foo(const 5_i32); - StorageLive(_4); _4 = Bar(const 6_i32); StorageLive(_5); - StorageLive(_6); - _6 = (); - _5 = yield(move _6) -> [resume: bb1, drop: bb6]; + _5 = yield(const ()) -> [resume: bb1, drop: bb5]; } bb1: { - StorageDead(_6); StorageDead(_5); + StorageLive(_6); StorageLive(_7); - StorageLive(_8); - _8 = move _3; - _7 = take::(move _8) -> [return: bb2, unwind: bb10]; + _7 = move _3; + _6 = take::(move _7) -> [return: bb2, unwind: bb9]; } bb2: { - StorageDead(_8); StorageDead(_7); - StorageLive(_9); - StorageLive(_10); - _10 = move _4; - _9 = take::(move _10) -> [return: bb3, unwind: bb9]; + StorageDead(_6); + StorageLive(_8); + _8 = take::(move _4) -> [return: bb3, unwind: bb8]; } bb3: { - StorageDead(_10); - StorageDead(_9); + StorageDead(_8); _0 = const (); - StorageDead(_4); - goto -> bb4; - } - - bb4: { StorageDead(_3); - drop(_1) -> [return: bb5, unwind: bb14]; + drop(_1) -> [return: bb4, unwind continue]; } - bb5: { + bb4: { return; } - bb6: { - StorageDead(_6); + bb5: { StorageDead(_5); - StorageDead(_4); - drop(_3) -> [return: bb7, unwind: bb15]; + drop(_3) -> [return: bb6, unwind: bb12]; } - bb7: { + bb6: { StorageDead(_3); - drop(_1) -> [return: bb8, unwind: bb14]; + drop(_1) -> [return: bb7, unwind continue]; } - bb8: { + bb7: { coroutine_drop; } - bb9 (cleanup): { - StorageDead(_10); - StorageDead(_9); - goto -> bb12; - } - - bb10 (cleanup): { - goto -> bb11; - } - - bb11 (cleanup): { + bb8 (cleanup): { StorageDead(_8); - StorageDead(_7); - goto -> bb12; + goto -> bb10; } - bb12 (cleanup): { - StorageDead(_4); - goto -> bb13; + bb9 (cleanup): { + StorageDead(_7); + StorageDead(_6); + goto -> bb10; } - bb13 (cleanup): { + bb10 (cleanup): { StorageDead(_3); - drop(_1) -> [return: bb14, unwind terminate(cleanup)]; + drop(_1) -> [return: bb11, unwind terminate(cleanup)]; } - bb14 (cleanup): { + bb11 (cleanup): { resume; } - bb15 (cleanup): { + bb12 (cleanup): { StorageDead(_3); - drop(_1) -> [return: bb14, unwind terminate(cleanup)]; + drop(_1) -> [return: bb11, unwind terminate(cleanup)]; } } diff --git a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir index f8b3f68d21e63..8e4d1aaaae83e 100644 --- a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir @@ -22,64 +22,52 @@ } */ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}>, _2: u8) -> CoroutineState<(), ()> { - debug _x => _10; + debug _x => _7; let mut _0: std::ops::CoroutineState<(), ()>; let _3: HasDrop; - let mut _4: !; - let mut _5: (); - let _6: u8; - let mut _7: (); - let _8: (); - let mut _9: (); - let _10: u8; - let mut _11: u32; + let _4: u8; + let _5: (); + let mut _6: (); + let _7: u8; + let mut _8: u32; scope 1 { debug _d => (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop); } bb0: { - _11 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))); - switchInt(move _11) -> [0: bb1, 3: bb5, otherwise: bb6]; + _8 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))); + switchInt(move _8) -> [0: bb1, 3: bb5, otherwise: bb6]; } bb1: { - _10 = move _2; + _7 = move _2; nop; - (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop) = HasDrop; - StorageLive(_4); + (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop) = const HasDrop; goto -> bb2; } bb2: { - StorageLive(_6); - StorageLive(_7); - _7 = (); - _0 = CoroutineState::<(), ()>::Yielded(move _7); + StorageLive(_4); + _0 = CoroutineState::<(), ()>::Yielded(const ()); StorageDead(_4); - StorageDead(_6); - StorageDead(_7); discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))) = 3; return; } bb3: { - StorageDead(_7); - StorageDead(_6); - StorageLive(_8); - _8 = callee() -> [return: bb4, unwind unreachable]; + StorageDead(_4); + StorageLive(_5); + _5 = callee() -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_8); - _5 = const (); + StorageDead(_5); goto -> bb2; } bb5: { StorageLive(_4); - StorageLive(_6); - StorageLive(_7); - _6 = move _2; + _4 = move _2; goto -> bb3; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 25ffff619e60b..be32d4676febb 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -70,7 +70,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; StorageLive(_11); StorageLive(_12); StorageLive(_13); @@ -88,7 +89,8 @@ } bb1: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } @@ -121,8 +123,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -139,7 +142,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff index b2085afb71379..26a0238518709 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff @@ -36,7 +36,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } @@ -46,8 +47,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -64,7 +66,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); @@ -74,7 +76,8 @@ } bb2: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 839b53e3b0b3b..e04e3e8483580 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -70,7 +70,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; StorageLive(_11); StorageLive(_12); StorageLive(_13); @@ -88,7 +89,8 @@ } bb1: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } @@ -121,8 +123,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -139,7 +142,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff index b2085afb71379..26a0238518709 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff @@ -36,7 +36,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } @@ -46,8 +47,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -64,7 +66,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); @@ -74,7 +76,8 @@ } bb2: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff index 151580da19e09..716e86cd15359 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff @@ -19,10 +19,14 @@ + } + } + scope 5 (inlined g::{closure#0}) { -+ debug a => _5; ++ debug a => _8; + let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _7: u32; -+ let mut _8: i32; ++ let _8: bool; ++ let mut _9: i32; ++ let mut _10: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; ++ let mut _11: bool; ++ let mut _12: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + } bb0: { @@ -39,7 +43,11 @@ + _5 = const false; + StorageLive(_6); + StorageLive(_7); -+ _6 = copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); ++ StorageLive(_8); ++ StorageLive(_10); ++ StorageLive(_11); ++ StorageLive(_12); ++ _6 = deref_copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); + _7 = discriminant((*_6)); + switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9]; } @@ -56,6 +64,10 @@ bb2: { - StorageDead(_3); - _1 = <{coroutine@$DIR/inline_coroutine.rs:20:5: 20:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind unreachable]; ++ StorageDead(_12); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_8); + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); @@ -66,8 +78,9 @@ bb3: { - StorageDead(_2); - drop(_4) -> [return: bb4, unwind unreachable]; -+ StorageLive(_8); -+ switchInt(copy _5) -> [0: bb4, otherwise: bb5]; ++ _8 = move _5; ++ StorageLive(_9); ++ switchInt(copy _8) -> [0: bb4, otherwise: bb5]; } bb4: { @@ -75,19 +88,20 @@ - _0 = const (); - StorageDead(_1); - return; -+ _8 = const 13_i32; ++ _9 = const 13_i32; + goto -> bb6; + } + + bb5: { -+ _8 = const 7_i32; ++ _9 = const 7_i32; + goto -> bb6; + } + + bb6: { -+ _1 = CoroutineState::::Yielded(move _8); -+ StorageDead(_8); -+ discriminant((*_6)) = 3; ++ _1 = CoroutineState::::Yielded(move _9); ++ StorageDead(_9); ++ _10 = deref_copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); ++ discriminant((*_10)) = 3; + goto -> bb2; + } + @@ -96,10 +110,12 @@ + } + + bb8: { -+ StorageLive(_8); -+ StorageDead(_8); -+ _1 = CoroutineState::::Complete(copy _5); -+ discriminant((*_6)) = 1; ++ StorageLive(_9); ++ _11 = move _5; ++ StorageDead(_9); ++ _1 = CoroutineState::::Complete(move _11); ++ _12 = deref_copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); ++ discriminant((*_12)) = 1; + goto -> bb2; + } + diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff index 6196fc0d0c6bf..742b3ad3e5f73 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff @@ -19,10 +19,14 @@ + } + } + scope 5 (inlined g::{closure#0}) { -+ debug a => _5; ++ debug a => _8; + let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _7: u32; -+ let mut _8: i32; ++ let _8: bool; ++ let mut _9: i32; ++ let mut _10: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; ++ let mut _11: bool; ++ let mut _12: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + } bb0: { @@ -39,7 +43,11 @@ + _5 = const false; + StorageLive(_6); + StorageLive(_7); -+ _6 = copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); ++ StorageLive(_8); ++ StorageLive(_10); ++ StorageLive(_11); ++ StorageLive(_12); ++ _6 = deref_copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); + _7 = discriminant((*_6)); + switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11]; } @@ -72,6 +80,10 @@ - _0 = const (); - StorageDead(_1); - return; ++ StorageDead(_12); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_8); + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); @@ -82,26 +94,28 @@ - bb5 (cleanup): { - drop(_4) -> [return: bb6, unwind terminate(cleanup)]; + bb5: { -+ StorageLive(_8); -+ switchInt(copy _5) -> [0: bb6, otherwise: bb7]; ++ _8 = move _5; ++ StorageLive(_9); ++ switchInt(copy _8) -> [0: bb6, otherwise: bb7]; } - bb6 (cleanup): { - resume; + bb6: { -+ _8 = const 13_i32; ++ _9 = const 13_i32; + goto -> bb8; + } + + bb7: { -+ _8 = const 7_i32; ++ _9 = const 7_i32; + goto -> bb8; + } + + bb8: { -+ _1 = CoroutineState::::Yielded(move _8); -+ StorageDead(_8); -+ discriminant((*_6)) = 3; ++ _1 = CoroutineState::::Yielded(move _9); ++ StorageDead(_9); ++ _10 = deref_copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); ++ discriminant((*_10)) = 3; + goto -> bb4; + } + @@ -110,10 +124,12 @@ + } + + bb10: { -+ StorageLive(_8); -+ StorageDead(_8); -+ _1 = CoroutineState::::Complete(copy _5); -+ discriminant((*_6)) = 1; ++ StorageLive(_9); ++ _11 = move _5; ++ StorageDead(_9); ++ _1 = CoroutineState::::Complete(move _11); ++ _12 = deref_copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); ++ discriminant((*_12)) = 1; + goto -> bb4; + } + diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff index c33e0810739f2..b37236944320b 100644 --- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff @@ -5,14 +5,13 @@ let mut _0: (); let _1: (!, !); + let mut _2: fn() -> ! {sleep}; ++ let mut _7: (); + let mut _8: (); -+ let mut _9: (); + scope 1 (inlined call_twice:: ! {sleep}>) { + debug f => _2; + let mut _3: &fn() -> ! {sleep}; + let _4: !; + let mut _5: &fn() -> ! {sleep}; -+ let mut _7: !; + scope 2 { + debug a => _4; + let _6: !; @@ -35,12 +34,12 @@ - _1 = call_twice:: ! {sleep}>(sleep) -> unwind continue; + StorageLive(_2); + _2 = sleep; -+ StorageLive(_6); + StorageLive(_4); ++ StorageLive(_6); + StorageLive(_3); + _3 = &_2; -+ StorageLive(_8); -+ _8 = const (); ++ StorageLive(_7); ++ _7 = const (); + goto -> bb1; + } + diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout index 642e27b2a57d6..4e721b3b0d995 100644 --- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout +++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout @@ -1,35 +1,32 @@ -print-type-size type: `{async fn body of test()}`: 3078 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of test()}`: 3079 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes -print-type-size variant `Suspend0`: 3077 bytes -print-type-size local `.__awaitee`: 3077 bytes, type: {async fn body of calls_fut<{async fn body of big_fut()}>()} +print-type-size variant `Suspend0`: 3078 bytes +print-type-size local `.__awaitee`: 3078 bytes, type: {async fn body of calls_fut<{async fn body of big_fut()}>()} print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes -print-type-size field `.value`: 3077 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes -print-type-size variant `MaybeUninit`: 3077 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3078 bytes, alignment: 1 bytes +print-type-size field `.value`: 3078 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3078 bytes, alignment: 1 bytes +print-type-size variant `MaybeUninit`: 3078 bytes print-type-size field `.uninit`: 0 bytes -print-type-size field `.value`: 3077 bytes -print-type-size type: `{async fn body of calls_fut<{async fn body of big_fut()}>()}`: 3077 bytes, alignment: 1 bytes +print-type-size field `.value`: 3078 bytes +print-type-size type: `{async fn body of calls_fut<{async fn body of big_fut()}>()}`: 3078 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes -print-type-size variant `Suspend0`: 2052 bytes +print-type-size variant `Suspend0`: 3077 bytes print-type-size upvar `.fut`: 1025 bytes print-type-size local `.fut`: 1025 bytes -print-type-size local `..coroutine_field4`: 1 bytes, type: bool print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()} -print-type-size variant `Suspend1`: 3076 bytes +print-type-size padding: 1025 bytes +print-type-size local `..coroutine_field3`: 1 bytes, alignment: 1 bytes, type: bool +print-type-size variant `Suspend1`: 3077 bytes print-type-size upvar `.fut`: 1025 bytes print-type-size padding: 1025 bytes -print-type-size local `..coroutine_field4`: 1 bytes, alignment: 1 bytes, type: bool +print-type-size local `.__awaitee`: 1 bytes, alignment: 1 bytes, type: {async fn body of wait()} print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body of big_fut()} -print-type-size variant `Suspend2`: 2052 bytes -print-type-size upvar `.fut`: 1025 bytes -print-type-size local `.fut`: 1025 bytes -print-type-size local `..coroutine_field4`: 1 bytes, type: bool -print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()} +print-type-size local `..coroutine_field3`: 1 bytes, type: bool print-type-size variant `Returned`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes print-type-size variant `Panicked`: 1025 bytes diff --git a/tests/ui/coroutine/size-moved-locals.rs b/tests/ui/coroutine/size-moved-locals.rs index 0f800de84544d..30ff74534c3c3 100644 --- a/tests/ui/coroutine/size-moved-locals.rs +++ b/tests/ui/coroutine/size-moved-locals.rs @@ -76,5 +76,5 @@ fn main() { assert_eq!(1025, std::mem::size_of_val(&move_before_yield())); assert_eq!(1026, std::mem::size_of_val(&move_before_yield_with_noop())); assert_eq!(2051, std::mem::size_of_val(&overlap_move_points())); - assert_eq!(1026, std::mem::size_of_val(&overlap_x_and_y())); + assert_eq!(2050, std::mem::size_of_val(&overlap_x_and_y())); } diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout index 4ce1ce46f6e82..30a9df6f20948 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout @@ -1,17 +1,7 @@ -print-type-size type: `{coroutine@$DIR/coroutine_discr_placement.rs:13:5: 13:7}`: 8 bytes, alignment: 4 bytes +print-type-size type: `{coroutine@$DIR/coroutine_discr_placement.rs:13:5: 13:7}`: 1 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes -print-type-size variant `Suspend0`: 7 bytes -print-type-size padding: 3 bytes -print-type-size local `.w`: 4 bytes, alignment: 4 bytes -print-type-size variant `Suspend1`: 7 bytes -print-type-size padding: 3 bytes -print-type-size local `.z`: 4 bytes, alignment: 4 bytes +print-type-size variant `Suspend0`: 0 bytes +print-type-size variant `Suspend1`: 0 bytes print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes -print-type-size type: `std::mem::ManuallyDrop`: 4 bytes, alignment: 4 bytes -print-type-size field `.value`: 4 bytes -print-type-size type: `std::mem::MaybeUninit`: 4 bytes, alignment: 4 bytes -print-type-size variant `MaybeUninit`: 4 bytes -print-type-size field `.uninit`: 0 bytes -print-type-size field `.value`: 4 bytes