Skip to content

Commit 91759b2

Browse files
authored
Rollup merge of rust-lang#78865 - Aaron1011:fix/const-item-mut-reborrow, r=varkor
Don't fire `CONST_ITEM_MUTATION` lint when borrowing a deref Fixes rust-lang#78819 This extends the check for dereferences added in PR rust-lang#77324 to cover mutable borrows, as well as direct writes. If we're operating on a dereference of a `const` item, we shouldn't be firing the lint.
2 parents c4e262e + bd3f3fa commit 91759b2

File tree

3 files changed

+47
-33
lines changed

3 files changed

+47
-33
lines changed

compiler/rustc_mir/src/transform/check_const_item_mutation.rs

+30-21
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,35 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> {
6161

6262
fn lint_const_item_usage(
6363
&self,
64+
place: &Place<'tcx>,
6465
const_item: DefId,
6566
location: Location,
6667
decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b>,
6768
) {
68-
let source_info = self.body.source_info(location);
69-
let lint_root = self.body.source_scopes[source_info.scope]
70-
.local_data
71-
.as_ref()
72-
.assert_crate_local()
73-
.lint_root;
69+
// Don't lint on borrowing/assigning to a dereference
70+
// e.g:
71+
//
72+
// `unsafe { *FOO = 0; *BAR.field = 1; }`
73+
// `unsafe { &mut *FOO }`
74+
if !matches!(place.projection.last(), Some(PlaceElem::Deref)) {
75+
let source_info = self.body.source_info(location);
76+
let lint_root = self.body.source_scopes[source_info.scope]
77+
.local_data
78+
.as_ref()
79+
.assert_crate_local()
80+
.lint_root;
7481

75-
self.tcx.struct_span_lint_hir(CONST_ITEM_MUTATION, lint_root, source_info.span, |lint| {
76-
decorate(lint)
77-
.span_note(self.tcx.def_span(const_item), "`const` item defined here")
78-
.emit()
79-
});
82+
self.tcx.struct_span_lint_hir(
83+
CONST_ITEM_MUTATION,
84+
lint_root,
85+
source_info.span,
86+
|lint| {
87+
decorate(lint)
88+
.span_note(self.tcx.def_span(const_item), "`const` item defined here")
89+
.emit()
90+
},
91+
);
92+
}
8093
}
8194
}
8295

@@ -88,15 +101,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
88101
// so emitting a lint would be redundant.
89102
if !lhs.projection.is_empty() {
90103
if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) {
91-
// Don't lint on writes through a pointer
92-
// (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`)
93-
if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) {
94-
self.lint_const_item_usage(def_id, loc, |lint| {
95-
let mut lint = lint.build("attempting to modify a `const` item");
96-
lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified");
97-
lint
98-
})
99-
}
104+
self.lint_const_item_usage(&lhs, def_id, loc, |lint| {
105+
let mut lint = lint.build("attempting to modify a `const` item");
106+
lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified");
107+
lint
108+
})
100109
}
101110
}
102111
// We are looking for MIR of the form:
@@ -127,7 +136,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
127136
});
128137
let lint_loc =
129138
if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc };
130-
self.lint_const_item_usage(def_id, lint_loc, |lint| {
139+
self.lint_const_item_usage(place, def_id, lint_loc, |lint| {
131140
let mut lint = lint.build("taking a mutable reference to a `const` item");
132141
lint
133142
.note("each usage of a `const` item creates a new temporary")

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

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const RAW_PTR: *mut u8 = 1 as *mut u8;
2929
const MUTABLE: Mutable = Mutable { msg: "" };
3030
const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
3131
const VEC: Vec<i32> = Vec::new();
32+
const PTR: *mut () = 1 as *mut _;
3233

3334
fn main() {
3435
ARRAY[0] = 5; //~ WARN attempting to modify
@@ -50,4 +51,8 @@ fn main() {
5051
MUTABLE.msg = "wow"; // no warning, because Drop observes the mutation
5152
MUTABLE2.msg = "wow"; //~ WARN attempting to modify
5253
VEC.push(0); //~ WARN taking a mutable reference to a `const` item
54+
55+
// Test that we don't warn when converting a raw pointer
56+
// into a mutable reference
57+
unsafe { &mut *PTR };
5358
}

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
warning: attempting to modify a `const` item
2-
--> $DIR/lint-const-item-mutation.rs:34:5
2+
--> $DIR/lint-const-item-mutation.rs:35:5
33
|
44
LL | ARRAY[0] = 5;
55
| ^^^^^^^^^^^^
66
|
77
= note: `#[warn(const_item_mutation)]` on by default
8-
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
8+
= 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
1010
--> $DIR/lint-const-item-mutation.rs:26: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:35:5
16+
--> $DIR/lint-const-item-mutation.rs:36:5
1717
|
1818
LL | MY_STRUCT.field = false;
1919
| ^^^^^^^^^^^^^^^^^^^^^^^
2020
|
21-
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
21+
= 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
2323
--> $DIR/lint-const-item-mutation.rs:27:1
2424
|
2525
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2727

2828
warning: attempting to modify a `const` item
29-
--> $DIR/lint-const-item-mutation.rs:36:5
29+
--> $DIR/lint-const-item-mutation.rs:37:5
3030
|
3131
LL | MY_STRUCT.inner_array[0] = 'b';
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3333
|
34-
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
34+
= 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
3636
--> $DIR/lint-const-item-mutation.rs:27:1
3737
|
3838
LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
3939
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4040

4141
warning: taking a mutable reference to a `const` item
42-
--> $DIR/lint-const-item-mutation.rs:37:5
42+
--> $DIR/lint-const-item-mutation.rs:38:5
4343
|
4444
LL | MY_STRUCT.use_mut();
4545
| ^^^^^^^^^^^^^^^^^^^
@@ -58,7 +58,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
5858
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959

6060
warning: taking a mutable reference to a `const` item
61-
--> $DIR/lint-const-item-mutation.rs:38:5
61+
--> $DIR/lint-const-item-mutation.rs:39:5
6262
|
6363
LL | &mut MY_STRUCT;
6464
| ^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
7272
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7373

7474
warning: taking a mutable reference to a `const` item
75-
--> $DIR/lint-const-item-mutation.rs:39:5
75+
--> $DIR/lint-const-item-mutation.rs:40:5
7676
|
7777
LL | (&mut MY_STRUCT).use_mut();
7878
| ^^^^^^^^^^^^^^^^
@@ -86,20 +86,20 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
8686
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8787

8888
warning: attempting to modify a `const` item
89-
--> $DIR/lint-const-item-mutation.rs:51:5
89+
--> $DIR/lint-const-item-mutation.rs:52:5
9090
|
9191
LL | MUTABLE2.msg = "wow";
9292
| ^^^^^^^^^^^^^^^^^^^^
9393
|
94-
= note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
94+
= note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
9595
note: `const` item defined here
9696
--> $DIR/lint-const-item-mutation.rs:30:1
9797
|
9898
LL | const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
9999
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
100100

101101
warning: taking a mutable reference to a `const` item
102-
--> $DIR/lint-const-item-mutation.rs:52:5
102+
--> $DIR/lint-const-item-mutation.rs:53:5
103103
|
104104
LL | VEC.push(0);
105105
| ^^^^^^^^^^^

0 commit comments

Comments
 (0)