Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arbitrary self types v2: Weak & NonNull diagnostics #134264

Merged
merged 1 commit into from
Dec 15, 2024
Merged
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
6 changes: 6 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ hir_analysis_invalid_receiver_ty_help =
hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types =
consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)

hir_analysis_invalid_receiver_ty_help_nonnull_note =
`NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`

hir_analysis_invalid_receiver_ty_help_weak_note =
`Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`

hir_analysis_invalid_receiver_ty_no_arbitrary_self_types = invalid `self` parameter type: `{$receiver_ty}`
.note = type of `self` must be `Self` or a type that dereferences to it

Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use {rustc_ast as ast, rustc_hir as hir};
use crate::autoderef::Autoderef;
use crate::collect::CollectItemTypesVisitor;
use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
use crate::errors::InvalidReceiverTyHint;
use crate::{errors, fluent_generated as fluent};

pub(super) struct WfCheckingCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -1749,7 +1750,18 @@ fn check_method_receiver<'tcx>(
{
match receiver_validity_err {
ReceiverValidityError::DoesNotDeref if arbitrary_self_types_level.is_some() => {
tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
let hint = match receiver_ty
.builtin_deref(false)
.unwrap_or(receiver_ty)
.ty_adt_def()
.and_then(|adt_def| tcx.get_diagnostic_name(adt_def.did()))
{
Some(sym::RcWeak | sym::ArcWeak) => Some(InvalidReceiverTyHint::Weak),
Some(sym::NonNull) => Some(InvalidReceiverTyHint::NonNull),
_ => None,
};

tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty, hint })
}
ReceiverValidityError::DoesNotDeref => {
tcx.dcx().emit_err(errors::InvalidReceiverTyNoArbitrarySelfTypes {
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,14 @@ pub(crate) struct NonConstRange {
pub span: Span,
}

#[derive(Subdiagnostic)]
pub(crate) enum InvalidReceiverTyHint {
#[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
Weak,
#[note(hir_analysis_invalid_receiver_ty_help_nonnull_note)]
NonNull,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_invalid_receiver_ty_no_arbitrary_self_types, code = E0307)]
#[note]
Expand All @@ -1673,6 +1681,8 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
#[primary_span]
pub span: Span,
pub receiver_ty: Ty<'tcx>,
#[subdiagnostic]
pub hint: Option<InvalidReceiverTyHint>,
}

#[derive(Diagnostic)]
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/self/arbitrary_self_types_nonnull.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![feature(arbitrary_self_types)]

struct A;

impl A {
fn m(self: std::ptr::NonNull<Self>) {}
//~^ ERROR: invalid `self` parameter type
fn n(self: &std::ptr::NonNull<Self>) {}
//~^ ERROR: invalid `self` parameter type
}

fn main() {
}
23 changes: 23 additions & 0 deletions tests/ui/self/arbitrary_self_types_nonnull.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0307]: invalid `self` parameter type: `NonNull<A>`
--> $DIR/arbitrary_self_types_nonnull.rs:6:16
|
LL | fn m(self: std::ptr::NonNull<Self>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: type of `self` must be `Self` or some type implementing `Receiver`
= help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
= note: `NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`

error[E0307]: invalid `self` parameter type: `&NonNull<A>`
--> $DIR/arbitrary_self_types_nonnull.rs:8:16
|
LL | fn n(self: &std::ptr::NonNull<Self>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: type of `self` must be `Self` or some type implementing `Receiver`
= help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
= note: `NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0307`.
13 changes: 13 additions & 0 deletions tests/ui/self/arbitrary_self_types_weak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![feature(arbitrary_self_types)]

struct A;

impl A {
fn m(self: std::rc::Weak<Self>) {}
//~^ ERROR: invalid `self` parameter type
fn n(self: std::sync::Weak<Self>) {}
//~^ ERROR: invalid `self` parameter type
}

fn main() {
}
23 changes: 23 additions & 0 deletions tests/ui/self/arbitrary_self_types_weak.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0307]: invalid `self` parameter type: `std::rc::Weak<A>`
--> $DIR/arbitrary_self_types_weak.rs:6:16
|
LL | fn m(self: std::rc::Weak<Self>) {}
| ^^^^^^^^^^^^^^^^^^^
|
= note: type of `self` must be `Self` or some type implementing `Receiver`
= help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
= note: `Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`

error[E0307]: invalid `self` parameter type: `std::sync::Weak<A>`
--> $DIR/arbitrary_self_types_weak.rs:8:16
|
LL | fn n(self: std::sync::Weak<Self>) {}
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: type of `self` must be `Self` or some type implementing `Receiver`
= help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
= note: `Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0307`.
Loading