@@ -26,7 +26,7 @@ use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
26
26
use rustc_middle:: ty:: { GenericArgs , GenericArgsRef } ;
27
27
use rustc_session:: lint:: builtin:: COHERENCE_LEAK_CHECK ;
28
28
use rustc_session:: lint:: builtin:: ORDER_DEPENDENT_TRAIT_OBJECTS ;
29
- use rustc_span:: { Span , DUMMY_SP } ;
29
+ use rustc_span:: { ErrorGuaranteed , Span , DUMMY_SP } ;
30
30
31
31
use super :: util;
32
32
use super :: SelectionContext ;
@@ -258,7 +258,7 @@ fn fulfill_implication<'tcx>(
258
258
pub ( super ) fn specialization_graph_provider (
259
259
tcx : TyCtxt < ' _ > ,
260
260
trait_id : DefId ,
261
- ) -> specialization_graph:: Graph {
261
+ ) -> Result < & ' _ specialization_graph:: Graph , ErrorGuaranteed > {
262
262
let mut sg = specialization_graph:: Graph :: new ( ) ;
263
263
let overlap_mode = specialization_graph:: OverlapMode :: get ( tcx, trait_id) ;
264
264
@@ -271,6 +271,8 @@ pub(super) fn specialization_graph_provider(
271
271
trait_impls
272
272
. sort_unstable_by_key ( |def_id| ( -( def_id. krate . as_u32 ( ) as i64 ) , def_id. index . index ( ) ) ) ;
273
273
274
+ let mut errored = Ok ( ( ) ) ;
275
+
274
276
for impl_def_id in trait_impls {
275
277
if let Some ( impl_def_id) = impl_def_id. as_local ( ) {
276
278
// This is where impl overlap checking happens:
@@ -283,15 +285,21 @@ pub(super) fn specialization_graph_provider(
283
285
} ;
284
286
285
287
if let Some ( overlap) = overlap {
286
- report_overlap_conflict ( tcx, overlap, impl_def_id, used_to_be_allowed, & mut sg) ;
288
+ errored = errored. and ( report_overlap_conflict (
289
+ tcx,
290
+ overlap,
291
+ impl_def_id,
292
+ used_to_be_allowed,
293
+ ) ) ;
287
294
}
288
295
} else {
289
296
let parent = tcx. impl_parent ( impl_def_id) . unwrap_or ( trait_id) ;
290
297
sg. record_impl_from_cstore ( tcx, parent, impl_def_id)
291
298
}
292
299
}
300
+ errored?;
293
301
294
- sg
302
+ Ok ( tcx . arena . alloc ( sg ) )
295
303
}
296
304
297
305
// This function is only used when
@@ -304,36 +312,31 @@ fn report_overlap_conflict<'tcx>(
304
312
overlap : OverlapError < ' tcx > ,
305
313
impl_def_id : LocalDefId ,
306
314
used_to_be_allowed : Option < FutureCompatOverlapErrorKind > ,
307
- sg : & mut specialization_graph:: Graph ,
308
- ) {
315
+ ) -> Result < ( ) , ErrorGuaranteed > {
309
316
let impl_polarity = tcx. impl_polarity ( impl_def_id. to_def_id ( ) ) ;
310
317
let other_polarity = tcx. impl_polarity ( overlap. with_impl ) ;
311
318
match ( impl_polarity, other_polarity) {
312
319
( ty:: ImplPolarity :: Negative , ty:: ImplPolarity :: Positive ) => {
313
- report_negative_positive_conflict (
320
+ Err ( report_negative_positive_conflict (
314
321
tcx,
315
322
& overlap,
316
323
impl_def_id,
317
324
impl_def_id. to_def_id ( ) ,
318
325
overlap. with_impl ,
319
- sg,
320
- ) ;
326
+ ) )
321
327
}
322
328
323
329
( ty:: ImplPolarity :: Positive , ty:: ImplPolarity :: Negative ) => {
324
- report_negative_positive_conflict (
330
+ Err ( report_negative_positive_conflict (
325
331
tcx,
326
332
& overlap,
327
333
impl_def_id,
328
334
overlap. with_impl ,
329
335
impl_def_id. to_def_id ( ) ,
330
- sg,
331
- ) ;
336
+ ) )
332
337
}
333
338
334
- _ => {
335
- report_conflicting_impls ( tcx, overlap, impl_def_id, used_to_be_allowed, sg) ;
336
- }
339
+ _ => report_conflicting_impls ( tcx, overlap, impl_def_id, used_to_be_allowed) ,
337
340
}
338
341
}
339
342
@@ -343,25 +346,24 @@ fn report_negative_positive_conflict<'tcx>(
343
346
local_impl_def_id : LocalDefId ,
344
347
negative_impl_def_id : DefId ,
345
348
positive_impl_def_id : DefId ,
346
- sg : & mut specialization_graph :: Graph ,
347
- ) {
348
- let err = tcx . dcx ( ) . create_err ( NegativePositiveConflict {
349
- impl_span : tcx. def_span ( local_impl_def_id) ,
350
- trait_desc : overlap. trait_ref ,
351
- self_ty : overlap. self_ty ,
352
- negative_impl_span : tcx. span_of_impl ( negative_impl_def_id) ,
353
- positive_impl_span : tcx. span_of_impl ( positive_impl_def_id) ,
354
- } ) ;
355
- sg . has_errored = Some ( err . emit ( ) ) ;
349
+ ) -> ErrorGuaranteed {
350
+ tcx . dcx ( )
351
+ . create_err ( NegativePositiveConflict {
352
+ impl_span : tcx. def_span ( local_impl_def_id) ,
353
+ trait_desc : overlap. trait_ref ,
354
+ self_ty : overlap. self_ty ,
355
+ negative_impl_span : tcx. span_of_impl ( negative_impl_def_id) ,
356
+ positive_impl_span : tcx. span_of_impl ( positive_impl_def_id) ,
357
+ } )
358
+ . emit ( )
356
359
}
357
360
358
361
fn report_conflicting_impls < ' tcx > (
359
362
tcx : TyCtxt < ' tcx > ,
360
363
overlap : OverlapError < ' tcx > ,
361
364
impl_def_id : LocalDefId ,
362
365
used_to_be_allowed : Option < FutureCompatOverlapErrorKind > ,
363
- sg : & mut specialization_graph:: Graph ,
364
- ) {
366
+ ) -> Result < ( ) , ErrorGuaranteed > {
365
367
let impl_span = tcx. def_span ( impl_def_id) ;
366
368
367
369
// Work to be done after we've built the DiagnosticBuilder. We have to define it
@@ -429,14 +431,11 @@ fn report_conflicting_impls<'tcx>(
429
431
let mut err = tcx. dcx ( ) . struct_span_err ( impl_span, msg) ;
430
432
err. code ( error_code ! ( E0119 ) ) ;
431
433
decorate ( tcx, & overlap, impl_span, & mut err) ;
432
- Some ( err. emit ( ) )
434
+ err. emit ( )
433
435
} else {
434
- Some (
435
- tcx. dcx ( )
436
- . span_delayed_bug ( impl_span, "impl should have failed the orphan check" ) ,
437
- )
436
+ tcx. dcx ( ) . span_delayed_bug ( impl_span, "impl should have failed the orphan check" )
438
437
} ;
439
- sg . has_errored = reported;
438
+ Err ( reported)
440
439
}
441
440
Some ( kind) => {
442
441
let lint = match kind {
@@ -452,8 +451,9 @@ fn report_conflicting_impls<'tcx>(
452
451
decorate ( tcx, & overlap, impl_span, err) ;
453
452
} ,
454
453
) ;
454
+ Ok ( ( ) )
455
455
}
456
- } ;
456
+ }
457
457
}
458
458
459
459
/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
0 commit comments