@@ -1102,6 +1102,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11021102 unstable_candidates. as_deref_mut ( ) ,
11031103 )
11041104 } )
1105+ . or_else ( || {
1106+ self . pick_reborrow_pin_method (
1107+ step,
1108+ self_ty,
1109+ unstable_candidates. as_deref_mut ( ) ,
1110+ )
1111+ } )
11051112 } )
11061113 } )
11071114 }
@@ -1136,7 +1143,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11361143 } )
11371144 }
11381145
1139- ty:: Adt ( def, args) if self . tcx . is_lang_item ( def. did ( ) , hir:: LangItem :: Pin ) => {
1146+ ty:: Adt ( def, args)
1147+ if self . tcx . features ( ) . pin_ergonomics
1148+ && self . tcx . is_lang_item ( def. did ( ) , hir:: LangItem :: Pin ) =>
1149+ {
11401150 // make sure this is a pinned reference (and not a `Pin<Box>` or something)
11411151 if let ty:: Ref ( _, _, mutbl) = args[ 0 ] . expect_ty ( ) . kind ( ) {
11421152 pick. autoref_or_ptr_adjustment =
@@ -1175,6 +1185,43 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11751185 } )
11761186 }
11771187
1188+ /// Looks for applicable methods if we reborrow a `Pin<&mut T>` as a `Pin<&T>`.
1189+ #[ instrument( level = "debug" , skip( self , step, unstable_candidates) ) ]
1190+ fn pick_reborrow_pin_method (
1191+ & self ,
1192+ step : & CandidateStep < ' tcx > ,
1193+ self_ty : Ty < ' tcx > ,
1194+ unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
1195+ ) -> Option < PickResult < ' tcx > > {
1196+ if !self . tcx . features ( ) . pin_ergonomics {
1197+ return None ;
1198+ }
1199+
1200+ // make sure self is a Pin<&mut T>
1201+ let inner_ty = match self_ty. kind ( ) {
1202+ ty:: Adt ( def, args) if self . tcx . is_lang_item ( def. did ( ) , hir:: LangItem :: Pin ) => {
1203+ match args[ 0 ] . expect_ty ( ) . kind ( ) {
1204+ ty:: Ref ( _, ty, hir:: Mutability :: Mut ) => * ty,
1205+ _ => {
1206+ return None ;
1207+ }
1208+ }
1209+ }
1210+ _ => return None ,
1211+ } ;
1212+
1213+ let region = self . tcx . lifetimes . re_erased ;
1214+ let autopin_ty = Ty :: new_pinned_ref ( self . tcx , region, inner_ty, hir:: Mutability :: Not ) ;
1215+ self . pick_method ( autopin_ty, unstable_candidates) . map ( |r| {
1216+ r. map ( |mut pick| {
1217+ pick. autoderefs = step. autoderefs ;
1218+ pick. autoref_or_ptr_adjustment =
1219+ Some ( AutorefOrPtrAdjustment :: ReborrowPin ( hir:: Mutability :: Not ) ) ;
1220+ pick
1221+ } )
1222+ } )
1223+ }
1224+
11781225 /// If `self_ty` is `*mut T` then this picks `*const T` methods. The reason why we have a
11791226 /// special case for this is because going from `*mut T` to `*const T` with autoderefs and
11801227 /// autorefs would require dereferencing the pointer, which is not safe.
0 commit comments