We do not coerce &mut &mut T -> *mut mut T
This commit is contained in:
parent
09cd00fea4
commit
e404e7a8bd
43
tests/ui/coercion/mut-mut-wont-coerce.rs
Normal file
43
tests/ui/coercion/mut-mut-wont-coerce.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Documents that Rust currently does not permit the coercion &mut &mut T -> *mut *mut T
|
||||||
|
// Making this compile was a feature request in rust-lang/rust#34117 but this is currently
|
||||||
|
// "working as intended". Allowing "deep pointer coercion" seems footgun-prone, and would
|
||||||
|
// require proceeding carefully.
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
struct Foo(i32);
|
||||||
|
|
||||||
|
struct SmartPtr<T>(*mut T);
|
||||||
|
|
||||||
|
impl<T> SmartPtr<T> {
|
||||||
|
fn get_addr(&mut self) -> &mut *mut T {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for SmartPtr<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
unsafe { &*self.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T> DerefMut for SmartPtr<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut T {
|
||||||
|
unsafe { &mut *self.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Puts a Foo into the pointer provided by the caller
|
||||||
|
fn make_foo(_: *mut *mut Foo) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut result: SmartPtr<Foo> = SmartPtr(std::ptr::null_mut());
|
||||||
|
make_foo(&mut &mut *result); //~ mismatched types
|
||||||
|
//~^ expected `*mut *mut Foo`, found `&mut &mut Foo`
|
||||||
|
make_foo(out(&mut result)); // works, but makes one wonder why above coercion cannot happen
|
||||||
|
}
|
||||||
|
|
||||||
|
fn out<T>(ptr: &mut SmartPtr<T>) -> &mut *mut T {
|
||||||
|
ptr.get_addr()
|
||||||
|
}
|
19
tests/ui/coercion/mut-mut-wont-coerce.stderr
Normal file
19
tests/ui/coercion/mut-mut-wont-coerce.stderr
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/mut-mut-wont-coerce.rs:36:14
|
||||||
|
|
|
||||||
|
LL | make_foo(&mut &mut *result);
|
||||||
|
| -------- ^^^^^^^^^^^^^^^^^ expected `*mut *mut Foo`, found `&mut &mut Foo`
|
||||||
|
| |
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
= note: expected raw pointer `*mut *mut Foo`
|
||||||
|
found mutable reference `&mut &mut Foo`
|
||||||
|
note: function defined here
|
||||||
|
--> $DIR/mut-mut-wont-coerce.rs:30:4
|
||||||
|
|
|
||||||
|
LL | fn make_foo(_: *mut *mut Foo) {
|
||||||
|
| ^^^^^^^^ ----------------
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user