@@ -1102,6 +1102,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1102
1102
unstable_candidates. as_deref_mut ( ) ,
1103
1103
)
1104
1104
} )
1105
+ . or_else ( || {
1106
+ self . pick_reborrow_pin_method (
1107
+ step,
1108
+ self_ty,
1109
+ unstable_candidates. as_deref_mut ( ) ,
1110
+ )
1111
+ } )
1105
1112
} )
1106
1113
} )
1107
1114
}
@@ -1136,7 +1143,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1136
1143
} )
1137
1144
}
1138
1145
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
+ {
1140
1150
// make sure this is a pinned reference (and not a `Pin<Box>` or something)
1141
1151
if let ty:: Ref ( _, _, mutbl) = args[ 0 ] . expect_ty ( ) . kind ( ) {
1142
1152
pick. autoref_or_ptr_adjustment =
@@ -1175,6 +1185,43 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1175
1185
} )
1176
1186
}
1177
1187
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
+
1178
1225
/// If `self_ty` is `*mut T` then this picks `*const T` methods. The reason why we have a
1179
1226
/// special case for this is because going from `*mut T` to `*const T` with autoderefs and
1180
1227
/// autorefs would require dereferencing the pointer, which is not safe.
0 commit comments