Skip to content

Commit 522ff7b

Browse files
committed
Forbid manual Unpin impls for structurally pinned types
1 parent 0208ee0 commit 522ff7b

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
@@ -226,6 +226,10 @@ hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a par
226226
hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
227227
.note = parent implementation is in crate `{$cname}`
228228
229+
hir_analysis_impl_unpin_for_pin_projected_type = explicit impls for the `Unpin` trait are not permitted for structurally pinned types
230+
.label = impl of `Unpin` not allowed
231+
.help = `{$adt_name}` is structurally pinned because it is marked as `#[pin_v2]`
232+
229233
hir_analysis_inherent_dyn = cannot define inherent `impl` for a dyn auto trait
230234
.label = impl requires at least one non-auto trait
231235
.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
@@ -1722,3 +1722,14 @@ pub(crate) struct EiiWithGenerics {
17221722
pub attr: Span,
17231723
pub eii_name: Symbol,
17241724
}
1725+
1726+
#[derive(Diagnostic)]
1727+
#[diag(hir_analysis_impl_unpin_for_pin_projected_type)]
1728+
pub(crate) struct ImplUnpinForPinProjectedType {
1729+
#[primary_span]
1730+
#[label]
1731+
pub span: Span,
1732+
#[help]
1733+
pub adt_span: Span,
1734+
pub adt_name: Symbol,
1735+
}
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)