Skip to content

Commit 1c081ea

Browse files
committed
Implement pinned borrows, part of pin_ergonomics
1 parent 30508fa commit 1c081ea

File tree

15 files changed

+441
-10
lines changed

15 files changed

+441
-10
lines changed

compiler/rustc_ast/src/ast.rs

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

871875
#[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
@@ -339,6 +339,10 @@ impl<'a> State<'a> {
339339
self.word_nbsp("raw");
340340
self.print_mutability(mutability, true);
341341
}
342+
ast::BorrowKind::Pin => {
343+
self.word_nbsp("pin");
344+
self.print_mutability(mutability, true);
345+
}
342346
}
343347
self.print_expr_cond_paren(
344348
expr,

compiler/rustc_const_eval/src/check_consts/ops.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -619,11 +619,13 @@ impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow {
619619
kind: ccx.const_kind(),
620620
teach: ccx.tcx.sess.teach(E0764),
621621
}),
622-
hir::BorrowKind::Ref => ccx.dcx().create_err(errors::MutableRefEscaping {
623-
span,
624-
kind: ccx.const_kind(),
625-
teach: ccx.tcx.sess.teach(E0764),
626-
}),
622+
hir::BorrowKind::Ref | hir::BorrowKind::Pin => {
623+
ccx.dcx().create_err(errors::MutableRefEscaping {
624+
span,
625+
kind: ccx.const_kind(),
626+
teach: ccx.tcx.sess.teach(E0764),
627+
})
628+
}
627629
}
628630
}
629631
}

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,10 @@ impl<'a> State<'a> {
13431343
self.word_nbsp("raw");
13441344
self.print_mutability(mutability, true);
13451345
}
1346+
hir::BorrowKind::Pin => {
1347+
self.word_nbsp("pin");
1348+
self.print_mutability(mutability, true);
1349+
}
13461350
}
13471351
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Prefix);
13481352
}

compiler/rustc_hir_typeck/src/expr.rs

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

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

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

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

477502
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
@@ -836,6 +836,10 @@ impl<'a> Parser<'a> {
836836
assert!(found_raw);
837837
let mutability = self.parse_const_or_mut().unwrap();
838838
(ast::BorrowKind::Raw, mutability)
839+
} else if let Some((ast::Pinnedness::Pinned, mutbl)) = self.parse_pin_and_mut() {
840+
// `pin [ const | mut ]`.
841+
// `pin` has been gated in `self.parse_pin_and_mut()` so we don't need to gate it here.
842+
(ast::BorrowKind::Pin, mutbl)
839843
} else {
840844
// `mut?`
841845
(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)