@@ -1113,6 +1113,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11131113 unstable_candidates. as_deref_mut ( ) ,
11141114 )
11151115 } )
1116+ . or_else ( || {
1117+ self . pick_reborrow_pin_method (
1118+ step,
1119+ self_ty,
1120+ unstable_candidates. as_deref_mut ( ) ,
1121+ )
1122+ } )
11161123 } )
11171124 } )
11181125 }
@@ -1147,7 +1154,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11471154 } )
11481155 }
11491156
1150- ty:: Adt ( def, args) if self . tcx . is_lang_item ( def. did ( ) , hir:: LangItem :: Pin ) => {
1157+ ty:: Adt ( def, args)
1158+ if self . tcx . features ( ) . pin_ergonomics
1159+ && self . tcx . is_lang_item ( def. did ( ) , hir:: LangItem :: Pin ) =>
1160+ {
11511161 // make sure this is a pinned reference (and not a `Pin<Box>` or something)
11521162 if let ty:: Ref ( _, _, mutbl) = args[ 0 ] . expect_ty ( ) . kind ( ) {
11531163 pick. autoref_or_ptr_adjustment =
@@ -1186,6 +1196,43 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11861196 } )
11871197 }
11881198
1199+ /// Looks for applicable methods if we reborrow a `Pin<&mut T>` as a `Pin<&T>`.
1200+ #[ instrument( level = "debug" , skip( self , step, unstable_candidates) ) ]
1201+ fn pick_reborrow_pin_method (
1202+ & self ,
1203+ step : & CandidateStep < ' tcx > ,
1204+ self_ty : Ty < ' tcx > ,
1205+ unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
1206+ ) -> Option < PickResult < ' tcx > > {
1207+ if !self . tcx . features ( ) . pin_ergonomics {
1208+ return None ;
1209+ }
1210+
1211+ // make sure self is a Pin<&mut T>
1212+ let inner_ty = match self_ty. kind ( ) {
1213+ ty:: Adt ( def, args) if self . tcx . is_lang_item ( def. did ( ) , hir:: LangItem :: Pin ) => {
1214+ match args[ 0 ] . expect_ty ( ) . kind ( ) {
1215+ ty:: Ref ( _, ty, hir:: Mutability :: Mut ) => * ty,
1216+ _ => {
1217+ return None ;
1218+ }
1219+ }
1220+ }
1221+ _ => return None ,
1222+ } ;
1223+
1224+ let region = self . tcx . lifetimes . re_erased ;
1225+ let autopin_ty = Ty :: new_pinned_ref ( self . tcx , region, inner_ty, hir:: Mutability :: Not ) ;
1226+ self . pick_method ( autopin_ty, unstable_candidates) . map ( |r| {
1227+ r. map ( |mut pick| {
1228+ pick. autoderefs = step. autoderefs ;
1229+ pick. autoref_or_ptr_adjustment =
1230+ Some ( AutorefOrPtrAdjustment :: ReborrowPin ( hir:: Mutability :: Not ) ) ;
1231+ pick
1232+ } )
1233+ } )
1234+ }
1235+
11891236 /// If `self_ty` is `*mut T` then this picks `*const T` methods. The reason why we have a
11901237 /// special case for this is because going from `*mut T` to `*const T` with autoderefs and
11911238 /// autorefs would require dereferencing the pointer, which is not safe.
0 commit comments