From 016a2e30a950b52ddf9da2d5f679bbc038b4be00 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 16:29:30 +1000 Subject: [PATCH 01/13] Remove unused features. --- compiler/rustc_mir_transform/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 88094b44edf21..cd24b4437ad16 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -3,13 +3,11 @@ #![feature(box_patterns)] #![feature(const_type_name)] #![feature(cow_is_borrowed)] -#![feature(decl_macro)] #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(let_chains)] #![feature(map_try_insert)] #![feature(never_type)] -#![feature(option_get_or_insert_default)] #![feature(round_char_boundary)] #![feature(try_blocks)] #![feature(yeet_expr)] From 016a709b2451ed120cb1317fc17ac27d3b0b5df6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 16:32:20 +1000 Subject: [PATCH 02/13] Condense `use rustc_*` declarations. No reason to have two of them listed separately, after modules. --- compiler/rustc_mir_transform/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index cd24b4437ad16..f65d835f59b17 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -18,6 +18,7 @@ extern crate tracing; use hir::ConstContext; use required_consts::RequiredConstsVisitor; +use rustc_const_eval::check_consts::{self, ConstCx}; use rustc_const_eval::util; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::steal::Steal; @@ -34,6 +35,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::util::Providers; use rustc_middle::{bug, query, span_bug}; +use rustc_mir_dataflow::rustc_peek; use rustc_span::source_map::Spanned; use rustc_span::{sym, DUMMY_SP}; use rustc_trait_selection::traits; @@ -108,9 +110,6 @@ mod unreachable_enum_branching; mod unreachable_prop; mod validate; -use rustc_const_eval::check_consts::{self, ConstCx}; -use rustc_mir_dataflow::rustc_peek; - rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { From fda52b8f63db5a2530f245e15b8a5695a929e886 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 08:18:30 +1000 Subject: [PATCH 03/13] Simplify a provider definition. --- compiler/rustc_mir_transform/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index f65d835f59b17..ddefc1307d8e0 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -127,7 +127,7 @@ pub fn provide(providers: &mut Providers) { mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses, optimized_mir, is_mir_available, - is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did), + is_ctfe_mir_available: is_mir_available, mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable, mir_inliner_callees: inline::cycle::mir_inliner_callees, promoted_mir, From 2932e097f49901bd46dca835ff7a6ac000a94876 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 08:24:20 +1000 Subject: [PATCH 04/13] Simplify creation of a set. --- compiler/rustc_mir_transform/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index ddefc1307d8e0..0289c32cdcfca 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -220,10 +220,8 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { /// Finds the full set of `DefId`s within the current crate that have /// MIR associated with them. fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { - let mut set = FxIndexSet::default(); - // All body-owners have MIR associated with them. - set.extend(tcx.hir().body_owners()); + let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect(); // Additionally, tuple struct/variant constructors have MIR, but // they don't have a BodyId, so we need to build them separately. From 66b3585145ff543687b316d8374f352821296a17 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 08:25:52 +1000 Subject: [PATCH 05/13] Simplify a pattern. --- compiler/rustc_mir_transform/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 0289c32cdcfca..33274fedc3cd7 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -246,8 +246,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { // No need to const-check a non-const `fn`. match const_kind { - Some(ConstContext::Const { .. } | ConstContext::Static(_)) - | Some(ConstContext::ConstFn) => {} + Some(ConstContext::Const { .. } | ConstContext::Static(_) | ConstContext::ConstFn) => {} None => span_bug!( tcx.def_span(def), "`mir_const_qualif` should only be called on const fns and const items" From 3b6af9a451fc3bfef3d11967c927a8ef62037126 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 10:34:42 +1000 Subject: [PATCH 06/13] Use a local variable. --- compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index cd850e2d73189..be8b09cfb4e70 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -85,7 +85,7 @@ fn add_move_for_packed_drop<'tcx>( let source_info = terminator.source_info; let ty = place.ty(body, tcx).ty; - let temp = patch.new_temp(ty, terminator.source_info.span); + let temp = patch.new_temp(ty, source_info.span); let storage_dead_block = patch.new_block(BasicBlockData { statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }], From 5331280a2b1e44f42bf5f9b6dea08a4f9d3452cf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 12:40:09 +1000 Subject: [PATCH 07/13] Merge some `if`s. For more concise code. --- .../src/check_packed_ref.rs | 29 +++++++------------ compiler/rustc_mir_transform/src/coroutine.rs | 10 +++---- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 9902002580aed..eb76a39be57ff 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -37,24 +37,17 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { } fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - if context.is_borrow() { - if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { - let def_id = self.body.source.instance.def_id(); - if let Some(impl_def_id) = self.tcx.impl_of_method(def_id) - && self.tcx.is_builtin_derived(impl_def_id) - { - // If we ever reach here it means that the generated derive - // code is somehow doing an unaligned reference, which it - // shouldn't do. - span_bug!( - self.source_info.span, - "builtin derive created an unaligned reference" - ); - } else { - self.tcx - .dcx() - .emit_err(errors::UnalignedPackedRef { span: self.source_info.span }); - } + if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.param_env, *place) { + let def_id = self.body.source.instance.def_id(); + if let Some(impl_def_id) = self.tcx.impl_of_method(def_id) + && self.tcx.is_builtin_derived(impl_def_id) + { + // If we ever reach here it means that the generated derive + // code is somehow doing an unaligned reference, which it + // shouldn't do. + span_bug!(self.source_info.span, "builtin derive created an unaligned reference"); + } else { + self.tcx.dcx().emit_err(errors::UnalignedPackedRef { span: self.source_info.span }); } } } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index d9d2abc554a65..7dbad721d6d7b 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1182,12 +1182,10 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { source_info, kind: TerminatorKind::Drop { place, target, unwind, replace: _ }, } => { - if let Some(local) = place.as_local() { - if local == SELF_ARG { - (target, unwind, source_info) - } else { - continue; - } + if let Some(local) = place.as_local() + && local == SELF_ARG + { + (target, unwind, source_info) } else { continue; } From d7cb1181dc29210af3c49e7be267b3423095fd3f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 13:08:02 +1000 Subject: [PATCH 08/13] Merge `DerefArgVisitor` and `PinArgVisitor`. They are almost identical, differing only in the `ProjectionElem` they insert. This commit merges them into a new type `SelfArgVisitor`. --- compiler/rustc_mir_transform/src/coroutine.rs | 54 +++---------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 7dbad721d6d7b..99c6eee40e9c5 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -112,11 +112,12 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> { } } -struct DerefArgVisitor<'tcx> { +struct SelfArgVisitor<'tcx> { + elem: ProjectionElem>, tcx: TyCtxt<'tcx>, } -impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { +impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -129,49 +130,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { if place.local == SELF_ARG { replace_base( place, - Place { - local: SELF_ARG, - projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]), - }, - self.tcx, - ); - } else { - self.visit_local(&mut place.local, context, location); - - for elem in place.projection.iter() { - if let PlaceElem::Index(local) = elem { - assert_ne!(local, SELF_ARG); - } - } - } - } -} - -struct PinArgVisitor<'tcx> { - ref_coroutine_ty: Ty<'tcx>, - tcx: TyCtxt<'tcx>, -} - -impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { - assert_ne!(*local, SELF_ARG); - } - - fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if place.local == SELF_ARG { - replace_base( - place, - Place { - local: SELF_ARG, - projection: self.tcx().mk_place_elems(&[ProjectionElem::Field( - FieldIdx::ZERO, - self.ref_coroutine_ty, - )]), - }, + Place { local: SELF_ARG, projection: self.tcx().mk_place_elems(&[self.elem]) }, self.tcx, ); } else { @@ -568,7 +527,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo body.local_decls.raw[1].ty = ref_coroutine_ty; // Add a deref to accesses of the coroutine state - DerefArgVisitor { tcx }.visit_body(body); + SelfArgVisitor { tcx, elem: ProjectionElem::Deref }.visit_body(body); } fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { @@ -583,7 +542,8 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body body.local_decls.raw[1].ty = pin_ref_coroutine_ty; // Add the Pin field access to accesses of the coroutine state - PinArgVisitor { ref_coroutine_ty, tcx }.visit_body(body); + SelfArgVisitor { tcx, elem: ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty) } + .visit_body(body); } /// Allocates a new local and replaces all references of `local` with it. Returns the new local. From 408481f4d876e58ab2b4d520706cfe07b223dc6f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 13:17:49 +1000 Subject: [PATCH 09/13] Remove some unnecessary constants. These are just renamings of `CoroutineArgs` constants. --- compiler/rustc_mir_transform/src/coroutine.rs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 99c6eee40e9c5..b9480d31e8857 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -156,15 +156,6 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx const SELF_ARG: Local = Local::from_u32(1); -/// Coroutine has not been resumed yet. -const UNRESUMED: usize = CoroutineArgs::UNRESUMED; -/// Coroutine has returned / is completed. -const RETURNED: usize = CoroutineArgs::RETURNED; -/// Coroutine has panicked and is poisoned. -const POISONED: usize = CoroutineArgs::POISONED; -/// Number of reserved variants of coroutine state. -const RESERVED_VARIANTS: usize = CoroutineArgs::RESERVED_VARIANTS; - /// A `yield` point in the coroutine. struct SuspensionPoint<'tcx> { /// State discriminant used when suspending or resuming at this point. @@ -475,7 +466,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { self.make_state(v, source_info, is_return, &mut data.statements); let state = if let Some((resume, mut resume_arg)) = resume { // Yield - let state = RESERVED_VARIANTS + self.suspension_points.len(); + let state = CoroutineArgs::RESERVED_VARIANTS + self.suspension_points.len(); // The resume arg target location might itself be remapped if its base local is // live across a yield. @@ -508,7 +499,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { VariantIdx::new(state) } else { // Return - VariantIdx::new(RETURNED) // state for returned + VariantIdx::new(CoroutineArgs::RETURNED) // state for returned }; data.statements.push(self.set_discr(state, source_info)); data.terminator_mut().kind = TerminatorKind::Return; @@ -1044,10 +1035,11 @@ fn compute_layout<'tcx>( // Build the coroutine variant field list. // Create a map from local indices to coroutine struct indices. let mut variant_fields: IndexVec> = - iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect(); + iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect(); let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size()); for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() { - let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx); + let variant_index = + VariantIdx::from(CoroutineArgs::RESERVED_VARIANTS + suspension_point_idx); let mut fields = IndexVec::new(); for (idx, saved_local) in live_locals.iter().enumerate() { fields.push(saved_local); @@ -1194,7 +1186,7 @@ fn create_coroutine_drop_shim<'tcx>( let mut cases = create_cases(&mut body, transform, Operation::Drop); - cases.insert(0, (UNRESUMED, drop_clean)); + cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean)); // The returned state and the poisoned state fall through to the default // case which is just to return @@ -1344,7 +1336,9 @@ fn create_coroutine_resume_function<'tcx>( if can_unwind { let source_info = SourceInfo::outermost(body.span); let poison_block = body.basic_blocks_mut().push(BasicBlockData { - statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)], + statements: vec![ + transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info), + ], terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }), is_cleanup: true, }); @@ -1376,13 +1370,16 @@ fn create_coroutine_resume_function<'tcx>( use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn}; // Jump to the entry point on the unresumed - cases.insert(0, (UNRESUMED, START_BLOCK)); + cases.insert(0, (CoroutineArgs::UNRESUMED, START_BLOCK)); // Panic when resumed on the returned or poisoned state if can_unwind { cases.insert( 1, - (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind))), + ( + CoroutineArgs::POISONED, + insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind)), + ), ); } @@ -1397,7 +1394,7 @@ fn create_coroutine_resume_function<'tcx>( transform.insert_none_ret_block(body) } }; - cases.insert(1, (RETURNED, block)); + cases.insert(1, (CoroutineArgs::RETURNED, block)); } insert_switch(body, cases, &transform, TerminatorKind::Unreachable); From 590a02173bba33fd7cd50bf9ae9061727ebe24ca Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 13:47:22 +1000 Subject: [PATCH 10/13] Factor out some repetitive code. --- compiler/rustc_mir_transform/src/coroutine.rs | 119 ++++++------------ 1 file changed, 38 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index b9480d31e8857..8ee2b8cbb9cdf 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -63,7 +63,9 @@ use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet}; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, InstanceKind, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt, +}; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, @@ -210,14 +212,10 @@ impl<'tcx> TransformVisitor<'tcx> { // `gen` continues return `None` CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); - Rvalue::Aggregate( - Box::new(AggregateKind::Adt( - option_def_id, - VariantIdx::ZERO, - self.tcx.mk_args(&[self.old_yield_ty.into()]), - None, - None, - )), + make_aggregate_adt( + option_def_id, + VariantIdx::ZERO, + self.tcx.mk_args(&[self.old_yield_ty.into()]), IndexVec::new(), ) } @@ -266,64 +264,28 @@ impl<'tcx> TransformVisitor<'tcx> { is_return: bool, statements: &mut Vec>, ) { + const ZERO: VariantIdx = VariantIdx::ZERO; + const ONE: VariantIdx = VariantIdx::from_usize(1); let rvalue = match self.coroutine_kind { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None); let args = self.tcx.mk_args(&[self.old_ret_ty.into()]); - if is_return { - // Poll::Ready(val) - Rvalue::Aggregate( - Box::new(AggregateKind::Adt( - poll_def_id, - VariantIdx::ZERO, - args, - None, - None, - )), - IndexVec::from_raw(vec![val]), - ) + let (variant_idx, operands) = if is_return { + (ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val) } else { - // Poll::Pending - Rvalue::Aggregate( - Box::new(AggregateKind::Adt( - poll_def_id, - VariantIdx::from_usize(1), - args, - None, - None, - )), - IndexVec::new(), - ) - } + (ONE, IndexVec::new()) // Poll::Pending + }; + make_aggregate_adt(poll_def_id, variant_idx, args, operands) } CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); let args = self.tcx.mk_args(&[self.old_yield_ty.into()]); - if is_return { - // None - Rvalue::Aggregate( - Box::new(AggregateKind::Adt( - option_def_id, - VariantIdx::ZERO, - args, - None, - None, - )), - IndexVec::new(), - ) + let (variant_idx, operands) = if is_return { + (ZERO, IndexVec::new()) // None } else { - // Some(val) - Rvalue::Aggregate( - Box::new(AggregateKind::Adt( - option_def_id, - VariantIdx::from_usize(1), - args, - None, - None, - )), - IndexVec::from_raw(vec![val]), - ) - } + (ONE, IndexVec::from_raw(vec![val])) // Some(val) + }; + make_aggregate_adt(option_def_id, variant_idx, args, operands) } CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => { if is_return { @@ -349,31 +311,17 @@ impl<'tcx> TransformVisitor<'tcx> { let coroutine_state_def_id = self.tcx.require_lang_item(LangItem::CoroutineState, None); let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]); - if is_return { - // CoroutineState::Complete(val) - Rvalue::Aggregate( - Box::new(AggregateKind::Adt( - coroutine_state_def_id, - VariantIdx::from_usize(1), - args, - None, - None, - )), - IndexVec::from_raw(vec![val]), - ) + let variant_idx = if is_return { + ONE // CoroutineState::Complete(val) } else { - // CoroutineState::Yielded(val) - Rvalue::Aggregate( - Box::new(AggregateKind::Adt( - coroutine_state_def_id, - VariantIdx::ZERO, - args, - None, - None, - )), - IndexVec::from_raw(vec![val]), - ) - } + ZERO // CoroutineState::Yielded(val) + }; + make_aggregate_adt( + coroutine_state_def_id, + variant_idx, + args, + IndexVec::from_raw(vec![val]), + ) } }; @@ -509,6 +457,15 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { } } +fn make_aggregate_adt<'tcx>( + def_id: DefId, + variant_idx: VariantIdx, + args: GenericArgsRef<'tcx>, + operands: IndexVec>, +) -> Rvalue<'tcx> { + Rvalue::Aggregate(Box::new(AggregateKind::Adt(def_id, variant_idx, args, None, None)), operands) +} + fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let coroutine_ty = body.local_decls.raw[1].ty; From 243109e006c0ffade939db475524c1957dcae409 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 13:54:13 +1000 Subject: [PATCH 11/13] Remove an unnecessary `continue`. --- compiler/rustc_mir_transform/src/coroutine.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 8ee2b8cbb9cdf..84c6a60fa23f9 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -558,8 +558,6 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let local = eliminate_get_context_call(&mut body[bb]); replace_resume_ty_local(tcx, body, local, context_mut_ref); } - } else { - continue; } } TerminatorKind::Yield { resume_arg, .. } => { From 8541b0f1f39eac7d53bd5423289422a82bd19fdd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Aug 2024 13:56:17 +1000 Subject: [PATCH 12/13] Use `let`/`else` to reduce some indentation. --- compiler/rustc_mir_transform/src/coroutine.rs | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 84c6a60fa23f9..6d5597dde6749 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -570,24 +570,23 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local { let terminator = bb_data.terminator.take().unwrap(); - if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind { - let [arg] = *Box::try_from(args).unwrap(); - let local = arg.node.place().unwrap().local; - - let arg = Rvalue::Use(arg.node); - let assign = Statement { - source_info: terminator.source_info, - kind: StatementKind::Assign(Box::new((destination, arg))), - }; - bb_data.statements.push(assign); - bb_data.terminator = Some(Terminator { - source_info: terminator.source_info, - kind: TerminatorKind::Goto { target: target.unwrap() }, - }); - local - } else { + let TerminatorKind::Call { args, destination, target, .. } = terminator.kind else { bug!(); - } + }; + let [arg] = *Box::try_from(args).unwrap(); + let local = arg.node.place().unwrap().local; + + let arg = Rvalue::Use(arg.node); + let assign = Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(Box::new((destination, arg))), + }; + bb_data.statements.push(assign); + bb_data.terminator = Some(Terminator { + source_info: terminator.source_info, + kind: TerminatorKind::Goto { target: target.unwrap() }, + }); + local } #[cfg_attr(not(debug_assertions), allow(unused))] From ac7a293336e0f7afd993725e8d91f9ae7859ed89 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 30 Aug 2024 13:18:45 +1000 Subject: [PATCH 13/13] Avoid repeated interning in `SelfArgVisitor`. --- compiler/rustc_mir_transform/src/coroutine.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 6d5597dde6749..954e6f25561f2 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -115,8 +115,14 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> { } struct SelfArgVisitor<'tcx> { - elem: ProjectionElem>, tcx: TyCtxt<'tcx>, + new_base: Place<'tcx>, +} + +impl<'tcx> SelfArgVisitor<'tcx> { + fn new(tcx: TyCtxt<'tcx>, elem: ProjectionElem>) -> Self { + Self { tcx, new_base: Place { local: SELF_ARG, projection: tcx.mk_place_elems(&[elem]) } } + } } impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> { @@ -130,11 +136,7 @@ impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> { fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { if place.local == SELF_ARG { - replace_base( - place, - Place { local: SELF_ARG, projection: self.tcx().mk_place_elems(&[self.elem]) }, - self.tcx, - ); + replace_base(place, self.new_base, self.tcx); } else { self.visit_local(&mut place.local, context, location); @@ -475,7 +477,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo body.local_decls.raw[1].ty = ref_coroutine_ty; // Add a deref to accesses of the coroutine state - SelfArgVisitor { tcx, elem: ProjectionElem::Deref }.visit_body(body); + SelfArgVisitor::new(tcx, ProjectionElem::Deref).visit_body(body); } fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { @@ -490,7 +492,7 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body body.local_decls.raw[1].ty = pin_ref_coroutine_ty; // Add the Pin field access to accesses of the coroutine state - SelfArgVisitor { tcx, elem: ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty) } + SelfArgVisitor::new(tcx, ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty)) .visit_body(body); }