Skip to content

Commit 06ff310

Browse files
committed
Migrate rustc_hir_analysis to session diagnostic
Part 4: Finishing `check/mod.rs` file
1 parent fa4cc63 commit 06ff310

File tree

5 files changed

+254
-85
lines changed

5 files changed

+254
-85
lines changed

compiler/rustc_hir_analysis/messages.ftl

+37
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,40 @@ hir_analysis_functions_names_duplicated = functions names are duplicated
225225
226226
hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code
227227
.help = add `#![feature(simd_ffi)]` to the crate attributes to enable
228+
229+
hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
230+
.label = cannot specialize default item `{$ident}`
231+
.ok_label = parent `impl` is here
232+
.note = to specialize, `{$ident}` in the parent `impl` must be marked `default`
233+
234+
hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
235+
.note = parent implementation is in crate `{$cname}`
236+
237+
hir_analysis_missing_trait_item = not all trait items implemented, missing: `{$missing_items_msg}`
238+
.label = missing `{$missing_items_msg}` in implementation
239+
240+
hir_analysis_missing_trait_item_suggestion = implement the missing item: `{$snippet}`
241+
242+
hir_analysis_missing_trait_item_label = `{$item}` from trait
243+
244+
hir_analysis_missing_one_of_trait_item = not all trait items implemented, missing one of: `{$missing_items_msg}`
245+
.label = missing one of `{$missing_items_msg}` in implementation
246+
.note = required because of this annotation
247+
248+
hir_analysis_missing_trait_item_unstable = not all trait items implemented, missing: `{$missing_item_name}`
249+
.note = default implementation of `{$missing_item_name}` is unstable
250+
.some_note = use of unstable library feature '{$feature}': {$r}
251+
.none_note = use of unstable library feature '{$feature}'
252+
253+
hir_analysis_transparent_enum_variant = transparent enum needs exactly one variant, but has {$number}
254+
.label = needs exactly one variant, but has {$number}
255+
.many_label = too many variants in `{$path}`
256+
.multi_label = variant here
257+
258+
hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$desc} needs at most one non-zero-sized field, but has {$field_count}
259+
.label = needs at most one non-zero-sized field, but has {$field_count}
260+
.labels = this field is non-zero-sized
261+
262+
hir_analysis_transparent_non_zero_sized = transparent {$desc} needs at most one non-zero-sized field, but has {$field_count}
263+
.label = needs at most one non-zero-sized field, but has {$field_count}
264+
.labels = this field is non-zero-sized

compiler/rustc_hir_analysis/src/check/mod.rs

+76-84
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub use check::check_abi;
7474

7575
use check::check_mod_item_types;
7676
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
77-
use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder};
77+
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
7878
use rustc_hir::def_id::{DefId, LocalDefId};
7979
use rustc_hir::intravisit::Visitor;
8080
use rustc_index::bit_set::BitSet;
@@ -90,6 +90,7 @@ use rustc_target::spec::abi::Abi;
9090
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
9191
use std::num::NonZeroU32;
9292

93+
use crate::errors;
9394
use crate::require_c_abi_if_c_variadic;
9495
use crate::util::common::indenter;
9596

@@ -171,29 +172,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
171172
fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_impl: DefId) {
172173
let span = tcx.def_span(impl_item);
173174
let ident = tcx.item_name(impl_item);
174-
let mut err = struct_span_err!(
175-
tcx.sess,
176-
span,
177-
E0520,
178-
"`{}` specializes an item from a parent `impl`, but that item is not marked `default`",
179-
ident,
180-
);
181-
err.span_label(span, format!("cannot specialize default item `{}`", ident));
182-
183-
match tcx.span_of_impl(parent_impl) {
184-
Ok(span) => {
185-
err.span_label(span, "parent `impl` is here");
186-
err.note(&format!(
187-
"to specialize, `{}` in the parent `impl` must be marked `default`",
188-
ident
189-
));
190-
}
191-
Err(cname) => {
192-
err.note(&format!("parent implementation is in crate `{cname}`"));
193-
}
194-
}
195175

196-
err.emit();
176+
let err = match tcx.span_of_impl(parent_impl) {
177+
Ok(sp) => errors::ImplNotMarkedDefault::Ok { span, ident, ok_label: sp },
178+
Err(cname) => errors::ImplNotMarkedDefault::Err { span, ident, cname },
179+
};
180+
181+
tcx.sess.emit_err(err);
197182
}
198183

199184
fn missing_items_err(
@@ -211,15 +196,6 @@ fn missing_items_err(
211196
.collect::<Vec<_>>()
212197
.join("`, `");
213198

214-
let impl_span = tcx.def_span(impl_def_id);
215-
let mut err = struct_span_err!(
216-
tcx.sess,
217-
impl_span,
218-
E0046,
219-
"not all trait items implemented, missing: `{missing_items_msg}`",
220-
);
221-
err.span_label(impl_span, format!("missing `{missing_items_msg}` in implementation"));
222-
223199
// `Span` before impl block closing brace.
224200
let hi = full_impl_span.hi() - BytePos(1);
225201
// Point at the place right before the closing brace of the relevant `impl` to suggest
@@ -228,6 +204,8 @@ fn missing_items_err(
228204
// Obtain the level of indentation ending in `sugg_sp`.
229205
let padding =
230206
tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
207+
let (mut missing_trait_item, mut missing_trait_item_none, mut missing_trait_item_label) =
208+
(Vec::new(), Vec::new(), Vec::new());
231209

232210
for &trait_item in missing_items {
233211
let snippet = suggestion_signature(
@@ -236,16 +214,30 @@ fn missing_items_err(
236214
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(),
237215
);
238216
let code = format!("{}{}\n{}", padding, snippet, padding);
239-
let msg = format!("implement the missing item: `{snippet}`");
240-
let appl = Applicability::HasPlaceholders;
241217
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
242-
err.span_label(span, format!("`{}` from trait", trait_item.name));
243-
err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
218+
missing_trait_item_label
219+
.push(errors::MissingTraitItemLabel { span, item: trait_item.name });
220+
missing_trait_item.push(errors::MissingTraitItemSuggestion {
221+
span: sugg_sp,
222+
code,
223+
snippet,
224+
});
244225
} else {
245-
err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
226+
missing_trait_item_none.push(errors::MissingTraitItemSuggestionNone {
227+
span: sugg_sp,
228+
code,
229+
snippet,
230+
})
246231
}
247232
}
248-
err.emit();
233+
234+
tcx.sess.emit_err(errors::MissingTraitItem {
235+
span: tcx.span_of_impl(impl_def_id.to_def_id()).unwrap(),
236+
missing_items_msg,
237+
missing_trait_item_label,
238+
missing_trait_item,
239+
missing_trait_item_none,
240+
});
249241
}
250242

251243
fn missing_items_must_implement_one_of_err(
@@ -257,19 +249,11 @@ fn missing_items_must_implement_one_of_err(
257249
let missing_items_msg =
258250
missing_items.iter().map(Ident::to_string).collect::<Vec<_>>().join("`, `");
259251

260-
let mut err = struct_span_err!(
261-
tcx.sess,
262-
impl_span,
263-
E0046,
264-
"not all trait items implemented, missing one of: `{missing_items_msg}`",
265-
);
266-
err.span_label(impl_span, format!("missing one of `{missing_items_msg}` in implementation"));
267-
268-
if let Some(annotation_span) = annotation_span {
269-
err.span_note(annotation_span, "required because of this annotation");
270-
}
271-
272-
err.emit();
252+
tcx.sess.emit_err(errors::MissingOneOfTraitItem {
253+
span: impl_span,
254+
note: annotation_span,
255+
missing_items_msg,
256+
});
273257
}
274258

275259
fn default_body_is_unstable(
@@ -281,25 +265,31 @@ fn default_body_is_unstable(
281265
issue: Option<NonZeroU32>,
282266
) {
283267
let missing_item_name = tcx.associated_item(item_did).name;
284-
let use_of_unstable_library_feature_note = match reason {
285-
Some(r) => format!("use of unstable library feature '{feature}': {r}"),
286-
None => format!("use of unstable library feature '{feature}'"),
268+
let (mut some_note, mut none_note, mut reason_str) = (false, false, String::new());
269+
match reason {
270+
Some(r) => {
271+
some_note = true;
272+
reason_str = r.to_string();
273+
}
274+
None => none_note = true,
287275
};
288276

289-
let mut err = struct_span_err!(
290-
tcx.sess,
291-
impl_span,
292-
E0046,
293-
"not all trait items implemented, missing: `{missing_item_name}`",
294-
);
295-
err.note(format!("default implementation of `{missing_item_name}` is unstable"));
296-
err.note(use_of_unstable_library_feature_note);
277+
let mut err = tcx.sess.create_err(errors::MissingTraitItemUnstable {
278+
span: impl_span,
279+
some_note,
280+
none_note,
281+
missing_item_name,
282+
feature,
283+
reason: reason_str,
284+
});
285+
297286
rustc_session::parse::add_feature_diagnostics_for_issue(
298287
&mut err,
299288
&tcx.sess.parse_sess,
300289
feature,
301290
rustc_feature::GateIssue::Library(issue),
302291
);
292+
303293
err.emit();
304294
}
305295

@@ -488,16 +478,18 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d
488478
.iter()
489479
.map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
490480
.collect();
491-
let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),);
492-
let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {msg}");
493-
err.span_label(sp, &msg);
481+
let (mut spans, mut many) = (Vec::new(), None);
494482
if let [start @ .., end] = &*variant_spans {
495-
for variant_span in start {
496-
err.span_label(*variant_span, "");
497-
}
498-
err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
483+
spans = start.to_vec();
484+
many = Some(*end);
499485
}
500-
err.emit();
486+
tcx.sess.emit_err(errors::TransparentEnumVariant {
487+
span: sp,
488+
spans,
489+
many,
490+
number: adt.variants().len(),
491+
path: tcx.def_path_str(did),
492+
});
501493
}
502494

503495
/// Emit an error when encountering two or more non-zero-sized fields in a transparent
@@ -509,21 +501,21 @@ fn bad_non_zero_sized_fields<'tcx>(
509501
field_spans: impl Iterator<Item = Span>,
510502
sp: Span,
511503
) {
512-
let msg = format!("needs at most one non-zero-sized field, but has {field_count}");
513-
let mut err = struct_span_err!(
514-
tcx.sess,
515-
sp,
516-
E0690,
517-
"{}transparent {} {}",
518-
if adt.is_enum() { "the variant of a " } else { "" },
519-
adt.descr(),
520-
msg,
521-
);
522-
err.span_label(sp, &msg);
523-
for sp in field_spans {
524-
err.span_label(sp, "this field is non-zero-sized");
504+
if adt.is_enum() {
505+
tcx.sess.emit_err(errors::TransparentNonZeroSizedEnum {
506+
span: sp,
507+
spans: field_spans.collect(),
508+
field_count,
509+
desc: adt.descr(),
510+
});
511+
} else {
512+
tcx.sess.emit_err(errors::TransparentNonZeroSized {
513+
span: sp,
514+
spans: field_spans.collect(),
515+
field_count,
516+
desc: adt.descr(),
517+
});
525518
}
526-
err.emit();
527519
}
528520

529521
// FIXME: Consider moving this method to a more fitting place.

0 commit comments

Comments
 (0)