@@ -515,9 +515,15 @@ impl From<Option<BlockId>> for VisibleFromModule {
515515 }
516516}
517517
518+ #[ derive( Debug , Clone ) ]
519+ pub enum AutorefOrPtrAdjustment {
520+ Autoref ( Mutability ) ,
521+ ToConstPtr ,
522+ }
523+
518524#[ derive( Debug , Clone , Default ) ]
519525pub struct ReceiverAdjustments {
520- autoref : Option < Mutability > ,
526+ autoref : Option < AutorefOrPtrAdjustment > ,
521527 autoderefs : usize ,
522528 unsize_array : bool ,
523529}
@@ -535,22 +541,43 @@ impl ReceiverAdjustments {
535541 }
536542 Some ( ( kind, new_ty) ) => {
537543 ty = new_ty. clone ( ) ;
544+ let mutbl = match self . autoref {
545+ Some ( AutorefOrPtrAdjustment :: Autoref ( m) ) => Some ( m) ,
546+ Some ( AutorefOrPtrAdjustment :: ToConstPtr ) => Some ( Mutability :: Not ) ,
547+ // FIXME should we know the mutability here, when autoref is `None`?
548+ None => None ,
549+ } ;
538550 adjust. push ( Adjustment {
539551 kind : Adjust :: Deref ( match kind {
540- // FIXME should we know the mutability here, when autoref is `None`?
541- AutoderefKind :: Overloaded => Some ( OverloadedDeref ( self . autoref ) ) ,
552+ AutoderefKind :: Overloaded => Some ( OverloadedDeref ( mutbl) ) ,
542553 AutoderefKind :: Builtin => None ,
543554 } ) ,
544555 target : new_ty,
545556 } ) ;
546557 }
547558 }
548559 }
549- if let Some ( m ) = self . autoref {
560+ if let Some ( autoref ) = & self . autoref {
550561 let lt = table. new_lifetime_var ( ) ;
551- let a = Adjustment :: borrow ( m, ty, lt) ;
552- ty = a. target . clone ( ) ;
553- adjust. push ( a) ;
562+ match autoref {
563+ AutorefOrPtrAdjustment :: Autoref ( m) => {
564+ let a = Adjustment :: borrow ( * m, ty, lt) ;
565+ ty = a. target . clone ( ) ;
566+ adjust. push ( a) ;
567+ }
568+ AutorefOrPtrAdjustment :: ToConstPtr => {
569+ if let TyKind :: Raw ( Mutability :: Mut , pointee) = ty. kind ( Interner ) {
570+ let a = Adjustment {
571+ kind : Adjust :: Pointer ( PointerCast :: MutToConstPointer ) ,
572+ target : TyKind :: Raw ( Mutability :: Not , pointee. clone ( ) ) . intern ( Interner ) ,
573+ } ;
574+ ty = a. target . clone ( ) ;
575+ adjust. push ( a) ;
576+ } else {
577+ never ! ( "`ToConstPtr` target is not a raw mutable pointer" ) ;
578+ }
579+ }
580+ } ;
554581 }
555582 if self . unsize_array {
556583 ty = ' it: {
@@ -575,8 +602,8 @@ impl ReceiverAdjustments {
575602 ( ty, adjust)
576603 }
577604
578- fn with_autoref ( & self , m : Mutability ) -> ReceiverAdjustments {
579- Self { autoref : Some ( m ) , ..* self }
605+ fn with_autoref ( & self , a : AutorefOrPtrAdjustment ) -> ReceiverAdjustments {
606+ Self { autoref : Some ( a ) , ..* self }
580607 }
581608}
582609
@@ -1051,7 +1078,7 @@ fn iterate_method_candidates_with_autoref(
10511078 let mut maybe_reborrowed = first_adjustment. clone ( ) ;
10521079 if let Some ( ( _, _, m) ) = receiver_ty. value . as_reference ( ) {
10531080 // Prefer reborrow of references to move
1054- maybe_reborrowed. autoref = Some ( m ) ;
1081+ maybe_reborrowed. autoref = Some ( AutorefOrPtrAdjustment :: Autoref ( m ) ) ;
10551082 maybe_reborrowed. autoderefs += 1 ;
10561083 }
10571084
@@ -1063,15 +1090,34 @@ fn iterate_method_candidates_with_autoref(
10631090 binders : receiver_ty. binders . clone ( ) ,
10641091 } ;
10651092
1066- iterate_method_candidates_by_receiver ( refed, first_adjustment. with_autoref ( Mutability :: Not ) ) ?;
1093+ iterate_method_candidates_by_receiver (
1094+ refed,
1095+ first_adjustment. with_autoref ( AutorefOrPtrAdjustment :: Autoref ( Mutability :: Not ) ) ,
1096+ ) ?;
10671097
10681098 let ref_muted = Canonical {
10691099 value : TyKind :: Ref ( Mutability :: Mut , error_lifetime ( ) , receiver_ty. value . clone ( ) )
10701100 . intern ( Interner ) ,
1071- binders : receiver_ty. binders ,
1101+ binders : receiver_ty. binders . clone ( ) ,
10721102 } ;
10731103
1074- iterate_method_candidates_by_receiver ( ref_muted, first_adjustment. with_autoref ( Mutability :: Mut ) )
1104+ iterate_method_candidates_by_receiver (
1105+ ref_muted,
1106+ first_adjustment. with_autoref ( AutorefOrPtrAdjustment :: Autoref ( Mutability :: Mut ) ) ,
1107+ ) ?;
1108+
1109+ if let Some ( ( ty, Mutability :: Mut ) ) = receiver_ty. value . as_raw_ptr ( ) {
1110+ let const_ptr_ty = Canonical {
1111+ value : TyKind :: Raw ( Mutability :: Not , ty. clone ( ) ) . intern ( Interner ) ,
1112+ binders : receiver_ty. binders ,
1113+ } ;
1114+ iterate_method_candidates_by_receiver (
1115+ const_ptr_ty,
1116+ first_adjustment. with_autoref ( AutorefOrPtrAdjustment :: ToConstPtr ) ,
1117+ ) ?;
1118+ }
1119+
1120+ ControlFlow :: Continue ( ( ) )
10751121}
10761122
10771123pub trait MethodCandidateCallback {
0 commit comments