Skip to content

Commit

Permalink
Rollup merge of rust-lang#77324 - Aaron1011:fix/const-item-mutation-p…
Browse files Browse the repository at this point in the history
…tr, r=petrochenkov

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

Fixes rust-lang#77321
  • Loading branch information
Dylan-DPC authored Sep 30, 2020
2 parents fafecb9 + c6107c5 commit 2f4ff59
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 29 deletions.
14 changes: 9 additions & 5 deletions compiler/rustc_mir/src/transform/check_const_item_mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,15 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
// so emitting a lint would be redundant.
if !lhs.projection.is_empty() {
if let Some(def_id) = self.is_const_item(lhs.local) {
self.lint_const_item_usage(def_id, loc, |lint| {
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
})
// 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| {
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
})
}
}
}
// We are looking for MIR of the form:
Expand Down
13 changes: 12 additions & 1 deletion src/test/ui/lint/lint-const-item-mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
struct MyStruct {
field: bool,
inner_array: [char; 1],
raw_ptr: *mut u8
}
impl MyStruct {
fn use_mut(&mut self) {}
}

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() {
ARRAY[0] = 5; //~ WARN attempting to modify
Expand All @@ -18,4 +20,13 @@ fn main() {
MY_STRUCT.use_mut(); //~ WARN taking
&mut MY_STRUCT; //~ 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;
}
}
46 changes: 23 additions & 23 deletions src/test/ui/lint/lint-const-item-mutation.stderr
Original file line number Diff line number Diff line change
@@ -1,89 +1,89 @@
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;
| ^^^^^^^^^^^^
|
= 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: `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];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
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
--> $DIR/lint-const-item-mutation.rs:17:5
--> $DIR/lint-const-item-mutation.rs:19:5
|
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: `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
--> $DIR/lint-const-item-mutation.rs:18:5
--> $DIR/lint-const-item-mutation.rs:20:5
|
LL | MY_STRUCT.use_mut();
| ^^^^^^^^^^^^^^^^^^^
|
= 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: 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) {}
| ^^^^^^^^^^^^^^^^^^^^^
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
--> $DIR/lint-const-item-mutation.rs:19:5
--> $DIR/lint-const-item-mutation.rs:21:5
|
LL | &mut MY_STRUCT;
| ^^^^^^^^^^^^^^
|
= 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: `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
--> $DIR/lint-const-item-mutation.rs:20:5
--> $DIR/lint-const-item-mutation.rs:22:5
|
LL | (&mut MY_STRUCT).use_mut();
| ^^^^^^^^^^^^^^^^
|
= 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: `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

0 comments on commit 2f4ff59

Please sign in to comment.