Skip to content

Commit e57789f

Browse files
committed
Implement pinned borrows
1 parent 73c0ae6 commit e57789f

File tree

15 files changed

+334
-10
lines changed

15 files changed

+334
-10
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,10 @@ pub enum BorrowKind {
864864
/// The resulting type is either `*const T` or `*mut T`
865865
/// where `T = typeof($expr)`.
866866
Raw,
867+
/// A pinned borrow, `&pin const $expr` or `&pin mut $expr`.
868+
/// The resulting type is either `Pin<&'a T>` or `Pin<&'a mut T>`
869+
/// where `T = typeof($expr)` and `'a` is some lifetime.
870+
Pin,
867871
}
868872

869873
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ impl<'a> State<'a> {
340340
self.word_nbsp("raw");
341341
self.print_mutability(mutability, true);
342342
}
343+
ast::BorrowKind::Pin => {
344+
self.word_nbsp("pin");
345+
self.print_mutability(mutability, true);
346+
}
343347
}
344348
self.print_expr_cond_paren(
345349
expr,

compiler/rustc_const_eval/src/check_consts/ops.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -596,11 +596,13 @@ impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow {
596596
kind: ccx.const_kind(),
597597
teach: ccx.tcx.sess.teach(E0764),
598598
}),
599-
hir::BorrowKind::Ref => ccx.dcx().create_err(errors::MutableRefEscaping {
600-
span,
601-
kind: ccx.const_kind(),
602-
teach: ccx.tcx.sess.teach(E0764),
603-
}),
599+
hir::BorrowKind::Ref | hir::BorrowKind::Pin => {
600+
ccx.dcx().create_err(errors::MutableRefEscaping {
601+
span,
602+
kind: ccx.const_kind(),
603+
teach: ccx.tcx.sess.teach(E0764),
604+
})
605+
}
604606
}
605607
}
606608
}

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,10 @@ impl<'a> State<'a> {
13381338
self.word_nbsp("raw");
13391339
self.print_mutability(mutability, true);
13401340
}
1341+
hir::BorrowKind::Pin => {
1342+
self.word_nbsp("pin");
1343+
self.print_mutability(mutability, true);
1344+
}
13411345
}
13421346
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Prefix);
13431347
}

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
690690
let region = self.next_region_var(infer::BorrowRegion(expr.span));
691691
Ty::new_ref(self.tcx, region, ty, mutbl)
692692
}
693+
hir::BorrowKind::Pin => {
694+
// See comments in the `hir::BorrowKind::Ref` arm above.
695+
let region = self.next_region_var(infer::BorrowRegion(expr.span));
696+
Ty::new_pinned_ref(self.tcx, region, ty, mutbl)
697+
}
693698
}
694699
}
695700

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,31 @@ impl<'tcx> Cx<'tcx> {
474474
ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) }
475475
}
476476

477+
// make `&pin mut $expr` and `&pin const $expr` into `Pin { __pointer: &mut $expr }`
478+
// and `Pin { __pointer: &$expr }`
479+
hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg) => match expr_ty.kind() {
480+
&ty::Adt(adt_def, args)
481+
if tcx.is_lang_item(adt_def.did(), rustc_hir::LangItem::Pin) =>
482+
{
483+
let arg = self.mirror_expr(arg);
484+
let expr = self.thir.exprs.push(Expr {
485+
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
486+
ty: args.type_at(0),
487+
span: expr.span,
488+
kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg },
489+
});
490+
ExprKind::Adt(Box::new(AdtExpr {
491+
adt_def,
492+
variant_index: FIRST_VARIANT,
493+
args,
494+
fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
495+
user_ty: None,
496+
base: AdtExprBase::None,
497+
}))
498+
}
499+
_ => span_bug!(expr.span, "unexpected type for pinned borrow: {:?}", expr_ty),
500+
},
501+
477502
hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
478503

479504
hir::ExprKind::Assign(lhs, rhs, _) => {

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,10 @@ impl<'a> Parser<'a> {
871871
assert!(found_raw);
872872
let mutability = self.parse_const_or_mut().unwrap();
873873
(ast::BorrowKind::Raw, mutability)
874+
} else if let Some((ast::Pinnedness::Pinned, mutbl)) = self.parse_pin_and_mut() {
875+
// `pin [ const | mut ]`.
876+
// `pin` has been gated in `self.parse_pin_and_mut()` so we don't need to gate it here.
877+
(ast::BorrowKind::Pin, mutbl)
874878
} else {
875879
// `mut?`
876880
(ast::BorrowKind::Ref, self.parse_mutability())

src/tools/rustfmt/src/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,8 +2285,10 @@ fn rewrite_expr_addrof(
22852285
let operator_str = match (mutability, borrow_kind) {
22862286
(ast::Mutability::Not, ast::BorrowKind::Ref) => "&",
22872287
(ast::Mutability::Not, ast::BorrowKind::Raw) => "&raw const ",
2288+
(ast::Mutability::Not, ast::BorrowKind::Pin) => "&pin const ",
22882289
(ast::Mutability::Mut, ast::BorrowKind::Ref) => "&mut ",
22892290
(ast::Mutability::Mut, ast::BorrowKind::Raw) => "&raw mut ",
2291+
(ast::Mutability::Mut, ast::BorrowKind::Pin) => "&pin mut ",
22902292
};
22912293
rewrite_unary_prefix(context, operator_str, expr, shape)
22922294
}

src/tools/rustfmt/tests/source/pin_sugar.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@ fn g<'a>(x: & 'a pin const i32) {}
88
fn h<'a>(x: & 'a pin
99
mut i32) {}
1010
fn i(x: &pin mut i32) {}
11+
12+
fn borrows() {
13+
let mut foo = 0_i32;
14+
let x: Pin<&mut _> = & pin
15+
mut foo;
16+
17+
let x: Pin<&_> = &
18+
pin const
19+
foo;
20+
}

src/tools/rustfmt/tests/target/pin_sugar.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ fn f(x: &pin const i32) {}
77
fn g<'a>(x: &'a pin const i32) {}
88
fn h<'a>(x: &'a pin mut i32) {}
99
fn i(x: &pin mut i32) {}
10+
11+
fn borrows() {
12+
let mut foo = 0_i32;
13+
let x: Pin<&mut _> = &pin mut foo;
14+
15+
let x: Pin<&_> = &pin const foo;
16+
}

0 commit comments

Comments
 (0)