Skip to content

Commit c8fbad0

Browse files
authored
Unrolled build for rust-lang#124692
Rollup merge of rust-lang#124692 - workingjubilee:document-no-double-pointer-coercion-happens, r=compiler-errors We do not coerce `&mut &mut T -> *mut mut T` Resolves rust-lang#34117 by declaring it to be "working as intended" until someone RFCs it or whatever other lang proposal would be required. It seems a bit of a footgun, but perhaps there are strong reasons to allow it anyways. Seeing as how I often have to be mindful to not allow a pointer to coerce the wrong way in my FFI work, I am inclined to think not, but perhaps it's fine in some use-case and that's actually more common?
2 parents 7dd170f + e404e7a commit c8fbad0

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

Diff for: tests/ui/coercion/mut-mut-wont-coerce.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Documents that Rust currently does not permit the coercion &mut &mut T -> *mut *mut T
2+
// Making this compile was a feature request in rust-lang/rust#34117 but this is currently
3+
// "working as intended". Allowing "deep pointer coercion" seems footgun-prone, and would
4+
// require proceeding carefully.
5+
use std::ops::{Deref, DerefMut};
6+
7+
struct Foo(i32);
8+
9+
struct SmartPtr<T>(*mut T);
10+
11+
impl<T> SmartPtr<T> {
12+
fn get_addr(&mut self) -> &mut *mut T {
13+
&mut self.0
14+
}
15+
}
16+
17+
impl<T> Deref for SmartPtr<T> {
18+
type Target = T;
19+
fn deref(&self) -> &T {
20+
unsafe { &*self.0 }
21+
}
22+
}
23+
impl<T> DerefMut for SmartPtr<T> {
24+
fn deref_mut(&mut self) -> &mut T {
25+
unsafe { &mut *self.0 }
26+
}
27+
}
28+
29+
/// Puts a Foo into the pointer provided by the caller
30+
fn make_foo(_: *mut *mut Foo) {
31+
unimplemented!()
32+
}
33+
34+
fn main() {
35+
let mut result: SmartPtr<Foo> = SmartPtr(std::ptr::null_mut());
36+
make_foo(&mut &mut *result); //~ mismatched types
37+
//~^ expected `*mut *mut Foo`, found `&mut &mut Foo`
38+
make_foo(out(&mut result)); // works, but makes one wonder why above coercion cannot happen
39+
}
40+
41+
fn out<T>(ptr: &mut SmartPtr<T>) -> &mut *mut T {
42+
ptr.get_addr()
43+
}

Diff for: tests/ui/coercion/mut-mut-wont-coerce.stderr

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/mut-mut-wont-coerce.rs:36:14
3+
|
4+
LL | make_foo(&mut &mut *result);
5+
| -------- ^^^^^^^^^^^^^^^^^ expected `*mut *mut Foo`, found `&mut &mut Foo`
6+
| |
7+
| arguments to this function are incorrect
8+
|
9+
= note: expected raw pointer `*mut *mut Foo`
10+
found mutable reference `&mut &mut Foo`
11+
note: function defined here
12+
--> $DIR/mut-mut-wont-coerce.rs:30:4
13+
|
14+
LL | fn make_foo(_: *mut *mut Foo) {
15+
| ^^^^^^^^ ----------------
16+
17+
error: aborting due to 1 previous error
18+
19+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)