Skip to content

Commit 572f341

Browse files
committed
migrate check_const.rs to translateable diagnostics
1 parent c457abe commit 572f341

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

compiler/rustc_error_messages/locales/en-US/passes.ftl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,3 +426,10 @@ passes_feature_stable_twice =
426426
427427
passes_feature_previously_declared =
428428
feature `{$feature}` is declared {$declared}, but was previously declared {$prev_declared}
429+
430+
passes_expr_not_allowed_in_context =
431+
{$expr} is not allowed in a `{$context}`
432+
433+
passes_const_impl_const_trait =
434+
const `impl`s must be for traits marked with `#[const_trait]`
435+
.note = this trait must be annotated with `#[const_trait]`

compiler/rustc_passes/src/check_const.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
//! through, but errors for structured control flow in a `const` should be emitted here.
99
1010
use rustc_attr as attr;
11-
use rustc_errors::struct_span_err;
1211
use rustc_hir as hir;
1312
use rustc_hir::def_id::LocalDefId;
1413
use rustc_hir::intravisit::{self, Visitor};
@@ -18,6 +17,8 @@ use rustc_middle::ty::TyCtxt;
1817
use rustc_session::parse::feature_err;
1918
use rustc_span::{sym, Span, Symbol};
2019

20+
use crate::errors::{ConstImplConstTrait, ExprNotAllowedInContext};
21+
2122
/// An expression that is not *always* legal in a const context.
2223
#[derive(Clone, Copy)]
2324
enum NonConstExpr {
@@ -133,18 +134,22 @@ impl<'tcx> CheckConstVisitor<'tcx> {
133134
let const_kind =
134135
const_kind.expect("`const_check_violated` may only be called inside a const context");
135136

136-
let msg = format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name());
137-
138137
let required_gates = required_gates.unwrap_or(&[]);
139138
let missing_gates: Vec<_> =
140139
required_gates.iter().copied().filter(|&g| !features.enabled(g)).collect();
141140

142141
match missing_gates.as_slice() {
143142
[] => {
144-
struct_span_err!(tcx.sess, span, E0744, "{}", msg).emit();
143+
tcx.sess.emit_err(ExprNotAllowedInContext {
144+
span,
145+
expr: expr.name(),
146+
context: const_kind.keyword_name(),
147+
});
145148
}
146149

147150
[missing_primary, ref missing_secondary @ ..] => {
151+
let msg =
152+
format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name());
148153
let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, &msg);
149154

150155
// If multiple feature gates would be required to enable this expression, include
@@ -191,6 +196,26 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
191196
self.tcx.hir()
192197
}
193198

199+
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
200+
let tcx = self.tcx;
201+
if let hir::ItemKind::Impl(hir::Impl {
202+
constness: hir::Constness::Const,
203+
of_trait: Some(trait_ref),
204+
..
205+
}) = item.kind
206+
&& let Some(def_id) = trait_ref.trait_def_id()
207+
{
208+
let source_map = tcx.sess.source_map();
209+
if !tcx.has_attr(def_id, sym::const_trait) {
210+
tcx.sess.emit_err(ConstImplConstTrait {
211+
span: source_map.guess_head_span(item.span),
212+
def_span: source_map.guess_head_span(tcx.def_span(def_id)),
213+
});
214+
}
215+
}
216+
intravisit::walk_item(self, item);
217+
}
218+
194219
fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
195220
let kind = Some(hir::ConstContext::Const);
196221
self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));

compiler/rustc_passes/src/errors.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,3 +852,21 @@ pub struct FeaturePreviouslyDeclared<'a, 'b> {
852852
pub declared: &'a str,
853853
pub prev_declared: &'b str,
854854
}
855+
856+
#[derive(Diagnostic)]
857+
#[diag(passes::expr_not_allowed_in_context, code = "E0744")]
858+
pub struct ExprNotAllowedInContext<'a> {
859+
#[primary_span]
860+
pub span: Span,
861+
pub expr: String,
862+
pub context: &'a str,
863+
}
864+
865+
#[derive(Diagnostic)]
866+
#[diag(passes::const_impl_const_trait)]
867+
pub struct ConstImplConstTrait {
868+
#[primary_span]
869+
pub span: Span,
870+
#[note]
871+
pub def_span: Span,
872+
}

0 commit comments

Comments
 (0)