File tree Expand file tree Collapse file tree 2 files changed +62
-0
lines changed Expand file tree Collapse file tree 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) ) ;  // 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+ } 
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