diff options
Diffstat (limited to 'compiler/rustc_mir_build/src/thir/cx/expr.rs')
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/cx/expr.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 3baeccf6409..764b7efe2a3 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -479,6 +479,55 @@ impl<'tcx> ThirBuildCx<'tcx> { ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) } } + // Make `&pin mut $expr` and `&pin const $expr` into + // `Pin { __pointer: &mut { $expr } }` and `Pin { __pointer: &$expr }`. + hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg_expr) => match expr_ty.kind() { + &ty::Adt(adt_def, args) if tcx.is_lang_item(adt_def.did(), hir::LangItem::Pin) => { + let ty = args.type_at(0); + let arg_ty = self.typeck_results.expr_ty(arg_expr); + let mut arg = self.mirror_expr(arg_expr); + // For `&pin mut $place` where `$place` is not `Unpin`, move the place + // `$place` to ensure it will not be used afterwards. + if mutbl.is_mut() && !arg_ty.is_unpin(self.tcx, self.typing_env) { + let block = self.thir.blocks.push(Block { + targeted_by_break: false, + region_scope: region::Scope { + local_id: arg_expr.hir_id.local_id, + data: region::ScopeData::Node, + }, + span: arg_expr.span, + stmts: Box::new([]), + expr: Some(arg), + safety_mode: BlockSafety::Safe, + }); + let (temp_lifetime, backwards_incompatible) = self + .rvalue_scopes + .temporary_scope(self.region_scope_tree, arg_expr.hir_id.local_id); + arg = self.thir.exprs.push(Expr { + temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible }, + ty: arg_ty, + span: arg_expr.span, + kind: ExprKind::Block { block }, + }); + } + let expr = self.thir.exprs.push(Expr { + temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible }, + ty, + span: expr.span, + kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg }, + }); + ExprKind::Adt(Box::new(AdtExpr { + adt_def, + variant_index: FIRST_VARIANT, + args, + fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]), + user_ty: None, + base: AdtExprBase::None, + })) + } + _ => span_bug!(expr.span, "unexpected type for pinned borrow: {:?}", expr_ty), + }, + hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) }, hir::ExprKind::Assign(lhs, rhs, _) => { |
