Skip to content

Commit c6107c5

Browse files
committed
Don't fire const_item_mutation lint on writes through a pointer
Fixes #77321
1 parent fc2daaa commit c6107c5

File tree

3 files changed

+44
-29
lines changed

3 files changed

+44
-29
lines changed

compiler/rustc_mir/src/transform/check_const_item_mutation.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,15 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
6060
// so emitting a lint would be redundant.
6161
if !lhs.projection.is_empty() {
6262
if let Some(def_id) = self.is_const_item(lhs.local) {
63-
self.lint_const_item_usage(def_id, loc, |lint| {
64-
let mut lint = lint.build("attempting to modify a `const` item");
65-
lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified");
66-
lint
67-
})
63+
// Don't lint on writes through a pointer
64+
// (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`)
65+
if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) {
66+
self.lint_const_item_usage(def_id, loc, |lint| {
67+
let mut lint = lint.build("attempting to modify a `const` item");
68+
lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified");
69+
lint
70+
})
71+
}
6872
}
6973
}
7074
// We are looking for MIR of the form:

src/test/ui/lint/lint-const-item-mutation.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
struct MyStruct {
44
field: bool,
55
inner_array: [char; 1],
6+
raw_ptr: *mut u8
67
}
78
impl MyStruct {
89
fn use_mut(&mut self) {}
910
}
1011

1112
const ARRAY: [u8; 1] = [25];
12-
const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
13+
const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
14+
const RAW_PTR: *mut u8 = 1 as *mut u8;
1315

1416
fn main() {
1517
ARRAY[0] = 5; //~ WARN attempting to modify
@@ -18,4 +20,13 @@ fn main() {
1820
MY_STRUCT.use_mut(); //~ WARN taking
1921
&mut MY_STRUCT; //~ WARN taking
2022
(&mut MY_STRUCT).use_mut(); //~ WARN taking
23+
24+
// Test that we don't warn when writing through
25+
// a raw pointer
26+
// This is U.B., but this test is check-pass,
27+
// so this never actually executes
28+
unsafe {
29+
*RAW_PTR = 0;
30+
*MY_STRUCT.raw_ptr = 0;
31+
}
2132
}
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,89 @@
11
warning: attempting to modify a `const` item
2-
--> $DIR/lint-const-item-mutation.rs:15:5
2+
--> $DIR/lint-const-item-mutation.rs:17:5
33
|
44
LL | ARRAY[0] = 5;
55
| ^^^^^^^^^^^^
66
|
77
= note: `#[warn(const_item_mutation)]` on by default
88
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
99
note: `const` item defined here
10-
--> $DIR/lint-const-item-mutation.rs:11:1
10+
--> $DIR/lint-const-item-mutation.rs:12:1
1111
|
1212
LL | const ARRAY: [u8; 1] = [25];
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1414

1515
warning: attempting to modify a `const` item
16-
--> $DIR/lint-const-item-mutation.rs:16:5
16+
--> $DIR/lint-const-item-mutation.rs:18:5
1717
|
1818
LL | MY_STRUCT.field = false;
1919
| ^^^^^^^^^^^^^^^^^^^^^^^
2020
|
2121
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
2222
note: `const` item defined here
23-
--> $DIR/lint-const-item-mutation.rs:12:1
23+
--> $DIR/lint-const-item-mutation.rs:13:1
2424
|
25-
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2727

2828
warning: attempting to modify a `const` item
29-
--> $DIR/lint-const-item-mutation.rs:17:5
29+
--> $DIR/lint-const-item-mutation.rs:19:5
3030
|
3131
LL | MY_STRUCT.inner_array[0] = 'b';
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3333
|
3434
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
3535
note: `const` item defined here
36-
--> $DIR/lint-const-item-mutation.rs:12:1
36+
--> $DIR/lint-const-item-mutation.rs:13:1
3737
|
38-
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
39-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4040

4141
warning: taking a mutable reference to a `const` item
42-
--> $DIR/lint-const-item-mutation.rs:18:5
42+
--> $DIR/lint-const-item-mutation.rs:20:5
4343
|
4444
LL | MY_STRUCT.use_mut();
4545
| ^^^^^^^^^^^^^^^^^^^
4646
|
4747
= note: each usage of a `const` item creates a new temporary
4848
= note: the mutable reference will refer to this temporary, not the original `const` item
4949
note: mutable reference created due to call to this method
50-
--> $DIR/lint-const-item-mutation.rs:8:5
50+
--> $DIR/lint-const-item-mutation.rs:9:5
5151
|
5252
LL | fn use_mut(&mut self) {}
5353
| ^^^^^^^^^^^^^^^^^^^^^
5454
note: `const` item defined here
55-
--> $DIR/lint-const-item-mutation.rs:12:1
55+
--> $DIR/lint-const-item-mutation.rs:13:1
5656
|
57-
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
58-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
57+
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
58+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959

6060
warning: taking a mutable reference to a `const` item
61-
--> $DIR/lint-const-item-mutation.rs:19:5
61+
--> $DIR/lint-const-item-mutation.rs:21:5
6262
|
6363
LL | &mut MY_STRUCT;
6464
| ^^^^^^^^^^^^^^
6565
|
6666
= note: each usage of a `const` item creates a new temporary
6767
= note: the mutable reference will refer to this temporary, not the original `const` item
6868
note: `const` item defined here
69-
--> $DIR/lint-const-item-mutation.rs:12:1
69+
--> $DIR/lint-const-item-mutation.rs:13:1
7070
|
71-
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
72-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
71+
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
72+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7373

7474
warning: taking a mutable reference to a `const` item
75-
--> $DIR/lint-const-item-mutation.rs:20:5
75+
--> $DIR/lint-const-item-mutation.rs:22:5
7676
|
7777
LL | (&mut MY_STRUCT).use_mut();
7878
| ^^^^^^^^^^^^^^^^
7979
|
8080
= note: each usage of a `const` item creates a new temporary
8181
= note: the mutable reference will refer to this temporary, not the original `const` item
8282
note: `const` item defined here
83-
--> $DIR/lint-const-item-mutation.rs:12:1
83+
--> $DIR/lint-const-item-mutation.rs:13:1
8484
|
85-
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
86-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
85+
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
86+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8787

8888
warning: 6 warnings emitted
8989

0 commit comments

Comments
 (0)