@@ -147,50 +147,64 @@ impl<'tcx> Cx<'tcx> {
147
147
ExprKind :: RawBorrow { mutability, arg : self . thir . exprs . push ( expr) }
148
148
}
149
149
Adjust :: DynStar => ExprKind :: Cast { source : self . thir . exprs . push ( expr) } ,
150
- Adjust :: ReborrowPin ( AutoBorrow :: Ref ( region, m ) ) => {
150
+ Adjust :: ReborrowPin ( region, mutbl ) => {
151
151
debug ! ( "apply ReborrowPin adjustment" ) ;
152
- match m {
153
- AutoBorrowMutability :: Mut { .. } => {
154
- // Rewrite `$expr` as `Pin::as_mut(&mut $expr)`
155
- let as_mut_method =
156
- self . tcx ( ) . require_lang_item ( rustc_hir:: LangItem :: PinAsMut , Some ( span) ) ;
157
- let pin_ty_args = match expr. ty . kind ( ) {
158
- ty:: Adt ( _, args) => args,
159
- _ => bug ! ( "ReborrowPin with non-Pin type" ) ,
160
- } ;
161
- let as_mut_ty =
162
- Ty :: new_fn_def ( self . tcx , as_mut_method, pin_ty_args. into_iter ( ) ) ;
163
-
164
- let ty = Ty :: new_ref ( self . tcx , region, expr. ty , ty:: Mutability :: Mut ) ;
165
- let arg = ExprKind :: Borrow {
166
- borrow_kind : BorrowKind :: Mut { kind : mir:: MutBorrowKind :: Default } ,
167
- arg : self . thir . exprs . push ( expr) ,
168
- } ;
169
- debug ! ( ?arg, "borrow arg" ) ;
170
- let arg = self . thir . exprs . push ( Expr { temp_lifetime, ty, span, kind : arg } ) ;
171
-
172
- let kind = ExprKind :: Call {
173
- ty : as_mut_ty,
174
- fun : self . thir . exprs . push ( Expr {
175
- temp_lifetime,
176
- ty : as_mut_ty,
177
- span,
178
- kind : ExprKind :: ZstLiteral { user_ty : None } ,
179
- } ) ,
180
- args : Box :: new ( [ arg] ) ,
181
- from_hir_call : true ,
182
- fn_span : span,
183
- } ;
184
- debug ! ( ?kind) ;
185
- kind
186
- }
187
- AutoBorrowMutability :: Not => {
188
- // FIXME: We need to call Pin::as_ref on the expression
189
- bug ! ( "ReborrowPin with shared reference is not implemented yet" )
190
- }
191
- }
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 expr = self . thir . exprs . push ( Expr {
185
+ temp_lifetime,
186
+ ty : Ty :: new_ref ( self . tcx , region, ptr_target_ty, mutbl) ,
187
+ span,
188
+ kind : ExprKind :: Borrow {
189
+ borrow_kind : BorrowKind :: Mut { kind : mir:: MutBorrowKind :: Default } ,
190
+ arg,
191
+ } ,
192
+ } ) ;
193
+
194
+ // kind = Pin { __pointer: pointer }
195
+ let pin_did = self . tcx . require_lang_item ( rustc_hir:: LangItem :: Pin , Some ( span) ) ;
196
+ let kind = ExprKind :: Adt ( Box :: new ( AdtExpr {
197
+ adt_def : self . tcx . adt_def ( pin_did) ,
198
+ variant_index : FIRST_VARIANT ,
199
+ args : pin_ty_args,
200
+ fields : Box :: new ( [ FieldExpr { name : FieldIdx :: from ( 0u32 ) , expr } ] ) ,
201
+ user_ty : None ,
202
+ base : None ,
203
+ } ) ) ;
204
+
205
+ debug ! ( ?kind) ;
206
+ kind
192
207
}
193
- Adjust :: ReborrowPin ( AutoBorrow :: RawPtr ( _) ) => bug ! ( "ReborrowPin with raw pointer" ) ,
194
208
} ;
195
209
196
210
Expr { temp_lifetime, ty : adjustment. target , span, kind }
@@ -1059,7 +1073,7 @@ impl<'tcx> Cx<'tcx> {
1059
1073
1060
1074
// Reconstruct the output assuming it's a reference with the
1061
1075
// same region and mutability as the receiver. This holds for
1062
- // `Deref(Mut)::Deref (_mut)` and `Index(Mut)::index(_mut)`.
1076
+ // `Deref(Mut)::deref (_mut)` and `Index(Mut)::index(_mut)`.
1063
1077
let ty:: Ref ( region, _, mutbl) = * self . thir [ args[ 0 ] ] . ty . kind ( ) else {
1064
1078
span_bug ! ( span, "overloaded_place: receiver is not a reference" ) ;
1065
1079
} ;
0 commit comments