Skip to content

Commit 8e82200

Browse files
committed
Porting 'compiler/rustc_trait_selection' to translatable diagnostics - Part 1
1 parent fb88811 commit 8e82200

File tree

12 files changed

+180
-87
lines changed

12 files changed

+180
-87
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
2+
3+
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
4+
5+
trait_selection_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
6+
.label = deref recursion limit reached
7+
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
8+
9+
trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
10+
.label = empty on-clause here
11+
12+
trait_selection_invalid_on_clause_in_rustc_on_unimplemented = invalid `on`-clause in `#[rustc_on_unimplemented]`
13+
.label = invalid on-clause here
14+
15+
trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a valid value
16+
.label = expected value here
17+
.note = eg `#[rustc_on_unimplemented(message="foo")]`
18+
19+
trait_selection_negative_positive_conflict = found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
20+
[none] {""}
21+
*[default] {" "}for type `{$self_desc}`
22+
}:
23+
.negative_implementation_here = negative implementation here
24+
.negative_implementation_in_crate = negative implementation in crate `{$negative_impl_cname}`
25+
.positive_implementation_here = positive implementation here
26+
.positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}`

compiler/rustc_error_messages/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fluent_messages! {
5151
plugin_impl => "../locales/en-US/plugin_impl.ftl",
5252
privacy => "../locales/en-US/privacy.ftl",
5353
query_system => "../locales/en-US/query_system.ftl",
54+
trait_selection => "../locales/en-US/trait_selection.ftl",
5455
save_analysis => "../locales/en-US/save_analysis.ftl",
5556
ty_utils => "../locales/en-US/ty_utils.ftl",
5657
typeck => "../locales/en-US/typeck.ftl",

compiler/rustc_middle/src/ty/consts/kind.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ pub struct Unevaluated<'tcx, P = Option<Promoted>> {
2020
pub promoted: P,
2121
}
2222

23+
impl rustc_errors::IntoDiagnosticArg for Unevaluated<'_> {
24+
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
25+
format!("{:?}", self).into_diagnostic_arg()
26+
}
27+
}
28+
2329
impl<'tcx> Unevaluated<'tcx> {
2430
#[inline]
2531
pub fn shrink(self) -> Unevaluated<'tcx, ()> {

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,12 @@ impl<'tcx> PolyTraitRef<'tcx> {
849849
}
850850
}
851851

852+
impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> {
853+
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
854+
self.to_string().into_diagnostic_arg()
855+
}
856+
}
857+
852858
/// An existential reference to a trait, where `Self` is erased.
853859
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
854860
/// ```ignore (illustrative)

compiler/rustc_session/src/session.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ impl Mul<usize> for Limit {
110110
}
111111
}
112112

113+
impl rustc_errors::IntoDiagnosticArg for Limit {
114+
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
115+
self.to_string().into_diagnostic_arg()
116+
}
117+
}
118+
113119
#[derive(Clone, Copy, Debug, HashStable_Generic)]
114120
pub struct Limits {
115121
/// The maximum recursion limit for potentially infinitely recursive

compiler/rustc_trait_selection/src/autoderef.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
use crate::errors::AutoDerefReachedRecursionLimit;
12
use crate::traits::query::evaluate_obligation::InferCtxtExt;
23
use crate::traits::{self, TraitEngine};
3-
use rustc_errors::struct_span_err;
44
use rustc_hir as hir;
55
use rustc_infer::infer::InferCtxt;
66
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
222222
Limit(0) => Limit(2),
223223
limit => limit * 2,
224224
};
225-
struct_span_err!(
226-
tcx.sess,
225+
tcx.sess.emit_err(AutoDerefReachedRecursionLimit {
227226
span,
228-
E0055,
229-
"reached the recursion limit while auto-dereferencing `{:?}`",
230-
ty
231-
)
232-
.span_label(span, "deref recursion limit reached")
233-
.help(&format!(
234-
"consider increasing the recursion limit by adding a \
235-
`#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
227+
ty,
236228
suggested_limit,
237-
tcx.crate_name(LOCAL_CRATE),
238-
))
239-
.emit();
229+
crate_name: tcx.crate_name(LOCAL_CRATE),
230+
});
240231
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use rustc_errors::{fluent, ErrorGuaranteed};
2+
use rustc_macros::SessionDiagnostic;
3+
use rustc_middle::ty::{PolyTraitRef, Ty, Unevaluated};
4+
use rustc_session::{parse::ParseSess, Limit, SessionDiagnostic};
5+
use rustc_span::{Span, Symbol};
6+
7+
#[derive(SessionDiagnostic)]
8+
#[diag(trait_selection::dump_vtable_entries)]
9+
pub struct DumpVTableEntries<'a> {
10+
#[primary_span]
11+
pub span: Span,
12+
pub trait_ref: PolyTraitRef<'a>,
13+
pub entries: String,
14+
}
15+
16+
#[derive(SessionDiagnostic)]
17+
#[diag(trait_selection::unable_to_construct_constant_value)]
18+
pub struct UnableToConstructConstantValue<'a> {
19+
#[primary_span]
20+
pub span: Span,
21+
pub unevaluated: Unevaluated<'a>,
22+
}
23+
24+
#[derive(SessionDiagnostic)]
25+
#[help]
26+
#[diag(trait_selection::auto_deref_reached_recursion_limit, code = "E0055")]
27+
pub struct AutoDerefReachedRecursionLimit<'a> {
28+
#[primary_span]
29+
#[label]
30+
pub span: Span,
31+
pub ty: Ty<'a>,
32+
pub suggested_limit: Limit,
33+
pub crate_name: Symbol,
34+
}
35+
36+
#[derive(SessionDiagnostic)]
37+
#[diag(trait_selection::empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
38+
pub struct EmptyOnClauseInOnUnimplemented {
39+
#[primary_span]
40+
#[label]
41+
pub span: Span,
42+
}
43+
44+
#[derive(SessionDiagnostic)]
45+
#[diag(trait_selection::invalid_on_clause_in_rustc_on_unimplemented, code = "E0232")]
46+
pub struct InvalidOnClauseInOnUnimplemented {
47+
#[primary_span]
48+
#[label]
49+
pub span: Span,
50+
}
51+
52+
#[derive(SessionDiagnostic)]
53+
#[diag(trait_selection::no_value_in_rustc_on_unimplemented, code = "E0232")]
54+
#[note]
55+
pub struct NoValueInOnUnimplemented {
56+
#[primary_span]
57+
#[label]
58+
pub span: Span,
59+
}
60+
61+
pub struct NegativePositiveConflict<'a> {
62+
pub impl_span: Span,
63+
pub trait_desc: &'a str,
64+
pub self_desc: &'a Option<String>,
65+
pub negative_impl_span: Result<Span, Symbol>,
66+
pub positive_impl_span: Result<Span, Symbol>,
67+
}
68+
69+
impl SessionDiagnostic<'_> for NegativePositiveConflict<'_> {
70+
fn into_diagnostic(
71+
self,
72+
sess: &ParseSess,
73+
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
74+
let mut diag = sess.struct_err(fluent::trait_selection::negative_positive_conflict);
75+
diag.set_arg("trait_desc", self.trait_desc);
76+
diag.set_arg(
77+
"self_desc",
78+
self.self_desc.clone().map_or_else(|| String::from("none"), |ty| ty),
79+
);
80+
diag.set_span(self.impl_span);
81+
diag.code(rustc_errors::error_code!(E0751));
82+
match self.negative_impl_span {
83+
Ok(span) => {
84+
diag.span_label(span, fluent::trait_selection::negative_implementation_here);
85+
}
86+
Err(cname) => {
87+
diag.note(fluent::trait_selection::negative_implementation_in_crate);
88+
diag.set_arg("negative_impl_cname", cname.to_string());
89+
}
90+
}
91+
match self.positive_impl_span {
92+
Ok(span) => {
93+
diag.span_label(span, fluent::trait_selection::positive_implementation_here);
94+
}
95+
Err(cname) => {
96+
diag.note(fluent::trait_selection::positive_implementation_in_crate);
97+
diag.set_arg("positive_impl_cname", cname.to_string());
98+
}
99+
}
100+
diag
101+
}
102+
}

compiler/rustc_trait_selection/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ extern crate rustc_middle;
3737
extern crate smallvec;
3838

3939
pub mod autoderef;
40+
pub mod errors;
4041
pub mod infer;
4142
pub mod traits;

compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
use super::*;
55

6+
use crate::errors::UnableToConstructConstantValue;
67
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
78
use crate::infer::InferCtxt;
89
use crate::traits::project::ProjectAndUnifyResult;
@@ -830,8 +831,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
830831
Ok(None) => {
831832
let tcx = self.tcx;
832833
let def_id = unevaluated.def.did;
833-
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();
834-
834+
let reported =
835+
tcx.sess.emit_err(UnableToConstructConstantValue {
836+
span: tcx.def_span(def_id),
837+
unevaluated,
838+
});
835839
Err(ErrorHandled::Reported(reported))
836840
}
837841
Err(err) => Err(err),

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ mod structural_match;
2323
mod util;
2424
pub mod wf;
2525

26+
use crate::errors::DumpVTableEntries;
2627
use crate::infer::outlives::env::OutlivesEnvironment;
2728
use crate::infer::{InferCtxt, TyCtxtInferExt};
2829
use crate::traits::error_reporting::InferCtxtExt as _;
@@ -763,8 +764,11 @@ fn dump_vtable_entries<'tcx>(
763764
trait_ref: ty::PolyTraitRef<'tcx>,
764765
entries: &[VtblEntry<'tcx>],
765766
) {
766-
let msg = format!("vtable entries for `{}`: {:#?}", trait_ref, entries);
767-
tcx.sess.struct_span_err(sp, &msg).emit();
767+
tcx.sess.emit_err(DumpVTableEntries {
768+
span: sp,
769+
trait_ref,
770+
entries: format!("{:#?}", entries),
771+
});
768772
}
769773

770774
fn own_existential_vtable_entries<'tcx>(

0 commit comments

Comments
 (0)