]> git.lizzy.rs Git - rust.git/commitdiff
migrate check_const.rs to translateable diagnostics
authorNathan Stocks <cleancut@github.com>
Sat, 24 Sep 2022 18:49:29 +0000 (12:49 -0600)
committerNathan Stocks <cleancut@github.com>
Fri, 7 Oct 2022 19:19:27 +0000 (13:19 -0600)
compiler/rustc_error_messages/locales/en-US/passes.ftl
compiler/rustc_passes/src/check_const.rs
compiler/rustc_passes/src/errors.rs

index b2c54aaccfe3565809a05f81cac75d421ab7aef1..550096469bb0bf58a3ef577d2fbe5a1cead28c61 100644 (file)
@@ -426,3 +426,10 @@ passes_feature_stable_twice =
 
 passes_feature_previously_declared =
     feature `{$feature}` is declared {$declared}, but was previously declared {$prev_declared}
+
+passes_expr_not_allowed_in_context =
+    {$expr} is not allowed in a `{$context}`
+
+passes_const_impl_const_trait =
+    const `impl`s must be for traits marked with `#[const_trait]`
+    .note = this trait must be annotated with `#[const_trait]`
index e502b9b54e3021ab926d96706f2d7b1d6fc81acf..0a509598ec51d57ee25413e1d1ec40cc93848f09 100644 (file)
@@ -8,7 +8,6 @@
 //! through, but errors for structured control flow in a `const` should be emitted here.
 
 use rustc_attr as attr;
-use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
@@ -18,6 +17,8 @@
 use rustc_session::parse::feature_err;
 use rustc_span::{sym, Span, Symbol};
 
+use crate::errors::{ConstImplConstTrait, ExprNotAllowedInContext};
+
 /// An expression that is not *always* legal in a const context.
 #[derive(Clone, Copy)]
 enum NonConstExpr {
@@ -133,18 +134,22 @@ fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
         let const_kind =
             const_kind.expect("`const_check_violated` may only be called inside a const context");
 
-        let msg = format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name());
-
         let required_gates = required_gates.unwrap_or(&[]);
         let missing_gates: Vec<_> =
             required_gates.iter().copied().filter(|&g| !features.enabled(g)).collect();
 
         match missing_gates.as_slice() {
             [] => {
-                struct_span_err!(tcx.sess, span, E0744, "{}", msg).emit();
+                tcx.sess.emit_err(ExprNotAllowedInContext {
+                    span,
+                    expr: expr.name(),
+                    context: const_kind.keyword_name(),
+                });
             }
 
             [missing_primary, ref missing_secondary @ ..] => {
+                let msg =
+                    format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name());
                 let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, &msg);
 
                 // If multiple feature gates would be required to enable this expression, include
@@ -191,6 +196,26 @@ fn nested_visit_map(&mut self) -> Self::Map {
         self.tcx.hir()
     }
 
+    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
+        let tcx = self.tcx;
+        if let hir::ItemKind::Impl(hir::Impl {
+            constness: hir::Constness::Const,
+            of_trait: Some(trait_ref),
+            ..
+        }) = item.kind
+            && let Some(def_id) = trait_ref.trait_def_id()
+        {
+            let source_map = tcx.sess.source_map();
+            if !tcx.has_attr(def_id, sym::const_trait) {
+                tcx.sess.emit_err(ConstImplConstTrait {
+                    span: source_map.guess_head_span(item.span),
+                    def_span: source_map.guess_head_span(tcx.def_span(def_id)),
+                });
+            }
+        }
+        intravisit::walk_item(self, item);
+    }
+
     fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
         let kind = Some(hir::ConstContext::Const);
         self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));
index 7c3a575242f320e0c00f18c426500f9773772b8a..fe169c566f63583bca18736db80580b40dccff4c 100644 (file)
@@ -852,3 +852,21 @@ pub struct FeaturePreviouslyDeclared<'a, 'b> {
     pub declared: &'a str,
     pub prev_declared: &'b str,
 }
+
+#[derive(Diagnostic)]
+#[diag(passes::expr_not_allowed_in_context, code = "E0744")]
+pub struct ExprNotAllowedInContext<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub expr: String,
+    pub context: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(passes::const_impl_const_trait)]
+pub struct ConstImplConstTrait {
+    #[primary_span]
+    pub span: Span,
+    #[note]
+    pub def_span: Span,
+}