]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #100814 - gabrielBusta:port_trait_selection_diagnostics, r=davidtwco
authorMatthias Krüger <matthias.krueger@famsik.de>
Fri, 2 Sep 2022 16:22:00 +0000 (18:22 +0200)
committerGitHub <noreply@github.com>
Fri, 2 Sep 2022 16:22:00 +0000 (18:22 +0200)
 Porting 'compiler/rustc_trait_selection' to translatable diagnostics - Part 1

``@rustbot`` label +A-translation

r? rust-lang/diagnostics
cc #100717

12 files changed:
compiler/rustc_error_messages/locales/en-US/trait_selection.ftl [new file with mode: 0644]
compiler/rustc_error_messages/src/lib.rs
compiler/rustc_middle/src/ty/consts/kind.rs
compiler/rustc_middle/src/ty/sty.rs
compiler/rustc_session/src/session.rs
compiler/rustc_trait_selection/src/autoderef.rs
compiler/rustc_trait_selection/src/errors.rs [new file with mode: 0644]
compiler/rustc_trait_selection/src/lib.rs
compiler/rustc_trait_selection/src/traits/auto_trait.rs
compiler/rustc_trait_selection/src/traits/mod.rs
compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
compiler/rustc_trait_selection/src/traits/specialize/mod.rs

diff --git a/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl b/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl
new file mode 100644 (file)
index 0000000..004e0ab
--- /dev/null
@@ -0,0 +1,26 @@
+trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
+
+trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
+
+trait_selection_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
+    .label = deref recursion limit reached
+    .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
+
+trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
+    .label = empty on-clause here
+
+trait_selection_invalid_on_clause_in_rustc_on_unimplemented = invalid `on`-clause in `#[rustc_on_unimplemented]`
+    .label = invalid on-clause here
+
+trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a valid value
+    .label = expected value here
+    .note = eg `#[rustc_on_unimplemented(message="foo")]`
+
+trait_selection_negative_positive_conflict = found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
+        [none] {""}
+       *[default] {" "}for type `{$self_desc}`
+    }:
+    .negative_implementation_here = negative implementation here
+    .negative_implementation_in_crate = negative implementation in crate `{$negative_impl_cname}`
+    .positive_implementation_here = positive implementation here
+    .positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}`
index ed5e092814f157ef222eb75753232a5a481e12ae..05d0a2ba82cee984758cc5f498edbb5b2b23c148 100644 (file)
@@ -53,6 +53,7 @@
     plugin_impl => "../locales/en-US/plugin_impl.ftl",
     privacy => "../locales/en-US/privacy.ftl",
     query_system => "../locales/en-US/query_system.ftl",
+    trait_selection => "../locales/en-US/trait_selection.ftl",
     save_analysis => "../locales/en-US/save_analysis.ftl",
     ty_utils => "../locales/en-US/ty_utils.ftl",
     typeck => "../locales/en-US/typeck.ftl",
index cb0137d2e5e09c8b8f84cf5dee284db3873b0113..3840e79cebd84e8d577b412366a049f552270719 100644 (file)
@@ -20,6 +20,12 @@ pub struct Unevaluated<'tcx, P = Option<Promoted>> {
     pub promoted: P,
 }
 
+impl rustc_errors::IntoDiagnosticArg for Unevaluated<'_> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        format!("{:?}", self).into_diagnostic_arg()
+    }
+}
+
 impl<'tcx> Unevaluated<'tcx> {
     #[inline]
     pub fn shrink(self) -> Unevaluated<'tcx, ()> {
index 80354a3f8a2260e8f61b39e37a89251470c10a75..9fb91b5fe8700032585acf97aaf3b88d4a38c116 100644 (file)
@@ -849,6 +849,12 @@ pub fn to_poly_trait_predicate_negative_polarity(&self) -> ty::PolyTraitPredicat
     }
 }
 
+impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        self.to_string().into_diagnostic_arg()
+    }
+}
+
 /// An existential reference to a trait, where `Self` is erased.
 /// For example, the trait object `Trait<'a, 'b, X, Y>` is:
 /// ```ignore (illustrative)
index ec5e5170d359494fbeae05002849ef132dd91c1d..a49af23be2316d7ad1a839bd27d115522d3a765e 100644 (file)
@@ -110,6 +110,12 @@ fn mul(self, rhs: usize) -> Self::Output {
     }
 }
 
+impl rustc_errors::IntoDiagnosticArg for Limit {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        self.to_string().into_diagnostic_arg()
+    }
+}
+
 #[derive(Clone, Copy, Debug, HashStable_Generic)]
 pub struct Limits {
     /// The maximum recursion limit for potentially infinitely recursive
index 8b7e8984a8adbf359b4be7882198932deea4413a..36ab8f3bd8845f6cf6bc754c1432fafccaf365bd 100644 (file)
@@ -1,6 +1,6 @@
+use crate::errors::AutoDerefReachedRecursionLimit;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::{self, TraitEngine};
-use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
@@ -222,19 +222,10 @@ pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Spa
         Limit(0) => Limit(2),
         limit => limit * 2,
     };
-    struct_span_err!(
-        tcx.sess,
+    tcx.sess.emit_err(AutoDerefReachedRecursionLimit {
         span,
-        E0055,
-        "reached the recursion limit while auto-dereferencing `{:?}`",
-        ty
-    )
-    .span_label(span, "deref recursion limit reached")
-    .help(&format!(
-        "consider increasing the recursion limit by adding a \
-             `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
+        ty,
         suggested_limit,
-        tcx.crate_name(LOCAL_CRATE),
-    ))
-    .emit();
+        crate_name: tcx.crate_name(LOCAL_CRATE),
+    });
 }
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
new file mode 100644 (file)
index 0000000..81977f2
--- /dev/null
@@ -0,0 +1,102 @@
+use rustc_errors::{fluent, ErrorGuaranteed};
+use rustc_macros::SessionDiagnostic;
+use rustc_middle::ty::{PolyTraitRef, Ty, Unevaluated};
+use rustc_session::{parse::ParseSess, Limit, SessionDiagnostic};
+use rustc_span::{Span, Symbol};
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::dump_vtable_entries)]
+pub struct DumpVTableEntries<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub trait_ref: PolyTraitRef<'a>,
+    pub entries: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::unable_to_construct_constant_value)]
+pub struct UnableToConstructConstantValue<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub unevaluated: Unevaluated<'a>,
+}
+
+#[derive(SessionDiagnostic)]
+#[help]
+#[diag(trait_selection::auto_deref_reached_recursion_limit, code = "E0055")]
+pub struct AutoDerefReachedRecursionLimit<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub ty: Ty<'a>,
+    pub suggested_limit: Limit,
+    pub crate_name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+pub struct EmptyOnClauseInOnUnimplemented {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::invalid_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+pub struct InvalidOnClauseInOnUnimplemented {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(trait_selection::no_value_in_rustc_on_unimplemented, code = "E0232")]
+#[note]
+pub struct NoValueInOnUnimplemented {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+pub struct NegativePositiveConflict<'a> {
+    pub impl_span: Span,
+    pub trait_desc: &'a str,
+    pub self_desc: &'a Option<String>,
+    pub negative_impl_span: Result<Span, Symbol>,
+    pub positive_impl_span: Result<Span, Symbol>,
+}
+
+impl SessionDiagnostic<'_> for NegativePositiveConflict<'_> {
+    fn into_diagnostic(
+        self,
+        sess: &ParseSess,
+    ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
+        let mut diag = sess.struct_err(fluent::trait_selection::negative_positive_conflict);
+        diag.set_arg("trait_desc", self.trait_desc);
+        diag.set_arg(
+            "self_desc",
+            self.self_desc.clone().map_or_else(|| String::from("none"), |ty| ty),
+        );
+        diag.set_span(self.impl_span);
+        diag.code(rustc_errors::error_code!(E0751));
+        match self.negative_impl_span {
+            Ok(span) => {
+                diag.span_label(span, fluent::trait_selection::negative_implementation_here);
+            }
+            Err(cname) => {
+                diag.note(fluent::trait_selection::negative_implementation_in_crate);
+                diag.set_arg("negative_impl_cname", cname.to_string());
+            }
+        }
+        match self.positive_impl_span {
+            Ok(span) => {
+                diag.span_label(span, fluent::trait_selection::positive_implementation_here);
+            }
+            Err(cname) => {
+                diag.note(fluent::trait_selection::positive_implementation_in_crate);
+                diag.set_arg("positive_impl_cname", cname.to_string());
+            }
+        }
+        diag
+    }
+}
index 77cc2c164c34c052ca381491d7262a928c429c8f..f039b1fca1817d1069e24d0f489bd659c644b259 100644 (file)
@@ -37,5 +37,6 @@
 extern crate smallvec;
 
 pub mod autoderef;
+pub mod errors;
 pub mod infer;
 pub mod traits;
index 4bab99355012e0792b8e3135040db1be28f11032..1223c7ced7abcb9e04bdaeb1b879ec240092bcf7 100644 (file)
@@ -3,6 +3,7 @@
 
 use super::*;
 
+use crate::errors::UnableToConstructConstantValue;
 use crate::infer::region_constraints::{Constraint, RegionConstraintData};
 use crate::infer::InferCtxt;
 use crate::traits::project::ProjectAndUnifyResult;
@@ -830,8 +831,11 @@ fn evaluate_nested_obligations(
                                 Ok(None) => {
                                     let tcx = self.tcx;
                                     let def_id = unevaluated.def.did;
-                                    let reported = tcx.sess.struct_span_err(tcx.def_span(def_id), &format!("unable to construct a constant value for the unevaluated constant {:?}", unevaluated)).emit();
-
+                                    let reported =
+                                        tcx.sess.emit_err(UnableToConstructConstantValue {
+                                            span: tcx.def_span(def_id),
+                                            unevaluated,
+                                        });
                                     Err(ErrorHandled::Reported(reported))
                                 }
                                 Err(err) => Err(err),
index e11ea7751aa731e93417895ba681a7f93a265bd2..14e078096783e39239cdb186325910f9df61dd8b 100644 (file)
@@ -23,6 +23,7 @@
 mod util;
 pub mod wf;
 
+use crate::errors::DumpVTableEntries;
 use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::{InferCtxt, TyCtxtInferExt};
 use crate::traits::error_reporting::InferCtxtExt as _;
@@ -763,8 +764,11 @@ fn dump_vtable_entries<'tcx>(
     trait_ref: ty::PolyTraitRef<'tcx>,
     entries: &[VtblEntry<'tcx>],
 ) {
-    let msg = format!("vtable entries for `{}`: {:#?}", trait_ref, entries);
-    tcx.sess.struct_span_err(sp, &msg).emit();
+    tcx.sess.emit_err(DumpVTableEntries {
+        span: sp,
+        trait_ref,
+        entries: format!("{:#?}", entries),
+    });
 }
 
 fn own_existential_vtable_entries<'tcx>(
index 9227bbf011dbfcb2c2d43475778289ed38f2bbf5..3d8840e9e7421b22de38bffe66d9ebb0a4eec556 100644 (file)
@@ -8,6 +8,10 @@
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
+use crate::errors::{
+    EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
+};
+
 #[derive(Clone, Debug)]
 pub struct OnUnimplementedFormatString(Symbol);
 
@@ -35,21 +39,6 @@ pub struct OnUnimplementedNote {
     pub append_const_msg: Option<Option<Symbol>>,
 }
 
-fn parse_error(
-    tcx: TyCtxt<'_>,
-    span: Span,
-    message: &str,
-    label: &str,
-    note: Option<&str>,
-) -> ErrorGuaranteed {
-    let mut diag = struct_span_err!(tcx.sess, span, E0232, "{}", message);
-    diag.span_label(span, label);
-    if let Some(note) = note {
-        diag.note(note);
-    }
-    diag.emit()
-}
-
 impl<'tcx> OnUnimplementedDirective {
     fn parse(
         tcx: TyCtxt<'tcx>,
@@ -70,25 +59,9 @@ fn parse(
         } else {
             let cond = item_iter
                 .next()
-                .ok_or_else(|| {
-                    parse_error(
-                        tcx,
-                        span,
-                        "empty `on`-clause in `#[rustc_on_unimplemented]`",
-                        "empty on-clause here",
-                        None,
-                    )
-                })?
+                .ok_or_else(|| tcx.sess.emit_err(EmptyOnClauseInOnUnimplemented { span }))?
                 .meta_item()
-                .ok_or_else(|| {
-                    parse_error(
-                        tcx,
-                        span,
-                        "invalid `on`-clause in `#[rustc_on_unimplemented]`",
-                        "invalid on-clause here",
-                        None,
-                    )
-                })?;
+                .ok_or_else(|| tcx.sess.emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
             attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| {
                 if let Some(value) = cfg.value && let Err(guar) = parse_value(value) {
                     errored = Some(guar);
@@ -150,13 +123,7 @@ fn parse(
             }
 
             // nothing found
-            parse_error(
-                tcx,
-                item.span(),
-                "this attribute must have a valid value",
-                "expected value here",
-                Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#),
-            );
+            tcx.sess.emit_err(NoValueInOnUnimplemented { span: item.span() });
         }
 
         if let Some(reported) = errored {
index 0f76fef0eee228168c49a3d5128776dd1338574f..7d299e30ae041290a3760f6295a0fff0da46c452 100644 (file)
@@ -12,6 +12,7 @@
 pub mod specialization_graph;
 use specialization_graph::GraphExt;
 
+use crate::errors::NegativePositiveConflict;
 use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
@@ -327,35 +328,13 @@ fn report_negative_positive_conflict(
     positive_impl_def_id: DefId,
     sg: &mut specialization_graph::Graph,
 ) {
-    let impl_span = tcx.def_span(local_impl_def_id);
-
-    let mut err = struct_span_err!(
-        tcx.sess,
-        impl_span,
-        E0751,
-        "found both positive and negative implementation of trait `{}`{}:",
-        overlap.trait_desc,
-        overlap.self_desc.clone().map_or_else(String::new, |ty| format!(" for type `{}`", ty))
-    );
-
-    match tcx.span_of_impl(negative_impl_def_id) {
-        Ok(span) => {
-            err.span_label(span, "negative implementation here");
-        }
-        Err(cname) => {
-            err.note(&format!("negative implementation in crate `{}`", cname));
-        }
-    }
-
-    match tcx.span_of_impl(positive_impl_def_id) {
-        Ok(span) => {
-            err.span_label(span, "positive implementation here");
-        }
-        Err(cname) => {
-            err.note(&format!("positive implementation in crate `{}`", cname));
-        }
-    }
-
+    let mut err = tcx.sess.create_err(NegativePositiveConflict {
+        impl_span: tcx.def_span(local_impl_def_id),
+        trait_desc: &overlap.trait_desc,
+        self_desc: &overlap.self_desc,
+        negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
+        positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
+    });
     sg.has_errored = Some(err.emit());
 }