summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
authorAdrian Taylor <adetaylor@chromium.org>2024-12-02 15:02:59 +0000
committerAdrian Taylor <adetaylor@chromium.org>2024-12-14 20:27:15 +0000
commitb27817c8c605499dc8269c5d1ad34527be8c52f2 (patch)
tree19548ab5b79aa7757c15e42f2502bf9d028b661f /compiler/rustc_hir_analysis/src
parent85641f729f43b3b826f2269f82817ea0b577613f (diff)
downloadrust-b27817c8c605499dc8269c5d1ad34527be8c52f2.tar.gz
rust-b27817c8c605499dc8269c5d1ad34527be8c52f2.zip
Arbitrary self types v2: Weak, NonNull hints
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.
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs10
2 files changed, 23 insertions, 1 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index e6ef29de965..95ad8225f61 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -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> {
@@ -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 {
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 5ab6faf3b7c..d46f60b16f5 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -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]
@@ -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)]