@@ -515,9 +515,15 @@ impl From<Option<BlockId>> for VisibleFromModule {
515
515
}
516
516
}
517
517
518
+ #[ derive( Debug , Clone ) ]
519
+ pub enum AutorefOrPtrAdjustment {
520
+ Autoref ( Mutability ) ,
521
+ ToConstPtr ,
522
+ }
523
+
518
524
#[ derive( Debug , Clone , Default ) ]
519
525
pub struct ReceiverAdjustments {
520
- autoref : Option < Mutability > ,
526
+ autoref : Option < AutorefOrPtrAdjustment > ,
521
527
autoderefs : usize ,
522
528
unsize_array : bool ,
523
529
}
@@ -535,22 +541,43 @@ impl ReceiverAdjustments {
535
541
}
536
542
Some ( ( kind, new_ty) ) => {
537
543
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
+ } ;
538
550
adjust. push ( Adjustment {
539
551
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) ) ,
542
553
AutoderefKind :: Builtin => None ,
543
554
} ) ,
544
555
target : new_ty,
545
556
} ) ;
546
557
}
547
558
}
548
559
}
549
- if let Some ( m ) = self . autoref {
560
+ if let Some ( autoref ) = & self . autoref {
550
561
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
+ } ;
554
581
}
555
582
if self . unsize_array {
556
583
ty = ' it: {
@@ -575,8 +602,8 @@ impl ReceiverAdjustments {
575
602
( ty, adjust)
576
603
}
577
604
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 }
580
607
}
581
608
}
582
609
@@ -1051,7 +1078,7 @@ fn iterate_method_candidates_with_autoref(
1051
1078
let mut maybe_reborrowed = first_adjustment. clone ( ) ;
1052
1079
if let Some ( ( _, _, m) ) = receiver_ty. value . as_reference ( ) {
1053
1080
// Prefer reborrow of references to move
1054
- maybe_reborrowed. autoref = Some ( m ) ;
1081
+ maybe_reborrowed. autoref = Some ( AutorefOrPtrAdjustment :: Autoref ( m ) ) ;
1055
1082
maybe_reborrowed. autoderefs += 1 ;
1056
1083
}
1057
1084
@@ -1063,15 +1090,34 @@ fn iterate_method_candidates_with_autoref(
1063
1090
binders : receiver_ty. binders . clone ( ) ,
1064
1091
} ;
1065
1092
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
+ ) ?;
1067
1097
1068
1098
let ref_muted = Canonical {
1069
1099
value : TyKind :: Ref ( Mutability :: Mut , error_lifetime ( ) , receiver_ty. value . clone ( ) )
1070
1100
. intern ( Interner ) ,
1071
- binders : receiver_ty. binders ,
1101
+ binders : receiver_ty. binders . clone ( ) ,
1072
1102
} ;
1073
1103
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 ( ( ) )
1075
1121
}
1076
1122
1077
1123
pub trait MethodCandidateCallback {
0 commit comments