Skip to content

Commit 137f20c

Browse files
committed
rebased: convert rustc_monomorphize errors to SessionDiagnostic
1 parent 4d45b07 commit 137f20c

File tree

10 files changed

+170
-41
lines changed

10 files changed

+170
-41
lines changed

Cargo.lock

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4253,8 +4253,10 @@ name = "rustc_monomorphize"
42534253
version = "0.0.0"
42544254
dependencies = [
42554255
"rustc_data_structures",
4256+
"rustc_errors",
42564257
"rustc_hir",
42574258
"rustc_index",
4259+
"rustc_macros",
42584260
"rustc_middle",
42594261
"rustc_session",
42604262
"rustc_span",
@@ -4995,9 +4997,9 @@ checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e"
49954997

49964998
[[package]]
49974999
name = "snapbox"
4998-
version = "0.3.3"
5000+
version = "0.2.10"
49995001
source = "registry+https://github.com/rust-lang/crates.io-index"
5000-
checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7"
5002+
checksum = "767a1d5da232b6959cd1bd5c9e8db8a7cce09c3038e89deedb49a549a2aefd93"
50015003
dependencies = [
50025004
"concolor",
50035005
"content_inspector",
@@ -5013,9 +5015,9 @@ dependencies = [
50135015

50145016
[[package]]
50155017
name = "snapbox-macros"
5016-
version = "0.3.0"
5018+
version = "0.2.1"
50175019
source = "registry+https://github.com/rust-lang/crates.io-index"
5018-
checksum = "8a253e6f894cfa440cba00600a249fa90869d8e0ec45ab274a456e043a0ce8f2"
5020+
checksum = "c01dea7e04cbb27ef4c86e9922184608185f7cd95c1763bc30d727cda4a5e930"
50195021

50205022
[[package]]
50215023
name = "socket2"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
monomorphize_recursion_limit =
2+
reached the recursion limit while instantiating `{$shrunk}`
3+
.note = `{$def_path_str}` defined here
4+
5+
monomorphize_written_to_path = the full type name has been written to '{$path}'
6+
7+
monomorphize_type_length_limit = reached the type-length limit while instantiating `{$shrunk}`
8+
9+
monomorphize_consider_type_length_limit =
10+
consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate
11+
12+
monomorphize_fatal_error = {$error_message}
13+
14+
monomorphize_unused_generic_params = item has unused generic parameters
15+
16+
monomorphize_large_assignments =
17+
moving {$size} bytes
18+
.label = value moved from here
19+
.note = The current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`

compiler/rustc_error_messages/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ fluent_messages! {
3939
expand => "../locales/en-US/expand.ftl",
4040
interface => "../locales/en-US/interface.ftl",
4141
lint => "../locales/en-US/lint.ftl",
42+
monomorphize => "../locales/en-US/monomorphize.ftl",
4243
parser => "../locales/en-US/parser.ftl",
4344
passes => "../locales/en-US/passes.ftl",
4445
plugin_impl => "../locales/en-US/plugin_impl.ftl",

compiler/rustc_monomorphize/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ edition = "2021"
77
doctest = false
88

99
[dependencies]
10-
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
10+
smallvec = { version = "1.8.1", features = [ "union", "may_dangle" ] }
1111
tracing = "0.1"
1212
rustc_data_structures = { path = "../rustc_data_structures" }
13+
rustc_errors = { path = "../rustc_errors" }
1314
rustc_hir = { path = "../rustc_hir" }
1415
rustc_index = { path = "../rustc_index" }
16+
rustc_macros = { path = "../rustc_macros" }
1517
rustc_middle = { path = "../rustc_middle" }
1618
rustc_session = { path = "../rustc_session" }
1719
rustc_span = { path = "../rustc_span" }

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ use std::iter;
207207
use std::ops::Range;
208208
use std::path::PathBuf;
209209

210+
use crate::errors::{FatalError, LargeAssignmentsLint, RecursionLimit, TypeLengthLimit};
211+
210212
#[derive(PartialEq)]
211213
pub enum MonoItemCollectionMode {
212214
Eager,
@@ -604,17 +606,24 @@ fn check_recursion_limit<'tcx>(
604606
// more than the recursion limit is assumed to be causing an
605607
// infinite expansion.
606608
if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
609+
let def_span = tcx.def_span(def_id);
610+
let def_path_str = tcx.def_path_str(def_id);
607611
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
608-
let error = format!("reached the recursion limit while instantiating `{}`", shrunk);
609-
let mut err = tcx.sess.struct_span_fatal(span, &error);
610-
err.span_note(
611-
tcx.def_span(def_id),
612-
&format!("`{}` defined here", tcx.def_path_str(def_id)),
613-
);
614-
if let Some(path) = written_to_path {
615-
err.note(&format!("the full type name has been written to '{}'", path.display()));
616-
}
617-
err.emit()
612+
let mut path = PathBuf::new();
613+
let was_written = if written_to_path.is_some() {
614+
path = written_to_path.unwrap();
615+
Some(())
616+
} else {
617+
None
618+
};
619+
tcx.sess.emit_fatal(RecursionLimit {
620+
span,
621+
shrunk,
622+
def_span,
623+
def_path_str,
624+
was_written,
625+
path,
626+
});
618627
}
619628

620629
recursion_depths.insert(def_id, recursion_depth + 1);
@@ -642,16 +651,15 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
642651
// Bail out in these cases to avoid that bad user experience.
643652
if !tcx.type_length_limit().value_within_limit(type_length) {
644653
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
645-
let msg = format!("reached the type-length limit while instantiating `{}`", shrunk);
646-
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
647-
if let Some(path) = written_to_path {
648-
diag.note(&format!("the full type name has been written to '{}'", path.display()));
649-
}
650-
diag.help(&format!(
651-
"consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
652-
type_length
653-
));
654-
diag.emit()
654+
let span = tcx.def_span(instance.def_id());
655+
let mut path = PathBuf::new();
656+
let was_written = if written_to_path.is_some() {
657+
path = written_to_path.unwrap();
658+
Some(())
659+
} else {
660+
None
661+
};
662+
tcx.sess.emit_fatal(TypeLengthLimit { span, shrunk, was_written, path, type_length });
655663
}
656664
}
657665

@@ -914,17 +922,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
914922
// but correct span? This would make the lint at least accept crate-level lint attributes.
915923
return;
916924
};
917-
self.tcx.struct_span_lint_hir(
925+
self.tcx.emit_spanned_lint(
918926
LARGE_ASSIGNMENTS,
919927
lint_root,
920928
source_info.span,
921-
|lint| {
922-
let mut err = lint.build(&format!("moving {} bytes", layout.size.bytes()));
923-
err.span_label(source_info.span, "value moved from here");
924-
err.note(&format!(r#"The current maximum size is {}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`"#, limit.bytes()));
925-
err.emit();
929+
LargeAssignmentsLint {
930+
span: source_info.span,
931+
size: layout.size.bytes(),
932+
limit: limit.bytes(),
926933
},
927-
);
934+
)
928935
}
929936
}
930937
}
@@ -1321,7 +1328,9 @@ impl<'v> RootCollector<'_, 'v> {
13211328

13221329
let start_def_id = match self.tcx.lang_items().require(LangItem::Start) {
13231330
Ok(s) => s,
1324-
Err(err) => self.tcx.sess.fatal(&err),
1331+
Err(error_message) => {
1332+
self.tcx.sess.emit_fatal(FatalError { error_message: error_message.clone() });
1333+
}
13251334
};
13261335
let main_ret_ty = self.tcx.fn_sig(main_def_id).output();
13271336

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use std::path::PathBuf;
2+
3+
use rustc_errors::ErrorGuaranteed;
4+
use rustc_macros::{LintDiagnostic, SessionDiagnostic};
5+
use rustc_session::SessionDiagnostic;
6+
// use rustc_session::SessionDiagnostic;
7+
use rustc_span::Span;
8+
9+
#[derive(SessionDiagnostic)]
10+
#[diag(monomorphize::recursion_limit)]
11+
pub struct RecursionLimit {
12+
#[primary_span]
13+
pub span: Span,
14+
pub shrunk: String,
15+
#[note]
16+
pub def_span: Span,
17+
pub def_path_str: String,
18+
#[note(monomorphize::written_to_path)]
19+
pub was_written: Option<()>,
20+
pub path: PathBuf,
21+
}
22+
23+
#[derive(SessionDiagnostic)]
24+
#[diag(monomorphize::type_length_limit)]
25+
#[help(monomorphize::consider_type_length_limit)]
26+
pub struct TypeLengthLimit {
27+
#[primary_span]
28+
pub span: Span,
29+
pub shrunk: String,
30+
#[note(monomorphize::written_to_path)]
31+
pub was_written: Option<()>,
32+
pub path: PathBuf,
33+
pub type_length: usize,
34+
}
35+
36+
#[derive(SessionDiagnostic)]
37+
#[diag(monomorphize::fatal_error)]
38+
pub struct FatalError {
39+
pub error_message: String,
40+
}
41+
42+
#[derive(SessionDiagnostic)]
43+
#[diag(monomorphize::fatal_error)]
44+
pub struct SpanFatalError {
45+
#[primary_span]
46+
pub span: Span,
47+
pub error_message: String,
48+
}
49+
50+
pub struct UnusedGenericParams {
51+
pub span: Span,
52+
pub param_spans: Vec<Span>,
53+
pub param_names: Vec<String>,
54+
}
55+
56+
impl SessionDiagnostic<'_> for UnusedGenericParams {
57+
fn into_diagnostic(
58+
self,
59+
sess: &'_ rustc_session::parse::ParseSess,
60+
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
61+
let mut diag = sess.struct_err(rustc_errors::fluent::monomorphize::unused_generic_params);
62+
diag.set_span(self.span);
63+
for (span, name) in self.param_spans.into_iter().zip(self.param_names) {
64+
// FIXME: I can figure out how to do a label with a fluent string with a fixed message,
65+
// or a label with a dynamic value in a hard-coded string, but I haven't figured out
66+
// how to combine the two. 😢
67+
diag.span_label(span, format!("generic parameter `{}` is unused", name));
68+
}
69+
diag
70+
}
71+
}
72+
73+
#[derive(LintDiagnostic)]
74+
#[diag(monomorphize::large_assignments)]
75+
#[note]
76+
pub struct LargeAssignmentsLint {
77+
#[label]
78+
pub span: Span,
79+
pub size: u64,
80+
pub limit: u64,
81+
}

compiler/rustc_monomorphize/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#![feature(let_else)]
44
#![recursion_limit = "256"]
55
#![allow(rustc::potential_query_instability)]
6+
#![deny(rustc::untranslatable_diagnostic)]
7+
#![deny(rustc::diagnostic_outside_of_impl)]
68

79
#[macro_use]
810
extern crate tracing;
@@ -16,6 +18,7 @@ use rustc_middle::ty::query::Providers;
1618
use rustc_middle::ty::{self, Ty, TyCtxt};
1719

1820
mod collector;
21+
mod errors;
1922
mod partitioning;
2023
mod polymorphize;
2124
mod util;

compiler/rustc_monomorphize/src/partitioning/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ use rustc_span::symbol::Symbol;
108108

109109
use crate::collector::InliningMap;
110110
use crate::collector::{self, MonoItemCollectionMode};
111+
use crate::errors::{FatalError, SpanFatalError};
111112

112113
pub struct PartitioningCx<'a, 'tcx> {
113114
tcx: TyCtxt<'tcx>,
@@ -149,7 +150,10 @@ fn get_partitioner<'tcx>(tcx: TyCtxt<'tcx>) -> Box<dyn Partitioner<'tcx>> {
149150

150151
match strategy {
151152
"default" => Box::new(default::DefaultPartitioning),
152-
_ => tcx.sess.fatal("unknown partitioning strategy"),
153+
_ => {
154+
let error_message = "unknown partitioning strategy".to_string();
155+
tcx.sess.emit_fatal(FatalError { error_message: error_message.clone() });
156+
}
153157
}
154158
}
155159

@@ -334,9 +338,9 @@ where
334338
let error_message = format!("symbol `{}` is already defined", sym1);
335339

336340
if let Some(span) = span {
337-
tcx.sess.span_fatal(span, &error_message)
341+
tcx.sess.emit_fatal(SpanFatalError { span, error_message: error_message.clone() });
338342
} else {
339-
tcx.sess.fatal(&error_message)
343+
tcx.sess.emit_fatal(FatalError { error_message: error_message.clone() });
340344
}
341345
}
342346
}

compiler/rustc_monomorphize/src/polymorphize.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use rustc_span::symbol::sym;
2222
use std::convert::TryInto;
2323
use std::ops::ControlFlow;
2424

25+
use crate::errors::UnusedGenericParams;
26+
2527
/// Provide implementations of queries relating to polymorphization analysis.
2628
pub fn provide(providers: &mut Providers) {
2729
providers.unused_generic_params = unused_generic_params;
@@ -206,22 +208,28 @@ fn emit_unused_generic_params_error<'tcx>(
206208
_ => tcx.def_span(def_id),
207209
};
208210

209-
let mut err = tcx.sess.struct_span_err(fn_span, "item has unused generic parameters");
210-
211+
let mut param_spans = Vec::new();
212+
let mut param_names = Vec::new();
211213
let mut next_generics = Some(generics);
212214
while let Some(generics) = next_generics {
213215
for param in &generics.params {
214216
if unused_parameters.contains(param.index).unwrap_or(false) {
215217
debug!(?param);
216218
let def_span = tcx.def_span(param.def_id);
217-
err.span_label(def_span, &format!("generic parameter `{}` is unused", param.name));
219+
// 🤔 The docs say
220+
//
221+
// Any attribute applied to a Vec<T> will be repeated for each element of the vector.
222+
//
223+
// But they don't say what template variable to use to substitute each value into the message!?
224+
param_spans.push(def_span);
225+
param_names.push(param.name.to_string());
218226
}
219227
}
220228

221229
next_generics = generics.parent.map(|did| tcx.generics_of(did));
222230
}
223231

224-
err.emit();
232+
tcx.sess.emit_err(UnusedGenericParams { span: fn_span, param_spans, param_names });
225233
}
226234

227235
/// Visitor used to aggregate generic parameter uses.

0 commit comments

Comments
 (0)