about summary refs log tree commit diff
diff options
context:
space:
mode:
authorclubby789 <jamie@hill-daniel.co.uk>2023-05-11 12:25:01 +0100
committerclubby789 <jamie@hill-daniel.co.uk>2023-05-11 13:21:10 +0100
commit3851a4bb914f74fb3f1d7394479ad810deb653cd (patch)
tree75fa8b4d41626091011676d70d6b9175f8a2210b
parent4d941cd9812891af3b83dd4de64aa7d8ee99641a (diff)
downloadrust-3851a4bb914f74fb3f1d7394479ad810deb653cd.tar.gz
rust-3851a4bb914f74fb3f1d7394479ad810deb653cd.zip
Improve error for `self: Box<self>`
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_resolve/messages.ftl4
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs3
-rw-r--r--compiler/rustc_resolve/src/errors.rs8
-rw-r--r--compiler/rustc_resolve/src/ident.rs44
-rw-r--r--compiler/rustc_resolve/src/late.rs9
-rw-r--r--compiler/rustc_resolve/src/lib.rs2
-rw-r--r--tests/ui/resolve/explicit-self-lowercase-param.rs8
-rw-r--r--tests/ui/resolve/explicit-self-lowercase-param.stderr8
9 files changed, 63 insertions, 25 deletions
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index e5b2d342452..bcb51db9bcf 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1253,7 +1253,7 @@ pub enum ExplicitSelf<'tcx> {
 
 impl<'tcx> ExplicitSelf<'tcx> {
     /// Categorizes an explicit self declaration like `self: SomeType`
-    /// into either `self`, `&self`, `&mut self`, `Box<self>`, or
+    /// into either `self`, `&self`, `&mut self`, `Box<Self>`, or
     /// `Other`.
     /// This is mainly used to require the arbitrary_self_types feature
     /// in the case of `Other`, to improve error messages in the common cases,
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index ff8bd462dd8..345255c4c69 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -199,6 +199,10 @@ resolve_invalid_asm_sym =
     .label = is a local variable
     .help = `sym` operands must refer to either a function or a static
 
+resolve_lowercase_self =
+    attempt to use a non-constant value in a constant
+    .suggestion = try using `Self`
+
 resolve_trait_impl_duplicate =
     duplicate definitions with name `{$name}`:
     .label = duplicate definition
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 72cdce5c8f0..6675b8ed59b 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -948,6 +948,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             ResolutionError::InvalidAsmSym => {
                 self.tcx.sess.create_err(errs::InvalidAsmSym { span })
             }
+            ResolutionError::LowercaseSelf => {
+                self.tcx.sess.create_err(errs::LowercaseSelf { span })
+            }
         }
     }
 
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index f6d7e8b4c87..2ab55f12637 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -443,6 +443,14 @@ pub(crate) struct InvalidAsmSym {
 }
 
 #[derive(Diagnostic)]
+#[diag(resolve_lowercase_self)]
+pub(crate) struct LowercaseSelf {
+    #[primary_span]
+    #[suggestion(code = "Self", applicability = "maybe-incorrect", style = "short")]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(resolve_trait_impl_duplicate, code = "E0201")]
 pub(crate) struct TraitImplDuplicate {
     #[primary_span]
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 5a3ae656ad4..755acdd81fe 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -15,8 +15,7 @@ use std::ptr;
 
 use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
 use crate::late::{
-    ConstantHasGenerics, ConstantItemKind, HasGenericParams, NoConstantGenericsReason, PathSource,
-    Rib, RibKind,
+    ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
 };
 use crate::macros::{sub_namespace_match, MacroRulesScope};
 use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
@@ -1127,28 +1126,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         RibKind::ConstantItem(_, item) => {
                             // Still doesn't deal with upvars
                             if let Some(span) = finalize {
-                                let (span, resolution_error) =
-                                    if let Some((ident, constant_item_kind)) = item {
-                                        let kind_str = match constant_item_kind {
-                                            ConstantItemKind::Const => "const",
-                                            ConstantItemKind::Static => "static",
-                                        };
-                                        (
-                                            span,
-                                            AttemptToUseNonConstantValueInConstant(
-                                                ident, "let", kind_str,
-                                            ),
-                                        )
-                                    } else {
-                                        (
-                                            rib_ident.span,
-                                            AttemptToUseNonConstantValueInConstant(
-                                                original_rib_ident_def,
-                                                "const",
-                                                "let",
-                                            ),
-                                        )
-                                    };
+                                let (span, resolution_error) = match item {
+                                    None if rib_ident.as_str() == "self" => (span, LowercaseSelf),
+                                    None => (
+                                        rib_ident.span,
+                                        AttemptToUseNonConstantValueInConstant(
+                                            original_rib_ident_def,
+                                            "const",
+                                            "let",
+                                        ),
+                                    ),
+                                    Some((ident, kind)) => (
+                                        span,
+                                        AttemptToUseNonConstantValueInConstant(
+                                            ident,
+                                            "let",
+                                            kind.as_str(),
+                                        ),
+                                    ),
+                                };
                                 self.report_error(span, resolution_error);
                             }
                             return Res::Err;
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 2a8287d5554..0aa0c74b45a 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -150,6 +150,15 @@ pub(crate) enum ConstantItemKind {
     Static,
 }
 
+impl ConstantItemKind {
+    pub(crate) fn as_str(&self) -> &'static str {
+        match self {
+            Self::Const => "const",
+            Self::Static => "static",
+        }
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 enum RecordPartialRes {
     Yes,
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 590609f9ed3..c12dc2f5d92 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -251,6 +251,8 @@ enum ResolutionError<'a> {
     TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span },
     /// Inline asm `sym` operand must refer to a `fn` or `static`.
     InvalidAsmSym,
+    /// `self` used instead of `Self` in a generic parameter
+    LowercaseSelf,
 }
 
 enum VisResolutionError<'a> {
diff --git a/tests/ui/resolve/explicit-self-lowercase-param.rs b/tests/ui/resolve/explicit-self-lowercase-param.rs
new file mode 100644
index 00000000000..7171bd8a42d
--- /dev/null
+++ b/tests/ui/resolve/explicit-self-lowercase-param.rs
@@ -0,0 +1,8 @@
+struct Foo;
+
+impl Foo {
+    fn do_nothing(self: Box<self>) {} //~ ERROR attempt to use a non-constant value in a constant
+    //~^ HELP try using `Self`
+}
+
+fn main() {}
diff --git a/tests/ui/resolve/explicit-self-lowercase-param.stderr b/tests/ui/resolve/explicit-self-lowercase-param.stderr
new file mode 100644
index 00000000000..cd64dbb3854
--- /dev/null
+++ b/tests/ui/resolve/explicit-self-lowercase-param.stderr
@@ -0,0 +1,8 @@
+error: attempt to use a non-constant value in a constant
+  --> $DIR/explicit-self-lowercase-param.rs:4:29
+   |
+LL |     fn do_nothing(self: Box<self>) {}
+   |                             ^^^^ help: try using `Self`
+
+error: aborting due to previous error
+