diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-01-20 17:10:37 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-20 17:10:37 +0100 |
| commit | 5c10dbd85f962e4fc1ed16f4e157f00e5e7b6a8a (patch) | |
| tree | 028faa77af90be6df66d96c3cba5b28c6638ef62 | |
| parent | 1839829f0a88a5835d3b85043d69b12d056ea191 (diff) | |
| parent | 36a11417fafcbfae0500884df2d4b6dd2c5e5a0f (diff) | |
| download | rust-5c10dbd85f962e4fc1ed16f4e157f00e5e7b6a8a.tar.gz rust-5c10dbd85f962e4fc1ed16f4e157f00e5e7b6a8a.zip | |
Rollup merge of #92704 - 5225225:std_mem_transmute_ref_t_mut_t, r=michaelwoerister
Change lint message to be stronger for &T -> &mut T transmute
The old message implied that it's only UB if you use the reference to mutate, which (as far as I know) is not true. As in, the following program has UB, and a &T -> &mut T transmute is effectively an `unreachable_unchecked`.
```rust
fn main() {
#[allow(mutable_transmutes)]
unsafe {
let _ = std::mem::transmute::<&i32, &mut i32>(&0);
}
}
```
In the future, it might be a good idea to use the edition system to make this a hard error, since I don't think it is *ever* defined behaviour? Unless we rule that `&UnsafeCell<i32> -> &mut i32` is fine. (That, and you always could just use `.get()`, so you're not losing anything)
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/transmute/transmute-imut-to-mut.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/transmute/transmute-imut-to-mut.stderr | 2 |
3 files changed, 5 insertions, 5 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 66a89492abd..38e1669d331 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1247,7 +1247,7 @@ declare_lint! { /// [`UnsafeCell`]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html MUTABLE_TRANSMUTES, Deny, - "mutating transmuted &mut T from &T may cause undefined behavior" + "transmuting &T to &mut T is undefined behavior, even if the reference is unused" } declare_lint_pass!(MutableTransmutes => [MUTABLE_TRANSMUTES]); @@ -1259,8 +1259,8 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes { get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (ty1.kind(), ty2.kind())) { if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not { - let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \ - consider instead using an UnsafeCell"; + let msg = "transmuting &T to &mut T is undefined behavior, \ + even if the reference is unused, consider instead using an UnsafeCell"; cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| lint.build(msg).emit()); } } diff --git a/src/test/ui/transmute/transmute-imut-to-mut.rs b/src/test/ui/transmute/transmute-imut-to-mut.rs index 8e34e0ae8c7..9f3f76c1ef3 100644 --- a/src/test/ui/transmute/transmute-imut-to-mut.rs +++ b/src/test/ui/transmute/transmute-imut-to-mut.rs @@ -4,5 +4,5 @@ use std::mem::transmute; fn main() { let _a: &mut u8 = unsafe { transmute(&1u8) }; - //~^ ERROR mutating transmuted &mut T from &T may cause undefined behavior + //~^ ERROR transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell } diff --git a/src/test/ui/transmute/transmute-imut-to-mut.stderr b/src/test/ui/transmute/transmute-imut-to-mut.stderr index d323c1a73b7..1e9dff3ce89 100644 --- a/src/test/ui/transmute/transmute-imut-to-mut.stderr +++ b/src/test/ui/transmute/transmute-imut-to-mut.stderr @@ -1,4 +1,4 @@ -error: mutating transmuted &mut T from &T may cause undefined behavior, consider instead using an UnsafeCell +error: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell --> $DIR/transmute-imut-to-mut.rs:6:32 | LL | let _a: &mut u8 = unsafe { transmute(&1u8) }; |
