Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't fire const_item_mutation lint on writes through a pointer #77324

Merged
merged 1 commit into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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