8
8
use rustc_hir:: def_id:: LocalDefId ;
9
9
use rustc_index:: bit_set:: BitSet ;
10
10
use 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 } ;
12
12
use rustc_middle:: ty:: { self , DeducedParamAttrs , Ty , TyCtxt } ;
13
13
use rustc_session:: config:: OptLevel ;
14
14
@@ -29,20 +29,31 @@ impl DeduceReadOnly {
29
29
}
30
30
31
31
impl < ' 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 ) {
33
33
// 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 ( ) {
35
35
return ;
36
36
}
37
37
38
- match context {
38
+ let mark_as_mutable = match context {
39
39
PlaceContext :: MutatingUse ( ..) => {
40
40
// 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 ( )
42
48
}
43
49
PlaceContext :: NonMutatingUse ( ..) | PlaceContext :: NonUse ( ..) => {
44
50
// Not mutating, so it's fine.
51
+ false
45
52
}
53
+ } ;
54
+
55
+ if mark_as_mutable {
56
+ self . mutable_args . insert ( place. local . index ( ) - 1 ) ;
46
57
}
47
58
}
48
59
0 commit comments