88use rustc_hir:: def_id:: LocalDefId ;
99use rustc_index:: bit_set:: BitSet ;
1010use rustc_middle:: mir:: visit:: { NonMutatingUseContext , PlaceContext , Visitor } ;
11- use rustc_middle:: mir:: { Body , Local , Location , Operand , Terminator , TerminatorKind , RETURN_PLACE } ;
11+ use rustc_middle:: mir:: { Body , Location , Operand , Place , Terminator , TerminatorKind , RETURN_PLACE } ;
1212use rustc_middle:: ty:: { self , DeducedParamAttrs , Ty , TyCtxt } ;
1313use rustc_session:: config:: OptLevel ;
1414
@@ -29,20 +29,31 @@ impl DeduceReadOnly {
2929}
3030
3131impl < ' tcx > Visitor < ' tcx > for DeduceReadOnly {
32- fn visit_local ( & mut self , local : Local , context : PlaceContext , _location : Location ) {
32+ fn visit_place ( & mut self , place : & Place < ' tcx > , context : PlaceContext , _location : Location ) {
3333 // We're only interested in arguments.
34- if local == RETURN_PLACE || local. index ( ) > self . mutable_args . domain_size ( ) {
34+ if place . local == RETURN_PLACE || place . local . index ( ) > self . mutable_args . domain_size ( ) {
3535 return ;
3636 }
3737
38- match context {
38+ let mark_as_mutable = match context {
3939 PlaceContext :: MutatingUse ( ..) => {
4040 // This is a mutation, so mark it as such.
41- self . mutable_args . insert ( local. index ( ) - 1 ) ;
41+ true
42+ }
43+ PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: AddressOf ) => {
44+ // Whether mutating though a `&raw const` is allowed is still undecided, so we
45+ // disable any sketchy `readonly` optimizations for now.
46+ // But we only need to do this if the pointer would point into the argument.
47+ !place. is_indirect ( )
4248 }
4349 PlaceContext :: NonMutatingUse ( ..) | PlaceContext :: NonUse ( ..) => {
4450 // Not mutating, so it's fine.
51+ false
4552 }
53+ } ;
54+
55+ if mark_as_mutable {
56+ self . mutable_args . insert ( place. local . index ( ) - 1 ) ;
4657 }
4758 }
4859
0 commit comments