struct EnsureCoroutineFieldAssignmentsNeverAlias<'a> {
saved_locals: &'a CoroutineSavedLocals,
storage_conflicts: &'a BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal>,
assigned_local: Option<CoroutineSavedLocal>,
}
Expand description
Looks for any assignments between locals (e.g., _4 = _5
) that will both be converted to fields
in the coroutine state machine but whose storage is not marked as conflicting
Validation needs to happen immediately before TransformVisitor
is invoked, not after.
This condition would arise when the assignment is the last use of _5
but the initial
definition of _4
if we weren’t extra careful to mark all locals used inside a statement as
conflicting. Non-conflicting coroutine saved locals may be stored at the same location within
the coroutine state machine, which would result in ill-formed MIR: the left-hand and right-hand
sides of an assignment may not alias. This caused a miscompilation in #73137.
Fields§
§saved_locals: &'a CoroutineSavedLocals
§storage_conflicts: &'a BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal>
§assigned_local: Option<CoroutineSavedLocal>
Implementations§
source§impl EnsureCoroutineFieldAssignmentsNeverAlias<'_>
impl EnsureCoroutineFieldAssignmentsNeverAlias<'_>
fn saved_local_for_direct_place( &self, place: Place<'_>, ) -> Option<CoroutineSavedLocal>
fn check_assigned_place(&mut self, place: Place<'_>, f: impl FnOnce(&mut Self))
Trait Implementations§
source§impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_>
impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_>
fn visit_place( &mut self, place: &Place<'tcx>, context: PlaceContext, location: Location, )
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location)
fn visit_terminator( &mut self, terminator: &Terminator<'tcx>, location: Location, )
fn visit_body(&mut self, body: &Body<'tcx>)
fn visit_basic_block_data( &mut self, block: BasicBlock, data: &BasicBlockData<'tcx>, )
fn visit_source_scope_data(&mut self, scope_data: &SourceScopeData<'tcx>)
fn visit_assign( &mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location, )
fn visit_assert_message( &mut self, msg: &AssertKind<Operand<'tcx>>, location: Location, )
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location)
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location)
fn visit_ascribe_user_ty( &mut self, place: &Place<'tcx>, variance: Variance, user_ty: &UserTypeProjection, location: Location, )
fn visit_coverage(&mut self, kind: &CoverageKind, location: Location)
fn visit_retag( &mut self, kind: RetagKind, place: &Place<'tcx>, location: Location, )
fn visit_projection( &mut self, place_ref: PlaceRef<'tcx>, context: PlaceContext, location: Location, )
fn visit_projection_elem( &mut self, place_ref: PlaceRef<'tcx>, elem: ProjectionElem<Local, Ty<'tcx>>, context: PlaceContext, location: Location, )
fn super_place( &mut self, place: &Place<'tcx>, context: PlaceContext, location: Location, )
fn super_projection( &mut self, place_ref: PlaceRef<'tcx>, context: PlaceContext, location: Location, )
fn super_projection_elem( &mut self, _place_ref: PlaceRef<'tcx>, elem: ProjectionElem<Local, Ty<'tcx>>, _context: PlaceContext, location: Location, )
source§fn visit_const_operand(
&mut self,
constant: &ConstOperand<'tcx>,
location: Location,
)
fn visit_const_operand( &mut self, constant: &ConstOperand<'tcx>, location: Location, )
required_consts
(i.e., including consts that have been dead-code-eliminated).fn visit_ty_const(&mut self, ct: Const<'tcx>, location: Location)
fn visit_span(&mut self, span: Span)
fn visit_source_info(&mut self, source_info: &SourceInfo)
fn visit_ty(&mut self, ty: Ty<'tcx>, _: TyContext)
fn visit_user_type_projection(&mut self, ty: &UserTypeProjection)
fn visit_user_type_annotation( &mut self, index: UserTypeAnnotationIndex, ty: &CanonicalUserTypeAnnotation<'tcx>, )
fn visit_region(&mut self, region: Region<'tcx>, _: Location)
fn visit_args( &mut self, args: &&'tcx RawList<(), GenericArg<'tcx>>, _: Location, )
fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>)
fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>)
fn visit_local( &mut self, _local: Local, _context: PlaceContext, _location: Location, )
fn visit_source_scope(&mut self, scope: SourceScope)
fn super_body(&mut self, body: &Body<'tcx>)
fn super_basic_block_data( &mut self, block: BasicBlock, data: &BasicBlockData<'tcx>, )
fn super_source_scope_data(&mut self, scope_data: &SourceScopeData<'tcx>)
fn super_statement(&mut self, statement: &Statement<'tcx>, location: Location)
fn super_assign( &mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location, )
fn super_terminator( &mut self, terminator: &Terminator<'tcx>, location: Location, )
fn super_assert_message( &mut self, msg: &AssertKind<Operand<'tcx>>, location: Location, )
fn super_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location)
fn super_operand(&mut self, operand: &Operand<'tcx>, location: Location)
fn super_ascribe_user_ty( &mut self, place: &Place<'tcx>, variance: Variance, user_ty: &UserTypeProjection, location: Location, )
fn super_coverage(&mut self, _kind: &CoverageKind, _location: Location)
fn super_retag( &mut self, _kind: RetagKind, place: &Place<'tcx>, location: Location, )
fn super_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>)
fn super_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>)
fn super_source_scope(&mut self, _scope: SourceScope)
fn super_const_operand( &mut self, constant: &ConstOperand<'tcx>, location: Location, )
fn super_ty_const(&mut self, _ct: Const<'tcx>, _location: Location)
fn super_span(&mut self, _span: Span)
fn super_source_info(&mut self, source_info: &SourceInfo)
fn super_user_type_projection(&mut self, _ty: &UserTypeProjection)
fn super_user_type_annotation( &mut self, _index: UserTypeAnnotationIndex, ty: &CanonicalUserTypeAnnotation<'tcx>, )
fn super_ty(&mut self, _ty: Ty<'tcx>)
fn super_region(&mut self, _region: Region<'tcx>)
fn super_args(&mut self, _args: &&'tcx RawList<(), GenericArg<'tcx>>)
fn visit_location(&mut self, body: &Body<'tcx>, location: Location)
Auto Trait Implementations§
impl<'a> Freeze for EnsureCoroutineFieldAssignmentsNeverAlias<'a>
impl<'a> RefUnwindSafe for EnsureCoroutineFieldAssignmentsNeverAlias<'a>
impl<'a> Send for EnsureCoroutineFieldAssignmentsNeverAlias<'a>
impl<'a> Sync for EnsureCoroutineFieldAssignmentsNeverAlias<'a>
impl<'a> Unpin for EnsureCoroutineFieldAssignmentsNeverAlias<'a>
impl<'a> UnwindSafe for EnsureCoroutineFieldAssignmentsNeverAlias<'a>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
source§impl<T> Filterable for T
impl<T> Filterable for T
source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<P> IntoQueryParam<P> for P
impl<P> IntoQueryParam<P> for P
fn into_query_param(self) -> P
source§impl<T> MaybeResult<T> for T
impl<T> MaybeResult<T> for T
source§impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
source§impl<I, T> UpcastFrom<I, T> for T
impl<I, T> UpcastFrom<I, T> for T
fn upcast_from(from: T, _tcx: I) -> T
source§impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T
source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
impl<T> ErasedDestructor for Twhere
T: 'static,
impl<T> MaybeSendSync for T
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 24 bytes