Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a par
hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
.note = parent implementation is in crate `{$cname}`
hir_analysis_impl_unpin_for_pin_projected_type = explicit impls for the `Unpin` trait are not permitted for structurally pinned types
.label = impl of `Unpin` not allowed
.help = `{$adt_name}` is structurally pinned because it is marked as `#[pin_v2]`
hir_analysis_inherent_dyn = cannot define inherent `impl` for a dyn auto trait
.label = impl requires at least one non-auto trait
.note = define and implement a new trait or type instead
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,20 @@ fn enforce_trait_manually_implementable(
return Err(err.emit());
}

// Disallow explicit impls of the `Unpin` trait for structurally pinned types
if tcx.features().pin_ergonomics()
&& tcx.is_lang_item(trait_def_id, LangItem::Unpin)
&& let Some(adt) =
tcx.impl_trait_ref(impl_def_id).instantiate_identity().self_ty().ty_adt_def()
&& adt.is_pin_project()
{
return Err(tcx.dcx().emit_err(crate::errors::ImplUnpinForPinProjectedType {
span: impl_header_span,
adt_span: tcx.def_span(adt.did()),
adt_name: tcx.item_name(adt.did()),
}));
}

if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable = trait_def.specialization_kind
{
if !tcx.features().specialization()
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1708,3 +1708,14 @@ pub(crate) struct AsyncDropWithoutSyncDrop {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_impl_unpin_for_pin_projected_type)]
pub(crate) struct ImplUnpinForPinProjectedType {
#[primary_span]
#[label]
pub span: Span,
#[help]
pub adt_span: Span,
pub adt_name: Symbol,
}
11 changes: 11 additions & 0 deletions tests/ui/pin-ergonomics/impl-unpin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(pin_ergonomics)]
#![allow(incomplete_features)]

#[pin_v2]
struct Foo;
struct Bar;

impl Unpin for Foo {} //~ ERROR explicit impls for the `Unpin` trait are not permitted for structurally pinned types
impl Unpin for Bar {} // ok

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/pin-ergonomics/impl-unpin.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: explicit impls for the `Unpin` trait are not permitted for structurally pinned types
--> $DIR/impl-unpin.rs:8:1
|
LL | impl Unpin for Foo {}
| ^^^^^^^^^^^^^^^^^^ impl of `Unpin` not allowed
|
help: `Foo` is structurally pinned because it is marked as `#[pin_v2]`
--> $DIR/impl-unpin.rs:5:1
|
LL | struct Foo;
| ^^^^^^^^^^

error: aborting due to 1 previous error

Loading