Skip to content

Commit 16ddefa

Browse files
committed
Project pinned references to pinned fields
1 parent c9ca4f8 commit 16ddefa

File tree

81 files changed

+937
-764
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+937
-764
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -719,14 +719,14 @@ pub struct PatField {
719719
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
720720
#[derive(Encodable, Decodable, HashStable_Generic)]
721721
pub enum ByRef {
722-
Yes(Mutability),
722+
Yes(Pinnedness, Mutability),
723723
No,
724724
}
725725

726726
impl ByRef {
727727
#[must_use]
728728
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
729-
if let ByRef::Yes(old_mutbl) = &mut self {
729+
if let ByRef::Yes(_, old_mutbl) = &mut self {
730730
*old_mutbl = cmp::min(*old_mutbl, mutbl);
731731
}
732732
self
@@ -744,20 +744,33 @@ pub struct BindingMode(pub ByRef, pub Mutability);
744744

745745
impl BindingMode {
746746
pub const NONE: Self = Self(ByRef::No, Mutability::Not);
747-
pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
747+
pub const REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Not);
748+
pub const REF_PIN: Self =
749+
Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Not);
748750
pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
749-
pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
750-
pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
751-
pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
751+
pub const REF_MUT: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Not);
752+
pub const REF_PIN_MUT: Self =
753+
Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Not);
754+
pub const MUT_REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Mut);
755+
pub const MUT_REF_PIN: Self =
756+
Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Mut);
757+
pub const MUT_REF_MUT: Self =
758+
Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Mut);
759+
pub const MUT_REF_PIN_MUT: Self =
760+
Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Mut);
752761

753762
pub fn prefix_str(self) -> &'static str {
754763
match self {
755764
Self::NONE => "",
756765
Self::REF => "ref ",
766+
Self::REF_PIN => "ref pin const ",
757767
Self::MUT => "mut ",
758768
Self::REF_MUT => "ref mut ",
769+
Self::REF_PIN_MUT => "ref pin mut ",
759770
Self::MUT_REF => "mut ref ",
771+
Self::MUT_REF_PIN => "mut ref pin ",
760772
Self::MUT_REF_MUT => "mut ref mut ",
773+
Self::MUT_REF_PIN_MUT => "mut ref pin mut ",
761774
}
762775
}
763776
}

compiler/rustc_ast_ir/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,10 @@ pub enum Pinnedness {
101101
Not,
102102
Pinned,
103103
}
104+
105+
impl Pinnedness {
106+
/// Return `true` if self is pinned
107+
pub fn is_pinned(self) -> bool {
108+
matches!(self, Self::Pinned)
109+
}
110+
}

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1624,10 +1624,15 @@ impl<'a> State<'a> {
16241624
if mutbl.is_mut() {
16251625
self.word_nbsp("mut");
16261626
}
1627-
if let ByRef::Yes(rmutbl) = by_ref {
1627+
if let ByRef::Yes(pinnedness, rmutbl) = by_ref {
16281628
self.word_nbsp("ref");
1629+
if pinnedness.is_pinned() {
1630+
self.word_nbsp("pin");
1631+
}
16291632
if rmutbl.is_mut() {
16301633
self.word_nbsp("mut");
1634+
} else if pinnedness.is_pinned() {
1635+
self.word_nbsp("const");
16311636
}
16321637
}
16331638
self.print_ident(*ident);

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12251225
}
12261226

12271227
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
1228-
binding_mode: BindingMode(ByRef::Yes(_), _),
1228+
binding_mode: BindingMode(ByRef::Yes(..), _),
12291229
..
12301230
})) => {
12311231
let pattern_span: Span = local_decl.source_info.span;
@@ -1588,7 +1588,7 @@ fn suggest_ampmut<'tcx>(
15881588
} else {
15891589
// otherwise, suggest that the user annotates the binding; we provide the
15901590
// type of the local.
1591-
let ty = decl_ty.builtin_deref(true, tcx).unwrap();
1591+
let ty = decl_ty.builtin_deref(true).unwrap();
15921592

15931593
Some(AmpMutSugg {
15941594
has_sugg: false,

compiler/rustc_borrowck/src/lib.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2472,10 +2472,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
24722472

24732473
// Check the kind of deref to decide
24742474
match base_ty.kind() {
2475-
_ if let Some((_, _, _, mutbl)) =
2476-
base_ty.is_ref_or_pin_ref(self.infcx.tcx) =>
2477-
{
2478-
// FIXME(pin_ergonomics): handle `&pin mut|const T`
2475+
_ if let &ty::Ref(_, _, mutbl) = base_ty.kind() => {
24792476
match mutbl {
24802477
// Shared borrowed data is never mutable
24812478
hir::Mutability::Not => Err(place),
@@ -2516,6 +2513,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
25162513
_ => bug!("Deref of unexpected type: {:?}", base_ty),
25172514
}
25182515
}
2516+
// Check as the inner reference type if it is a field projection
2517+
// from the `&pin` pattern
2518+
ProjectionElem::Field(FieldIdx::ZERO, _)
2519+
if let Some(adt) =
2520+
place_base.ty(self.body(), self.infcx.tcx).ty.ty_adt_def()
2521+
&& adt.is_pin()
2522+
&& self.infcx.tcx.features().pin_ergonomics() =>
2523+
{
2524+
self.is_mutable(place_base, is_local_mutation_allowed)
2525+
}
25192526
// All other projections are owned by their base path, so mutable if
25202527
// base path is mutable
25212528
ProjectionElem::Field(..)

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,7 +1761,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
17611761
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
17621762
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
17631763
let normalized_ty = self.normalize(unnormalized_ty, locations);
1764-
let literal_ty = constant.const_.ty().builtin_deref(true, tcx).unwrap();
1764+
let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();
17651765

17661766
if let Err(terr) =
17671767
self.eq_types(literal_ty, normalized_ty, locations, ConstraintCategory::Boring)
@@ -2360,9 +2360,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23602360

23612361
debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
23622362
match base_ty.kind() {
2363-
_ if let Some((ref_region, _, _, mutbl)) =
2364-
base_ty.is_ref_or_pin_ref(tcx) =>
2365-
{
2363+
_ if let &ty::Ref(ref_region, _, mutbl) = base_ty.kind() => {
23662364
// FIXME(pin_ergonomics): handle `&pin mut|const T`
23672365
constraints.outlives_constraints.push(OutlivesConstraint {
23682366
sup: ref_region.as_var(),

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
626626
let element_type_index = unsafe { llvm::LLVMRustGetElementTypeArgIndex(callsite) };
627627
if element_type_index >= 0 {
628628
let arg_ty = self.args[element_type_index as usize].layout.ty;
629-
let pointee_ty = arg_ty.builtin_deref(true, bx.tcx).expect("Must be pointer argument");
629+
let pointee_ty = arg_ty.builtin_deref(true).expect("Must be pointer argument");
630630
let element_type_attr = unsafe {
631631
llvm::LLVMRustCreateElementTypeAttr(bx.llcx, bx.layout_of(pointee_ty).llvm_type(bx))
632632
};

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2532,7 +2532,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
25322532

25332533
if name == sym::simd_arith_offset {
25342534
// This also checks that the first operand is a ptr type.
2535-
let pointee = in_elem.builtin_deref(true, bx.tcx).unwrap_or_else(|| {
2535+
let pointee = in_elem.builtin_deref(true).unwrap_or_else(|| {
25362536
span_bug!(span, "must be called with a vector of pointer types as first argument")
25372537
});
25382538
let layout = bx.layout_of(pointee);

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11061106

11071107
// Make sure that we've actually unwrapped the rcvr down
11081108
// to a pointer or ref to `dyn* Trait`.
1109-
if !op.layout.ty.builtin_deref(true, bx.tcx()).unwrap().is_dyn_star() {
1109+
if !op.layout.ty.builtin_deref(true).unwrap().is_dyn_star() {
11101110
span_bug!(span, "can't codegen a virtual call on {:#?}", op);
11111111
}
11121112
let place = op.deref(bx.cx());

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
130130
{
131131
fn deref(&self, bx: &mut Bx) -> Self {
132132
bx.cx().layout_of(
133-
self.ty
134-
.builtin_deref(true, bx.tcx())
135-
.unwrap_or_else(|| bug!("cannot deref `{}`", self.ty)),
133+
self.ty.builtin_deref(true).unwrap_or_else(|| bug!("cannot deref `{}`", self.ty)),
136134
)
137135
}
138136

0 commit comments

Comments
 (0)