@@ -74,6 +74,7 @@ impl<'tcx> Cx<'tcx> {
7474 self . thir . exprs . push ( expr)
7575 }
7676
77+ #[ instrument( level = "trace" , skip( self , expr, span) ) ]
7778 fn apply_adjustment (
7879 & mut self ,
7980 hir_expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -146,6 +147,67 @@ impl<'tcx> Cx<'tcx> {
146147 ExprKind :: RawBorrow { mutability, arg : self . thir . exprs . push ( expr) }
147148 }
148149 Adjust :: DynStar => ExprKind :: Cast { source : self . thir . exprs . push ( expr) } ,
150+ Adjust :: ReborrowPin ( region, mutbl) => {
151+ debug ! ( "apply ReborrowPin adjustment" ) ;
152+ // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
153+
154+ // We'll need these types later on
155+ let pin_ty_args = match expr. ty . kind ( ) {
156+ ty:: Adt ( _, args) => args,
157+ _ => bug ! ( "ReborrowPin with non-Pin type" ) ,
158+ } ;
159+ let pin_ty = pin_ty_args. iter ( ) . next ( ) . unwrap ( ) . expect_ty ( ) ;
160+ let ptr_target_ty = match pin_ty. kind ( ) {
161+ ty:: Ref ( _, ty, _) => * ty,
162+ _ => bug ! ( "ReborrowPin with non-Ref type" ) ,
163+ } ;
164+
165+ // pointer = ($expr).__pointer
166+ let pointer_target = ExprKind :: Field {
167+ lhs : self . thir . exprs . push ( expr) ,
168+ variant_index : FIRST_VARIANT ,
169+ name : FieldIdx :: from ( 0u32 ) ,
170+ } ;
171+ let arg = Expr { temp_lifetime, ty : pin_ty, span, kind : pointer_target } ;
172+ let arg = self . thir . exprs . push ( arg) ;
173+
174+ // arg = *pointer
175+ let expr = ExprKind :: Deref { arg } ;
176+ let arg = self . thir . exprs . push ( Expr {
177+ temp_lifetime,
178+ ty : ptr_target_ty,
179+ span,
180+ kind : expr,
181+ } ) ;
182+
183+ // expr = &mut target
184+ let borrow_kind = match mutbl {
185+ hir:: Mutability :: Mut => BorrowKind :: Mut { kind : mir:: MutBorrowKind :: Default } ,
186+ hir:: Mutability :: Not => BorrowKind :: Shared ,
187+ } ;
188+ let new_pin_target = Ty :: new_ref ( self . tcx , region, ptr_target_ty, mutbl) ;
189+ let expr = self . thir . exprs . push ( Expr {
190+ temp_lifetime,
191+ ty : new_pin_target,
192+ span,
193+ kind : ExprKind :: Borrow { borrow_kind, arg } ,
194+ } ) ;
195+
196+ // kind = Pin { __pointer: pointer }
197+ let pin_did = self . tcx . require_lang_item ( rustc_hir:: LangItem :: Pin , Some ( span) ) ;
198+ let args = self . tcx . mk_args ( & [ new_pin_target. into ( ) ] ) ;
199+ let kind = ExprKind :: Adt ( Box :: new ( AdtExpr {
200+ adt_def : self . tcx . adt_def ( pin_did) ,
201+ variant_index : FIRST_VARIANT ,
202+ args,
203+ fields : Box :: new ( [ FieldExpr { name : FieldIdx :: from ( 0u32 ) , expr } ] ) ,
204+ user_ty : None ,
205+ base : None ,
206+ } ) ) ;
207+
208+ debug ! ( ?kind) ;
209+ kind
210+ }
149211 } ;
150212
151213 Expr { temp_lifetime, ty : adjustment. target , span, kind }
@@ -1014,7 +1076,7 @@ impl<'tcx> Cx<'tcx> {
10141076
10151077 // Reconstruct the output assuming it's a reference with the
10161078 // same region and mutability as the receiver. This holds for
1017- // `Deref(Mut)::Deref (_mut)` and `Index(Mut)::index(_mut)`.
1079+ // `Deref(Mut)::deref (_mut)` and `Index(Mut)::index(_mut)`.
10181080 let ty:: Ref ( region, _, mutbl) = * self . thir [ args[ 0 ] ] . ty . kind ( ) else {
10191081 span_bug ! ( span, "overloaded_place: receiver is not a reference" ) ;
10201082 } ;
0 commit comments