File tree 2 files changed +62
-0
lines changed
2 files changed +62
-0
lines changed Original file line number Diff line number Diff line change
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) ) ; // this is okay, but makes one wonder why the above can't have type inference
39
+ }
40
+
41
+ fn out < T > ( ptr : & mut SmartPtr < T > ) -> & mut * mut T {
42
+ ptr. get_addr ( )
43
+ }
Original file line number Diff line number Diff line change
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`.
You can’t perform that action at this time.
0 commit comments