@@ -74,7 +74,7 @@ pub use check::check_abi;
74
74
75
75
use check:: check_mod_item_types;
76
76
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 } ;
78
78
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
79
79
use rustc_hir:: intravisit:: Visitor ;
80
80
use rustc_index:: bit_set:: BitSet ;
@@ -90,6 +90,7 @@ use rustc_target::spec::abi::Abi;
90
90
use rustc_trait_selection:: traits:: error_reporting:: suggestions:: ReturnsVisitor ;
91
91
use std:: num:: NonZeroU32 ;
92
92
93
+ use crate :: errors;
93
94
use crate :: require_c_abi_if_c_variadic;
94
95
use crate :: util:: common:: indenter;
95
96
@@ -171,29 +172,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
171
172
fn report_forbidden_specialization ( tcx : TyCtxt < ' _ > , impl_item : DefId , parent_impl : DefId ) {
172
173
let span = tcx. def_span ( impl_item) ;
173
174
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
- }
195
175
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) ;
197
182
}
198
183
199
184
fn missing_items_err (
@@ -211,15 +196,6 @@ fn missing_items_err(
211
196
. collect :: < Vec < _ > > ( )
212
197
. join ( "`, `" ) ;
213
198
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
-
223
199
// `Span` before impl block closing brace.
224
200
let hi = full_impl_span. hi ( ) - BytePos ( 1 ) ;
225
201
// Point at the place right before the closing brace of the relevant `impl` to suggest
@@ -228,6 +204,8 @@ fn missing_items_err(
228
204
// Obtain the level of indentation ending in `sugg_sp`.
229
205
let padding =
230
206
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 ( ) ) ;
231
209
232
210
for & trait_item in missing_items {
233
211
let snippet = suggestion_signature (
@@ -236,16 +214,30 @@ fn missing_items_err(
236
214
tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . subst_identity ( ) ,
237
215
) ;
238
216
let code = format ! ( "{}{}\n {}" , padding, snippet, padding) ;
239
- let msg = format ! ( "implement the missing item: `{snippet}`" ) ;
240
- let appl = Applicability :: HasPlaceholders ;
241
217
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
+ } ) ;
244
225
} 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
+ } )
246
231
}
247
232
}
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
+ } ) ;
249
241
}
250
242
251
243
fn missing_items_must_implement_one_of_err (
@@ -257,19 +249,11 @@ fn missing_items_must_implement_one_of_err(
257
249
let missing_items_msg =
258
250
missing_items. iter ( ) . map ( Ident :: to_string) . collect :: < Vec < _ > > ( ) . join ( "`, `" ) ;
259
251
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
+ } ) ;
273
257
}
274
258
275
259
fn default_body_is_unstable (
@@ -281,25 +265,31 @@ fn default_body_is_unstable(
281
265
issue : Option < NonZeroU32 > ,
282
266
) {
283
267
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 ,
287
275
} ;
288
276
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
+
297
286
rustc_session:: parse:: add_feature_diagnostics_for_issue (
298
287
& mut err,
299
288
& tcx. sess . parse_sess ,
300
289
feature,
301
290
rustc_feature:: GateIssue :: Library ( issue) ,
302
291
) ;
292
+
303
293
err. emit ( ) ;
304
294
}
305
295
@@ -488,16 +478,18 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d
488
478
. iter ( )
489
479
. map ( |variant| tcx. hir ( ) . span_if_local ( variant. def_id ) . unwrap ( ) )
490
480
. 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 ) ;
494
482
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) ;
499
485
}
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
+ } ) ;
501
493
}
502
494
503
495
/// 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>(
509
501
field_spans : impl Iterator < Item = Span > ,
510
502
sp : Span ,
511
503
) {
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
+ } ) ;
525
518
}
526
- err. emit ( ) ;
527
519
}
528
520
529
521
// FIXME: Consider moving this method to a more fitting place.
0 commit comments