@@ -1113,6 +1113,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1113
1113
unstable_candidates. as_deref_mut ( ) ,
1114
1114
)
1115
1115
} )
1116
+ . or_else ( || {
1117
+ self . pick_reborrow_pin_method (
1118
+ step,
1119
+ self_ty,
1120
+ unstable_candidates. as_deref_mut ( ) ,
1121
+ )
1122
+ } )
1116
1123
} )
1117
1124
} )
1118
1125
}
@@ -1147,7 +1154,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1147
1154
} )
1148
1155
}
1149
1156
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
+ {
1151
1161
// make sure this is a pinned reference (and not a `Pin<Box>` or something)
1152
1162
if let ty:: Ref ( _, _, mutbl) = args[ 0 ] . expect_ty ( ) . kind ( ) {
1153
1163
pick. autoref_or_ptr_adjustment =
@@ -1186,6 +1196,43 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1186
1196
} )
1187
1197
}
1188
1198
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
+
1189
1236
/// If `self_ty` is `*mut T` then this picks `*const T` methods. The reason why we have a
1190
1237
/// special case for this is because going from `*mut T` to `*const T` with autoderefs and
1191
1238
/// autorefs would require dereferencing the pointer, which is not safe.
0 commit comments