diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 40398011f1f..3a498f84ec5 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -1,3 +1,4 @@ +use rustc_hir::ConstContext; use rustc_macros::SessionDiagnostic; use rustc_span::Span; @@ -26,3 +27,15 @@ pub(crate) struct NonConstOpErr { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[error(const_eval::static_access, code = "E0013")] +#[help] +pub(crate) struct StaticAccessErr { + #[primary_span] + pub span: Span, + pub kind: ConstContext, + #[note(const_eval::teach_note)] + #[help(const_eval::teach_help)] + pub teach: Option<()>, +} diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 01080560021..d104fdd59c5 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -1,7 +1,9 @@ //! Concrete error types for all operations which may be invalid in a certain const context. use hir::def_id::LocalDefId; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{ + error_code, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, +}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; @@ -20,7 +22,7 @@ use rustc_span::{BytePos, Pos, Span, Symbol}; use rustc_trait_selection::traits::SelectionContext; use super::ConstCx; -use crate::errors::NonConstOpErr; +use crate::errors::{NonConstOpErr, StaticAccessErr}; use crate::util::{call_kind, CallDesugaringKind, CallKind}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -731,24 +733,11 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let mut err = struct_span_err!( - ccx.tcx.sess, + ccx.tcx.sess.create_err(StaticAccessErr { span, - E0013, - "{}s cannot refer to statics", - ccx.const_kind() - ); - err.help( - "consider extracting the value of the `static` to a `const`, and referring to that", - ); - if ccx.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "`static` and `const` variables can refer to other `const` variables. \ - A `const` variable, however, cannot refer to a `static` variable.", - ); - err.help("To fix this, the value can be extracted to a `const` and then used."); - } - err + kind: ccx.const_kind(), + teach: ccx.tcx.sess.teach(&error_code!(E0013)).then_some(()), + }) } } diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index 897ddce7e99..66058aa1769 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -4,4 +4,14 @@ const-eval-unstable-in-stable = .bypass-sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks const-eval-thread-local-access = - thread-local statics cannot be accessed at compile-time \ No newline at end of file + thread-local statics cannot be accessed at compile-time + +const-eval-static-access = + { $kind -> + [constant function] constant functions + [static] statics + *[constant] constants + } cannot refer to statics + .help = consider extracting the value of the `static` to a `const`, and referring to that + .teach-note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + .teach-help = To fix this, the value can be extracted to a `const` and then used.