Skip to content

Commit cc5e4cb

Browse files
committed
Move the place in &pin mut $place when !Unpin to ensure soundness
1 parent bf435bd commit cc5e4cb

File tree

8 files changed

+557
-190
lines changed

8 files changed

+557
-190
lines changed

compiler/rustc_mir_build/src/thir/cx/expr.rs

+31-7
Original file line numberDiff line numberDiff line change
@@ -477,15 +477,39 @@ impl<'tcx> ThirBuildCx<'tcx> {
477477
}
478478

479479
// Make `&pin mut $expr` and `&pin const $expr` into
480-
// `Pin { __pointer: &mut $expr }` and `Pin { __pointer: &$expr }`.
481-
hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg) => match expr_ty.kind() {
482-
&ty::Adt(adt_def, args)
483-
if tcx.is_lang_item(adt_def.did(), rustc_hir::LangItem::Pin) =>
484-
{
485-
let arg = self.mirror_expr(arg);
480+
// `Pin { __pointer: &mut { $expr } }` and `Pin { __pointer: &$expr }`.
481+
hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg_expr) => match expr_ty.kind() {
482+
&ty::Adt(adt_def, args) if tcx.is_lang_item(adt_def.did(), hir::LangItem::Pin) => {
483+
let ty = args.type_at(0);
484+
let arg_ty = self.typeck_results.expr_ty(arg_expr);
485+
let mut arg = self.mirror_expr(arg_expr);
486+
// For `&pin mut $place` where `$place` is not `Unpin`, move the place
487+
// `$place` to ensure it will not be used afterwards.
488+
if mutbl.is_mut() && !arg_ty.is_unpin(self.tcx, self.typing_env) {
489+
let block = self.thir.blocks.push(Block {
490+
targeted_by_break: false,
491+
region_scope: region::Scope {
492+
local_id: arg_expr.hir_id.local_id,
493+
data: region::ScopeData::Node,
494+
},
495+
span: arg_expr.span,
496+
stmts: Box::new([]),
497+
expr: Some(arg),
498+
safety_mode: BlockSafety::Safe,
499+
});
500+
let (temp_lifetime, backwards_incompatible) = self
501+
.rvalue_scopes
502+
.temporary_scope(self.region_scope_tree, arg_expr.hir_id.local_id);
503+
arg = self.thir.exprs.push(Expr {
504+
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
505+
ty: arg_ty,
506+
span: arg_expr.span,
507+
kind: ExprKind::Block { block },
508+
});
509+
}
486510
let expr = self.thir.exprs.push(Expr {
487511
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
488-
ty: args.type_at(0),
512+
ty,
489513
span: expr.span,
490514
kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg },
491515
});

tests/pretty/pin-ergonomics.rs

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ fn bar() {
3030
foo_const(x);
3131

3232
let x: Pin<&_> = &pin const Foo;
33-
3433
foo_const(x);
3534
foo_const(x);
3635
}

tests/ui/pin-ergonomics/borrow-mut-xor-share.rs

-59
This file was deleted.

tests/ui/pin-ergonomics/borrow-mut-xor-share.stderr

-121
This file was deleted.

0 commit comments

Comments
 (0)