@@ -74,6 +74,7 @@ impl<'tcx> Cx<'tcx> {
74
74
self . thir . exprs . push ( expr)
75
75
}
76
76
77
+ #[ instrument( level = "trace" , skip( self , expr, span) ) ]
77
78
fn apply_adjustment (
78
79
& mut self ,
79
80
hir_expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -146,6 +147,67 @@ impl<'tcx> Cx<'tcx> {
146
147
ExprKind :: RawBorrow { mutability, arg : self . thir . exprs . push ( expr) }
147
148
}
148
149
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
+ }
149
211
} ;
150
212
151
213
Expr { temp_lifetime, ty : adjustment. target , span, kind }
@@ -1014,7 +1076,7 @@ impl<'tcx> Cx<'tcx> {
1014
1076
1015
1077
// Reconstruct the output assuming it's a reference with the
1016
1078
// 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)`.
1018
1080
let ty:: Ref ( region, _, mutbl) = * self . thir [ args[ 0 ] ] . ty . kind ( ) else {
1019
1081
span_bug ! ( span, "overloaded_place: receiver is not a reference" ) ;
1020
1082
} ;
0 commit comments