1
Fork 0

Rollup merge of #77324 - Aaron1011:fix/const-item-mutation-ptr, r=petrochenkov

Don't fire `const_item_mutation` lint on writes through a pointer

Fixes #77321
This commit is contained in:
Dylan DPC 2020-10-01 02:13:43 +02:00 committed by GitHub
commit 73258f87ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 29 deletions

View file

@ -60,6 +60,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
// so emitting a lint would be redundant. // so emitting a lint would be redundant.
if !lhs.projection.is_empty() { if !lhs.projection.is_empty() {
if let Some(def_id) = self.is_const_item(lhs.local) { if let Some(def_id) = self.is_const_item(lhs.local) {
// Don't lint on writes through a pointer
// (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`)
if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) {
self.lint_const_item_usage(def_id, loc, |lint| { self.lint_const_item_usage(def_id, loc, |lint| {
let mut lint = lint.build("attempting to modify a `const` item"); let mut lint = lint.build("attempting to modify a `const` item");
lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified"); lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified");
@ -67,6 +70,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
}) })
} }
} }
}
// We are looking for MIR of the form: // We are looking for MIR of the form:
// //
// ``` // ```

View file

@ -3,13 +3,15 @@
struct MyStruct { struct MyStruct {
field: bool, field: bool,
inner_array: [char; 1], inner_array: [char; 1],
raw_ptr: *mut u8
} }
impl MyStruct { impl MyStruct {
fn use_mut(&mut self) {} fn use_mut(&mut self) {}
} }
const ARRAY: [u8; 1] = [25]; const ARRAY: [u8; 1] = [25];
const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
const RAW_PTR: *mut u8 = 1 as *mut u8;
fn main() { fn main() {
ARRAY[0] = 5; //~ WARN attempting to modify ARRAY[0] = 5; //~ WARN attempting to modify
@ -18,4 +20,13 @@ fn main() {
MY_STRUCT.use_mut(); //~ WARN taking MY_STRUCT.use_mut(); //~ WARN taking
&mut MY_STRUCT; //~ WARN taking &mut MY_STRUCT; //~ WARN taking
(&mut MY_STRUCT).use_mut(); //~ WARN taking (&mut MY_STRUCT).use_mut(); //~ WARN taking
// Test that we don't warn when writing through
// a raw pointer
// This is U.B., but this test is check-pass,
// so this never actually executes
unsafe {
*RAW_PTR = 0;
*MY_STRUCT.raw_ptr = 0;
}
} }

View file

@ -1,5 +1,5 @@
warning: attempting to modify a `const` item warning: attempting to modify a `const` item
--> $DIR/lint-const-item-mutation.rs:15:5 --> $DIR/lint-const-item-mutation.rs:17:5
| |
LL | ARRAY[0] = 5; LL | ARRAY[0] = 5;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
@ -7,39 +7,39 @@ LL | ARRAY[0] = 5;
= note: `#[warn(const_item_mutation)]` on by default = note: `#[warn(const_item_mutation)]` on by default
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
note: `const` item defined here note: `const` item defined here
--> $DIR/lint-const-item-mutation.rs:11:1 --> $DIR/lint-const-item-mutation.rs:12:1
| |
LL | const ARRAY: [u8; 1] = [25]; LL | const ARRAY: [u8; 1] = [25];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: attempting to modify a `const` item warning: attempting to modify a `const` item
--> $DIR/lint-const-item-mutation.rs:16:5 --> $DIR/lint-const-item-mutation.rs:18:5
| |
LL | MY_STRUCT.field = false; LL | MY_STRUCT.field = false;
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
note: `const` item defined here note: `const` item defined here
--> $DIR/lint-const-item-mutation.rs:12:1 --> $DIR/lint-const-item-mutation.rs:13:1
| |
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: attempting to modify a `const` item warning: attempting to modify a `const` item
--> $DIR/lint-const-item-mutation.rs:17:5 --> $DIR/lint-const-item-mutation.rs:19:5
| |
LL | MY_STRUCT.inner_array[0] = 'b'; LL | MY_STRUCT.inner_array[0] = 'b';
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
note: `const` item defined here note: `const` item defined here
--> $DIR/lint-const-item-mutation.rs:12:1 --> $DIR/lint-const-item-mutation.rs:13:1
| |
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: taking a mutable reference to a `const` item warning: taking a mutable reference to a `const` item
--> $DIR/lint-const-item-mutation.rs:18:5 --> $DIR/lint-const-item-mutation.rs:20:5
| |
LL | MY_STRUCT.use_mut(); LL | MY_STRUCT.use_mut();
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
@ -47,18 +47,18 @@ LL | MY_STRUCT.use_mut();
= note: each usage of a `const` item creates a new temporary = note: each usage of a `const` item creates a new temporary
= note: the mutable reference will refer to this temporary, not the original `const` item = note: the mutable reference will refer to this temporary, not the original `const` item
note: mutable reference created due to call to this method note: mutable reference created due to call to this method
--> $DIR/lint-const-item-mutation.rs:8:5 --> $DIR/lint-const-item-mutation.rs:9:5
| |
LL | fn use_mut(&mut self) {} LL | fn use_mut(&mut self) {}
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
note: `const` item defined here note: `const` item defined here
--> $DIR/lint-const-item-mutation.rs:12:1 --> $DIR/lint-const-item-mutation.rs:13:1
| |
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: taking a mutable reference to a `const` item warning: taking a mutable reference to a `const` item
--> $DIR/lint-const-item-mutation.rs:19:5 --> $DIR/lint-const-item-mutation.rs:21:5
| |
LL | &mut MY_STRUCT; LL | &mut MY_STRUCT;
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -66,13 +66,13 @@ LL | &mut MY_STRUCT;
= note: each usage of a `const` item creates a new temporary = note: each usage of a `const` item creates a new temporary
= note: the mutable reference will refer to this temporary, not the original `const` item = note: the mutable reference will refer to this temporary, not the original `const` item
note: `const` item defined here note: `const` item defined here
--> $DIR/lint-const-item-mutation.rs:12:1 --> $DIR/lint-const-item-mutation.rs:13:1
| |
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: taking a mutable reference to a `const` item warning: taking a mutable reference to a `const` item
--> $DIR/lint-const-item-mutation.rs:20:5 --> $DIR/lint-const-item-mutation.rs:22:5
| |
LL | (&mut MY_STRUCT).use_mut(); LL | (&mut MY_STRUCT).use_mut();
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
@ -80,10 +80,10 @@ LL | (&mut MY_STRUCT).use_mut();
= note: each usage of a `const` item creates a new temporary = note: each usage of a `const` item creates a new temporary
= note: the mutable reference will refer to this temporary, not the original `const` item = note: the mutable reference will refer to this temporary, not the original `const` item
note: `const` item defined here note: `const` item defined here
--> $DIR/lint-const-item-mutation.rs:12:1 --> $DIR/lint-const-item-mutation.rs:13:1
| |
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: 6 warnings emitted warning: 6 warnings emitted