Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I have quite a lot of MMIO in an embedded project, defined and used like this: (see a ) When I , I'm getting a whole host of warnings of the type: I expect no warnings, because I'm not assigning to a , I'm assigning to a dereferenced , aka a mutable u32. I couldn't figure out a playground example that would show the value actually mutating, but by hitting hardware registers I can prove that the value does get mutated, and it makes sense that it would: The pointer is , but it's pointing to a able . Dereferencing shouldn't care whether the pointer variable is . <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: No backtrace for this bug; it's a warning.
There's a... fine, I guess, workaround of in my case, since all the MMIO code is bundled into a module away from the rest.
cc
This will be fixed by
Awesome, thanks so much!

Discussion:
// so emitting a lint would be redundant. if !lhs.projection.is_empty() { if let Some(def_id) = self.is_const_item(lhs.local) { <del> 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 }) </del> <ins> // 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 }) } </ins> } } // We are looking for MIR of the form:

struct MyStruct { field: bool, inner_array: [char; 1], <ins> raw_ptr: *mut u8 </ins> } impl MyStruct { fn use_mut(&mut self) {} } const ARRAY: [u8; 1] = [25]; <del> const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; </del> <ins> 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; </ins> fn main() { ARRAY[0] = 5; //~ WARN attempting to modify

MY_STRUCT.use_mut(); //~ WARN taking &mut MY_STRUCT; //~ WARN taking (&mut MY_STRUCT).use_mut(); //~ WARN taking <ins> // 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; } </ins> }

warning: attempting to modify a `const` item <del> --> $DIR/lint-const-item-mutation.rs:15:5 </del> <ins> --> $DIR/lint-const-item-mutation.rs:17:5 </ins> | 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 <del> --> $DIR/lint-const-item-mutation.rs:11:1 </del> <ins> --> $DIR/lint-const-item-mutation.rs:12:1 </ins> | LL | const ARRAY: [u8; 1] = [25]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: attempting to modify a `const` item <del> --> $DIR/lint-const-item-mutation.rs:16:5 </del> <ins> --> $DIR/lint-const-item-mutation.rs:18:5 </ins> | 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 <del> --> $DIR/lint-const-item-mutation.rs:12:1 </del> <ins> --> $DIR/lint-const-item-mutation.rs:13:1 </ins> | <del> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </del> <ins> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </ins> warning: attempting to modify a `const` item <del> --> $DIR/lint-const-item-mutation.rs:17:5 </del> <ins> --> $DIR/lint-const-item-mutation.rs:19:5 </ins> | 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 <del> --> $DIR/lint-const-item-mutation.rs:12:1 </del> <ins> --> $DIR/lint-const-item-mutation.rs:13:1 </ins> | <del> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </del> <ins> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </ins> warning: taking a mutable reference to a `const` item <del> --> $DIR/lint-const-item-mutation.rs:18:5 </del> <ins> --> $DIR/lint-const-item-mutation.rs:20:5 </ins> | 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 <del> --> $DIR/lint-const-item-mutation.rs:8:5 </del> <ins> --> $DIR/lint-const-item-mutation.rs:9:5 </ins> | LL |     fn use_mut(&mut self) {} |     ^^^^^^^^^^^^^^^^^^^^^ note: `const` item defined here <del> --> $DIR/lint-const-item-mutation.rs:12:1 </del> <ins> --> $DIR/lint-const-item-mutation.rs:13:1 </ins> | <del> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </del> <ins> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </ins> warning: taking a mutable reference to a `const` item <del> --> $DIR/lint-const-item-mutation.rs:19:5 </del> <ins> --> $DIR/lint-const-item-mutation.rs:21:5 </ins> | 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 <del> --> $DIR/lint-const-item-mutation.rs:12:1 </del> <ins> --> $DIR/lint-const-item-mutation.rs:13:1 </ins> | <del> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </del> <ins> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </ins> warning: taking a mutable reference to a `const` item <del> --> $DIR/lint-const-item-mutation.rs:20:5 </del> <ins> --> $DIR/lint-const-item-mutation.rs:22:5 </ins> | 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 <del> --> $DIR/lint-const-item-mutation.rs:12:1 </del> <ins> --> $DIR/lint-const-item-mutation.rs:13:1 </ins> | <del> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </del> <ins> LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </ins> warning: 6 warnings emitted