Skip to content

Commit f0b30c4

Browse files
committed
Forbid manual Unpin impls for structurally pinned types
1 parent d3e1ccd commit f0b30c4

File tree

5 files changed

+54
-0
lines changed

5 files changed

+54
-0
lines changed

compiler/rustc_hir_analysis/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a par
222222
hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
223223
.note = parent implementation is in crate `{$cname}`
224224
225+
hir_analysis_impl_unpin_for_pin_projected_type = explicit impls for the `Unpin` trait are not permitted for structurally pinned types
226+
.label = impl of `Unpin` not allowed
227+
.help = `{$adt_name}` is structurally pinned because it is marked as `#[pin_v2]`
228+
225229
hir_analysis_inherent_dyn = cannot define inherent `impl` for a dyn auto trait
226230
.label = impl requires at least one non-auto trait
227231
.note = define and implement a new trait or type instead

compiler/rustc_hir_analysis/src/coherence/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ fn enforce_trait_manually_implementable(
9090
return Err(err.emit());
9191
}
9292

93+
// Disallow explicit impls of the `Unpin` trait for structurally pinned types
94+
if tcx.features().pin_ergonomics()
95+
&& tcx.is_lang_item(trait_def_id, LangItem::Unpin)
96+
&& let Some(adt) =
97+
tcx.impl_trait_ref(impl_def_id).instantiate_identity().self_ty().ty_adt_def()
98+
&& adt.is_pin_project()
99+
{
100+
return Err(tcx.dcx().emit_err(crate::errors::ImplUnpinForPinProjectedType {
101+
span: impl_header_span,
102+
adt_span: tcx.def_span(adt.did()),
103+
adt_name: tcx.item_name(adt.did()),
104+
}));
105+
}
106+
93107
if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable = trait_def.specialization_kind
94108
{
95109
if !tcx.features().specialization()

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,3 +1708,14 @@ pub(crate) struct AsyncDropWithoutSyncDrop {
17081708
#[primary_span]
17091709
pub span: Span,
17101710
}
1711+
1712+
#[derive(Diagnostic)]
1713+
#[diag(hir_analysis_impl_unpin_for_pin_projected_type)]
1714+
pub(crate) struct ImplUnpinForPinProjectedType {
1715+
#[primary_span]
1716+
#[label]
1717+
pub span: Span,
1718+
#[help]
1719+
pub adt_span: Span,
1720+
pub adt_name: Symbol,
1721+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(pin_ergonomics)]
2+
#![allow(incomplete_features)]
3+
4+
#[pin_v2]
5+
struct Foo;
6+
struct Bar;
7+
8+
impl Unpin for Foo {} //~ ERROR explicit impls for the `Unpin` trait are not permitted for structurally pinned types
9+
impl Unpin for Bar {} // ok
10+
11+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: explicit impls for the `Unpin` trait are not permitted for structurally pinned types
2+
--> $DIR/impl-unpin.rs:8:1
3+
|
4+
LL | impl Unpin for Foo {}
5+
| ^^^^^^^^^^^^^^^^^^ impl of `Unpin` not allowed
6+
|
7+
help: `Foo` is structurally pinned because it is marked as `#[pin_v2]`
8+
--> $DIR/impl-unpin.rs:5:1
9+
|
10+
LL | struct Foo;
11+
| ^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

0 commit comments

Comments
 (0)