diff options
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/ident.rs | 44 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 11 |
4 files changed, 51 insertions, 22 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f879e548f27..09221041031 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -819,7 +819,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => { self.dcx().create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span }) } - ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => { + ResolutionError::AttemptToUseNonConstantValueInConstant { + ident, + suggestion, + current, + type_span, + } => { // let foo =... // ^^^ given this Span // ------- get this Span to have an applicable suggestion @@ -844,6 +849,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span: sp, suggestion, current, + type_span, }), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})), None, ) diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index a4bdd62acbb..79c76e7a976 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -240,16 +240,18 @@ pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> { } #[derive(Subdiagnostic)] -#[suggestion( +#[multipart_suggestion( resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion, - code = "{suggestion} ", style = "verbose", - applicability = "maybe-incorrect" + applicability = "has-placeholders" )] pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> { - #[primary_span] + // #[primary_span] + #[suggestion_part(code = "{suggestion} ")] pub(crate) span: Span, pub(crate) suggestion: &'a str, + #[suggestion_part(code = ": /* Type */")] + pub(crate) type_span: Option<Span>, pub(crate) current: &'a str, } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 7d531385e21..f1934ff184b 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1178,21 +1178,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(span) = finalize { 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", - ), - ), + None => { + // If we have a `let name = expr;`, we have the span for + // `name` and use that to see if it is followed by a type + // specifier. If not, then we know we need to suggest + // `const name: Ty = expr;`. This is a heuristic, it will + // break down in the presence of macros. + let sm = self.tcx.sess.source_map(); + let type_span = match sm.span_look_ahead( + original_rib_ident_def.span, + ":", + None, + ) { + None => { + Some(original_rib_ident_def.span.shrink_to_hi()) + } + Some(_) => None, + }; + ( + rib_ident.span, + AttemptToUseNonConstantValueInConstant { + ident: original_rib_ident_def, + suggestion: "const", + current: "let", + type_span, + }, + ) + } Some((ident, kind)) => ( span, - AttemptToUseNonConstantValueInConstant( + AttemptToUseNonConstantValueInConstant { ident, - "let", - kind.as_str(), - ), + suggestion: "let", + current: kind.as_str(), + type_span: None, + }, ), }; self.report_error(span, resolution_error); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 7cb5a3fb2fd..3dcb83d65b0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -236,11 +236,12 @@ enum ResolutionError<'a> { /// Error E0434: can't capture dynamic environment in a fn item. CannotCaptureDynamicEnvironmentInFnItem, /// Error E0435: attempt to use a non-constant value in a constant. - AttemptToUseNonConstantValueInConstant( - Ident, - /* suggestion */ &'static str, - /* current */ &'static str, - ), + AttemptToUseNonConstantValueInConstant { + ident: Ident, + suggestion: &'static str, + current: &'static str, + type_span: Option<Span>, + }, /// Error E0530: `X` bindings cannot shadow `Y`s. BindingShadowsSomethingUnacceptable { shadowing_binding: PatternSource, |
