Skip to content

Commit ca78422

Browse files
authored
Unrolled build for rust-lang#134264
Rollup merge of rust-lang#134264 - adetaylor:weak-and-nonnull, r=compiler-errors Arbitrary self types v2: Weak & NonNull diagnostics This builds on top of rust-lang#134262 which is more urgent to review and merge first. I'll likely rebase this PR once that lands. This is the first part of the diagnostic enhancements planned for Arbitrary Self Types v2. Various types can be used as method receivers, such as `Rc<>`, `Box<>` and `Arc<>`. The arbitrary self types v2 work allows further types to be made method receivers by implementing the Receiver trait. With that in mind, it may come as a surprise to people when certain common types do not implement Receiver and thus cannot be used as a method receiver. The RFC for arbitrary self types v2 therefore proposes emitting specific lint hints for these cases: * `NonNull` * `Weak` * Raw pointers The code already emits a hint for this third case, in that it advises folks that the `arbitrary_self_types_pointers` feature may meet their need. This PR adds diagnostic hints for the `Weak` and `NonNull` cases. Tracking issue rust-lang#44874 r? `@wesleywiser`
2 parents b57d93d + b27817c commit ca78422

7 files changed

+101
-1
lines changed

compiler/rustc_hir_analysis/messages.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ hir_analysis_invalid_receiver_ty_help =
249249
hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types =
250250
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`)
251251
252+
hir_analysis_invalid_receiver_ty_help_nonnull_note =
253+
`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`
254+
255+
hir_analysis_invalid_receiver_ty_help_weak_note =
256+
`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`
257+
252258
hir_analysis_invalid_receiver_ty_no_arbitrary_self_types = invalid `self` parameter type: `{$receiver_ty}`
253259
.note = type of `self` must be `Self` or a type that dereferences to it
254260

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use {rustc_ast as ast, rustc_hir as hir};
4444
use crate::autoderef::Autoderef;
4545
use crate::collect::CollectItemTypesVisitor;
4646
use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
47+
use crate::errors::InvalidReceiverTyHint;
4748
use crate::{errors, fluent_generated as fluent};
4849

4950
pub(super) struct WfCheckingCtxt<'a, 'tcx> {
@@ -1749,7 +1750,18 @@ fn check_method_receiver<'tcx>(
17491750
{
17501751
match receiver_validity_err {
17511752
ReceiverValidityError::DoesNotDeref if arbitrary_self_types_level.is_some() => {
1752-
tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
1753+
let hint = match receiver_ty
1754+
.builtin_deref(false)
1755+
.unwrap_or(receiver_ty)
1756+
.ty_adt_def()
1757+
.and_then(|adt_def| tcx.get_diagnostic_name(adt_def.did()))
1758+
{
1759+
Some(sym::RcWeak | sym::ArcWeak) => Some(InvalidReceiverTyHint::Weak),
1760+
Some(sym::NonNull) => Some(InvalidReceiverTyHint::NonNull),
1761+
_ => None,
1762+
};
1763+
1764+
tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty, hint })
17531765
}
17541766
ReceiverValidityError::DoesNotDeref => {
17551767
tcx.dcx().emit_err(errors::InvalidReceiverTyNoArbitrarySelfTypes {

compiler/rustc_hir_analysis/src/errors.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1655,6 +1655,14 @@ pub(crate) struct NonConstRange {
16551655
pub span: Span,
16561656
}
16571657

1658+
#[derive(Subdiagnostic)]
1659+
pub(crate) enum InvalidReceiverTyHint {
1660+
#[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
1661+
Weak,
1662+
#[note(hir_analysis_invalid_receiver_ty_help_nonnull_note)]
1663+
NonNull,
1664+
}
1665+
16581666
#[derive(Diagnostic)]
16591667
#[diag(hir_analysis_invalid_receiver_ty_no_arbitrary_self_types, code = E0307)]
16601668
#[note]
@@ -1673,6 +1681,8 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
16731681
#[primary_span]
16741682
pub span: Span,
16751683
pub receiver_ty: Ty<'tcx>,
1684+
#[subdiagnostic]
1685+
pub hint: Option<InvalidReceiverTyHint>,
16761686
}
16771687

16781688
#[derive(Diagnostic)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(arbitrary_self_types)]
2+
3+
struct A;
4+
5+
impl A {
6+
fn m(self: std::ptr::NonNull<Self>) {}
7+
//~^ ERROR: invalid `self` parameter type
8+
fn n(self: &std::ptr::NonNull<Self>) {}
9+
//~^ ERROR: invalid `self` parameter type
10+
}
11+
12+
fn main() {
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0307]: invalid `self` parameter type: `NonNull<A>`
2+
--> $DIR/arbitrary_self_types_nonnull.rs:6:16
3+
|
4+
LL | fn m(self: std::ptr::NonNull<Self>) {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: type of `self` must be `Self` or some type implementing `Receiver`
8+
= 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>`
9+
= 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`
10+
11+
error[E0307]: invalid `self` parameter type: `&NonNull<A>`
12+
--> $DIR/arbitrary_self_types_nonnull.rs:8:16
13+
|
14+
LL | fn n(self: &std::ptr::NonNull<Self>) {}
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= note: type of `self` must be `Self` or some type implementing `Receiver`
18+
= 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>`
19+
= 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`
20+
21+
error: aborting due to 2 previous errors
22+
23+
For more information about this error, try `rustc --explain E0307`.
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(arbitrary_self_types)]
2+
3+
struct A;
4+
5+
impl A {
6+
fn m(self: std::rc::Weak<Self>) {}
7+
//~^ ERROR: invalid `self` parameter type
8+
fn n(self: std::sync::Weak<Self>) {}
9+
//~^ ERROR: invalid `self` parameter type
10+
}
11+
12+
fn main() {
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0307]: invalid `self` parameter type: `std::rc::Weak<A>`
2+
--> $DIR/arbitrary_self_types_weak.rs:6:16
3+
|
4+
LL | fn m(self: std::rc::Weak<Self>) {}
5+
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: type of `self` must be `Self` or some type implementing `Receiver`
8+
= 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>`
9+
= 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`
10+
11+
error[E0307]: invalid `self` parameter type: `std::sync::Weak<A>`
12+
--> $DIR/arbitrary_self_types_weak.rs:8:16
13+
|
14+
LL | fn n(self: std::sync::Weak<Self>) {}
15+
| ^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= note: type of `self` must be `Self` or some type implementing `Receiver`
18+
= 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>`
19+
= 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`
20+
21+
error: aborting due to 2 previous errors
22+
23+
For more information about this error, try `rustc --explain E0307`.

0 commit comments

Comments
 (0)