@@ -5,9 +5,8 @@ use std::ops::Deref;
55
66use rustc_data_structures:: fx:: FxHashSet ;
77use rustc_errors:: Applicability ;
8- use rustc_hir as hir;
98use rustc_hir:: def:: DefKind ;
10- use rustc_hir:: HirId ;
9+ use rustc_hir:: { self as hir , HirId } ;
1110use rustc_hir_analysis:: autoderef:: { self , Autoderef } ;
1211use rustc_infer:: infer:: canonical:: { Canonical , OriginalQueryValues , QueryResponse } ;
1312use rustc_infer:: infer:: { self , DefineOpaqueTypes , InferOk , TyCtxtInferExt } ;
@@ -136,7 +135,7 @@ enum ProbeResult {
136135/// `mut`), or it has type `*mut T` and we convert it to `*const T`.
137136#[ derive( Debug , PartialEq , Copy , Clone ) ]
138137pub ( crate ) enum AutorefOrPtrAdjustment {
139- /// Receiver has type `T`, add `&` or `&mut` (it `T` is `mut`), and maybe also "unsize" it.
138+ /// Receiver has type `T`, add `&` or `&mut` (if `T` is `mut`), and maybe also "unsize" it.
140139 /// Unsizing is used to convert a `[T; N]` to `[T]`, which only makes sense when autorefing.
141140 Autoref {
142141 mutbl : hir:: Mutability ,
@@ -147,13 +146,17 @@ pub(crate) enum AutorefOrPtrAdjustment {
147146 } ,
148147 /// Receiver has type `*mut T`, convert to `*const T`
149148 ToConstPtr ,
149+
150+ /// Reborrow a `Pin<&mut T>` or `Pin<&T>`.
151+ ReborrowPin ( hir:: Mutability ) ,
150152}
151153
152154impl AutorefOrPtrAdjustment {
153155 fn get_unsize ( & self ) -> bool {
154156 match self {
155157 AutorefOrPtrAdjustment :: Autoref { mutbl : _, unsize } => * unsize,
156158 AutorefOrPtrAdjustment :: ToConstPtr => false ,
159+ AutorefOrPtrAdjustment :: ReborrowPin ( _) => false ,
157160 }
158161 }
159162}
@@ -1123,13 +1126,25 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11231126 r. map ( |mut pick| {
11241127 pick. autoderefs = step. autoderefs ;
11251128
1126- // Insert a `&*` or `&mut *` if this is a reference type:
1127- if let ty:: Ref ( _, _, mutbl) = * step. self_ty . value . value . kind ( ) {
1128- pick. autoderefs += 1 ;
1129- pick. autoref_or_ptr_adjustment = Some ( AutorefOrPtrAdjustment :: Autoref {
1130- mutbl,
1131- unsize : pick. autoref_or_ptr_adjustment . is_some_and ( |a| a. get_unsize ( ) ) ,
1132- } )
1129+ match * step. self_ty . value . value . kind ( ) {
1130+ // Insert a `&*` or `&mut *` if this is a reference type:
1131+ ty:: Ref ( _, _, mutbl) => {
1132+ pick. autoderefs += 1 ;
1133+ pick. autoref_or_ptr_adjustment = Some ( AutorefOrPtrAdjustment :: Autoref {
1134+ mutbl,
1135+ unsize : pick. autoref_or_ptr_adjustment . is_some_and ( |a| a. get_unsize ( ) ) ,
1136+ } )
1137+ }
1138+
1139+ ty:: Adt ( def, args) if self . tcx . is_lang_item ( def. did ( ) , hir:: LangItem :: Pin ) => {
1140+ // make sure this is a pinned reference (and not a `Pin<Box>` or something)
1141+ if let ty:: Ref ( _, _, mutbl) = args[ 0 ] . expect_ty ( ) . kind ( ) {
1142+ pick. autoref_or_ptr_adjustment =
1143+ Some ( AutorefOrPtrAdjustment :: ReborrowPin ( * mutbl) ) ;
1144+ }
1145+ }
1146+
1147+ _ => ( ) ,
11331148 }
11341149
11351150 pick
0 commit comments