diff options
| author | León Orell Valerian Liehr <me@fmease.dev> | 2024-02-02 02:49:13 +0100 |
|---|---|---|
| committer | León Orell Valerian Liehr <me@fmease.dev> | 2024-02-02 03:25:04 +0100 |
| commit | 5906237b32a83a1df215b87bbafcc926bf49cd66 (patch) | |
| tree | d3355ec0af3ea3972d7b21dea577e380180f9515 /compiler/rustc_resolve | |
| parent | 3f7b1a5f491a66365e9973babc1b3dde2c90ad55 (diff) | |
| download | rust-5906237b32a83a1df215b87bbafcc926bf49cd66.tar.gz rust-5906237b32a83a1df215b87bbafcc926bf49cd66.zip | |
Suggest changing ty to const params if appropriate
Diffstat (limited to 'compiler/rustc_resolve')
| -rw-r--r-- | compiler/rustc_resolve/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 50 |
3 files changed, 67 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index c8ec10cad17..02847a0f5f9 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -289,6 +289,9 @@ resolve_underscore_lifetime_name_cannot_be_used_here = `'_` cannot be used here .note = `'_` is a reserved lifetime name +resolve_unexpected_res_change_ty_to_const_param_sugg = + you might have meant to write a const parameter here + resolve_unreachable_label = use of unreachable label `{$name}` .label = unreachable label `{$name}` diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 50ff09feb4d..655fc9812d7 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::codes::*; +use rustc_errors::{codes::*, Applicability}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{ symbol::{Ident, Symbol}, @@ -787,3 +787,16 @@ pub(crate) struct IsNotDirectlyImportable { pub(crate) span: Span, pub(crate) target: Ident, } + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_unexpected_res_change_ty_to_const_param_sugg, + code = "const ", + style = "verbose" +)] +pub(crate) struct UnexpectedResChangeTyToConstParamSugg { + #[primary_span] + pub span: Span, + #[applicability] + pub applicability: Applicability, +} diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 64e2b6a4971..9f810741f49 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -444,6 +444,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } self.suggest_bare_struct_literal(&mut err); + self.suggest_changing_type_to_const_param(&mut err, res, source, span); if self.suggest_pattern_match_with_let(&mut err, source, span) { // Fallback label. @@ -1138,6 +1139,55 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } } + fn suggest_changing_type_to_const_param( + &mut self, + err: &mut Diagnostic, + res: Option<Res>, + source: PathSource<'_>, + span: Span, + ) { + let PathSource::Trait(_) = source else { return }; + + // We don't include `DefKind::Str` and `DefKind::AssocTy` as they can't be reached here anyway. + let applicability = match res { + Some(Res::PrimTy(PrimTy::Int(_) | PrimTy::Uint(_) | PrimTy::Bool | PrimTy::Char)) => { + Applicability::MachineApplicable + } + // FIXME(const_generics): Add `DefKind::TyParam` and `SelfTyParam` once we support generic + // const generics. Of course, `Struct` and `Enum` may contain ty params, too, but the + // benefits of including them here outweighs the small number of false positives. + Some(Res::Def(DefKind::Struct | DefKind::Enum, _)) + if self.r.tcx.features().adt_const_params => + { + Applicability::MaybeIncorrect + } + _ => return, + }; + + let Some(item) = self.diagnostic_metadata.current_item else { return }; + let Some(generics) = item.kind.generics() else { return }; + + let param = generics.params.iter().find_map(|param| { + // Only consider type params with exactly one trait bound. + if let [bound] = &*param.bounds + && let ast::GenericBound::Trait(tref, ast::TraitBoundModifiers::NONE) = bound + && tref.span == span + && param.ident.span.eq_ctxt(span) + { + Some(param.ident.span) + } else { + None + } + }); + + if let Some(param) = param { + err.subdiagnostic(errors::UnexpectedResChangeTyToConstParamSugg { + span: param.shrink_to_lo(), + applicability, + }); + } + } + fn suggest_pattern_match_with_let( &mut self, err: &mut Diagnostic, |
