@@ -1835,13 +1835,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18351835 f ( self , MacroNS ) ;
18361836 }
18371837
1838- fn per_ns_cm < ' r , F : FnMut ( & mut CmResolver < ' r , ' ra , ' tcx > , Namespace ) > (
1838+ fn per_ns_cm < ' r , F : FnMut ( CmResolver < ' _ , ' ra , ' tcx > , Namespace ) > (
18391839 mut self : CmResolver < ' r , ' ra , ' tcx > ,
18401840 mut f : F ,
18411841 ) {
1842- f ( & mut self , TypeNS ) ;
1843- f ( & mut self , ValueNS ) ;
1844- f ( & mut self , MacroNS ) ;
1842+ f ( self . reborrow ( ) , TypeNS ) ;
1843+ f ( self . reborrow ( ) , ValueNS ) ;
1844+ f ( self . reborrow ( ) , MacroNS ) ;
18451845 }
18461846
18471847 fn is_builtin_macro ( & self , res : Res ) -> bool {
@@ -1898,7 +1898,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18981898 }
18991899
19001900 let scope_set = ScopeSet :: All ( TypeNS ) ;
1901- self . cm ( ) . visit_scopes ( scope_set, parent_scope, ctxt, None , |this, scope, _, _| {
1901+ self . cm ( ) . visit_scopes ( scope_set, parent_scope, ctxt, None , |mut this, scope, _, _| {
19021902 match scope {
19031903 Scope :: Module ( module, _) => {
19041904 this. get_mut ( ) . traits_in_module ( module, assoc_item, & mut found_traits) ;
@@ -2536,38 +2536,44 @@ use std::cell::{Cell as CacheCell, RefCell as CacheRefCell};
25362536mod ref_mut {
25372537 use std:: cell:: { BorrowMutError , Cell , Ref , RefCell , RefMut } ;
25382538 use std:: fmt;
2539+ use std:: marker:: PhantomData ;
25392540 use std:: ops:: Deref ;
25402541
25412542 use crate :: Resolver ;
25422543
25432544 /// A wrapper around a mutable reference that conditionally allows mutable access.
25442545 pub ( crate ) struct RefOrMut < ' a , T > {
2545- p : & ' a mut T ,
2546+ // You can't actually create 2 `RefOrMut`s through `RefOrMut::new` because of the `&mut T`
2547+ // You can't alias it through `reborrow`, because reborrow requires a `&mut Self`
2548+ // You can't alias the underlying mutable reference through `get_mut` because it requires a `&mut Self`
2549+ // FIXME: still unsure if this is actually sound, I can't seem to create an example.
2550+ p : * const T ,
25462551 mutable : bool ,
2552+ _marker : PhantomData < & ' a mut ( ) > ,
25472553 }
25482554
25492555 impl < ' a , T > Deref for RefOrMut < ' a , T > {
25502556 type Target = T ;
25512557
2552- fn deref ( & self ) -> & Self :: Target {
2553- self . p
2558+ fn deref ( & self ) -> & T {
2559+ unsafe { self . p . as_ref_unchecked ( ) }
25542560 }
25552561 }
25562562
25572563 impl < ' a , T > AsRef < T > for RefOrMut < ' a , T > {
25582564 fn as_ref ( & self ) -> & T {
2559- self . p
2565+ unsafe { self . p . as_ref_unchecked ( ) }
25602566 }
25612567 }
25622568
25632569 impl < ' a , T > RefOrMut < ' a , T > {
25642570 pub ( crate ) fn new ( p : & ' a mut T , mutable : bool ) -> Self {
2565- RefOrMut { p, mutable }
2571+ RefOrMut { p, mutable, _marker : PhantomData }
25662572 }
25672573
25682574 /// This is needed because this wraps a `&mut T` and is therefore not `Copy`.
25692575 pub ( crate ) fn reborrow ( & mut self ) -> RefOrMut < ' _ , T > {
2570- RefOrMut { p : self . p , mutable : self . mutable }
2576+ RefOrMut { p : self . p , mutable : self . mutable , _marker : PhantomData }
25712577 }
25722578
25732579 /// Returns a mutable reference to the inner value if allowed.
@@ -2578,14 +2584,16 @@ mod ref_mut {
25782584 pub ( crate ) fn get_mut ( & mut self ) -> & mut T {
25792585 match self . mutable {
25802586 false => panic ! ( "Can't mutably borrow speculative resolver" ) ,
2581- true => self . p ,
2587+ // SAFETY: you can only create a `RefOrMut` with a `&mut T`
2588+ true => unsafe { self . p . cast_mut ( ) . as_mut_unchecked ( ) } ,
25822589 }
25832590 }
25842591
25852592 /// Returns a mutable reference to the inner value without checking if
25862593 /// it's in a mutable state.
25872594 pub ( crate ) fn get_mut_unchecked ( & mut self ) -> & mut T {
2588- self . p
2595+ // SAFETY: you can only create a `RefOrMut` with a `&mut T`
2596+ unsafe { self . p . cast_mut ( ) . as_mut_unchecked ( ) }
25892597 }
25902598 }
25912599
0 commit comments