Skip to content

Commit 7010181

Browse files
committed
Implement pinned borrows, part of pin_ergonomics
1 parent 59a9b9e commit 7010181

File tree

15 files changed

+371
-15
lines changed

15 files changed

+371
-15
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,10 @@ pub enum BorrowKind {
877877
/// The resulting type is either `*const T` or `*mut T`
878878
/// where `T = typeof($expr)`.
879879
Raw,
880+
/// A pinned borrow, `&pin const $expr` or `&pin mut $expr`.
881+
/// The resulting type is either `Pin<&'a T>` or `Pin<&'a mut T>`
882+
/// where `T = typeof($expr)` and `'a` is some lifetime.
883+
Pin,
880884
}
881885

882886
#[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
@@ -1417,6 +1417,10 @@ impl<'a> State<'a> {
14171417
self.word_nbsp("raw");
14181418
self.print_mutability(mutability, true);
14191419
}
1420+
hir::BorrowKind::Pin => {
1421+
self.word_nbsp("pin");
1422+
self.print_mutability(mutability, true);
1423+
}
14201424
}
14211425
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Prefix);
14221426
}

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
@@ -18,3 +18,13 @@ impl Foo {
1818
mut self) {}
1919
fn i(&pin mut self) {}
2020
}
21+
22+
fn borrows() {
23+
let mut foo = 0_i32;
24+
let x: Pin<&mut _> = & pin
25+
mut foo;
26+
27+
let x: Pin<&_> = &
28+
pin const
29+
foo;
30+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ impl Foo {
1616
fn h<'a>(&'a pin mut self) {}
1717
fn i(&pin mut self) {}
1818
}
19+
20+
fn borrows() {
21+
let mut foo = 0_i32;
22+
let x: Pin<&mut _> = &pin mut foo;
23+
24+
let x: Pin<&_> = &pin const foo;
25+
}

0 commit comments

Comments
 (0)