@@ -74,7 +74,7 @@ pub use check::check_abi;
7474
7575use check:: check_mod_item_types;
7676use 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 } ;
7878use rustc_hir:: def_id:: { DefId , LocalDefId } ;
7979use rustc_hir:: intravisit:: Visitor ;
8080use rustc_index:: bit_set:: BitSet ;
@@ -90,6 +90,7 @@ use rustc_target::spec::abi::Abi;
9090use rustc_trait_selection:: traits:: error_reporting:: suggestions:: ReturnsVisitor ;
9191use std:: num:: NonZeroU32 ;
9292
93+ use crate :: errors;
9394use crate :: require_c_abi_if_c_variadic;
9495use crate :: util:: common:: indenter;
9596
@@ -171,29 +172,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
171172fn 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
199184fn 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
251243fn 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
275259fn 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