From 3851a4bb914f74fb3f1d7394479ad810deb653cd Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 11 May 2023 12:25:01 +0100 Subject: [PATCH] Improve error for `self: Box` --- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_resolve/messages.ftl | 4 ++ compiler/rustc_resolve/src/diagnostics.rs | 3 ++ compiler/rustc_resolve/src/errors.rs | 8 ++++ compiler/rustc_resolve/src/ident.rs | 44 +++++++++---------- compiler/rustc_resolve/src/late.rs | 9 ++++ compiler/rustc_resolve/src/lib.rs | 2 + .../resolve/explicit-self-lowercase-param.rs | 8 ++++ .../explicit-self-lowercase-param.stderr | 8 ++++ 9 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 tests/ui/resolve/explicit-self-lowercase-param.rs create mode 100644 tests/ui/resolve/explicit-self-lowercase-param.stderr diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e5b2d342452f3..bcb51db9bcf90 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`, or + /// into either `self`, `&self`, `&mut self`, `Box`, 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 ff8bd462dd8d8..345255c4c6935 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 72cdce5c8f05e..6675b8ed59b26 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 f6d7e8b4c873d..2ab55f12637c8 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -442,6 +442,14 @@ pub(crate) struct InvalidAsmSym { pub(crate) span: Span, } +#[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 { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 5a3ae656ad459..755acdd81fe5c 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 2a8287d5554f8..0aa0c74b45a8c 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 590609f9ed3db..c12dc2f5d92a5 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 0000000000000..7171bd8a42dd2 --- /dev/null +++ b/tests/ui/resolve/explicit-self-lowercase-param.rs @@ -0,0 +1,8 @@ +struct Foo; + +impl Foo { + fn do_nothing(self: Box) {} //~ 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 0000000000000..cd64dbb3854af --- /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) {} + | ^^^^ help: try using `Self` + +error: aborting due to previous error +