44//! body of the function instead of just the signature. These can be useful for optimization
55//! purposes on a best-effort basis. We compute them here and store them into the crate metadata so
66//! dependent crates can use them.
7+ //!
8+ //! Note that this *crucially* relies on codegen *not* doing any more MIR-level transformations
9+ //! after `optimized_mir`! We check for things that are *not* guaranteed to be preserved by MIR
10+ //! transforms, such as which local variables happen to be mutated.
711
812use rustc_hir:: def_id:: LocalDefId ;
913use rustc_index:: bit_set:: DenseBitSet ;
@@ -34,6 +38,11 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
3438 if place. local == RETURN_PLACE || place. local . index ( ) > self . mutable_args . domain_size ( ) {
3539 return ;
3640 }
41+ // Mutating an indirect place doesn't mutate the local it is based on, so we can skip those.
42+ // We're using runtime MIR so we can use the `first_projection` check.
43+ if place. is_indirect_first_projection ( ) {
44+ return ;
45+ }
3746
3847 let mark_as_mutable = match context {
3948 PlaceContext :: MutatingUse ( ..) => {
@@ -42,13 +51,14 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
4251 }
4352 PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: RawBorrow ) => {
4453 // Whether mutating though a `&raw const` is allowed is still undecided, so we
45- // disable any sketchy `readonly` optimizations for now. But we only need to do
46- // this if the pointer would point into the argument. IOW: for indirect places,
47- // like `&raw (*local).field`, this surely cannot mutate `local`.
54+ // disable any sketchy `readonly` optimizations for now.
4855 !place. is_indirect ( )
4956 }
5057 PlaceContext :: NonMutatingUse ( ..) | PlaceContext :: NonUse ( ..) => {
51- // Not mutating, so it's fine.
58+ // This could still mutate if it's a shared reference to a `!Freeze` type -- but
59+ // we check for `Freeze` below when converting the final `mutable_args` values
60+ // into the actually deduced attributes.
61+ // The rest is not mutating, so it's fine.
5262 false
5363 }
5464 } ;
0 commit comments