@@ -26,7 +26,7 @@ use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
2626use rustc_middle:: ty:: { GenericArgs , GenericArgsRef } ;
2727use rustc_session:: lint:: builtin:: COHERENCE_LEAK_CHECK ;
2828use rustc_session:: lint:: builtin:: ORDER_DEPENDENT_TRAIT_OBJECTS ;
29- use rustc_span:: { Span , DUMMY_SP } ;
29+ use rustc_span:: { ErrorGuaranteed , Span , DUMMY_SP } ;
3030
3131use super :: util;
3232use super :: SelectionContext ;
@@ -258,7 +258,7 @@ fn fulfill_implication<'tcx>(
258258pub ( super ) fn specialization_graph_provider (
259259 tcx : TyCtxt < ' _ > ,
260260 trait_id : DefId ,
261- ) -> specialization_graph:: Graph {
261+ ) -> Result < & ' _ specialization_graph:: Graph , ErrorGuaranteed > {
262262 let mut sg = specialization_graph:: Graph :: new ( ) ;
263263 let overlap_mode = specialization_graph:: OverlapMode :: get ( tcx, trait_id) ;
264264
@@ -271,6 +271,8 @@ pub(super) fn specialization_graph_provider(
271271 trait_impls
272272 . sort_unstable_by_key ( |def_id| ( -( def_id. krate . as_u32 ( ) as i64 ) , def_id. index . index ( ) ) ) ;
273273
274+ let mut errored = Ok ( ( ) ) ;
275+
274276 for impl_def_id in trait_impls {
275277 if let Some ( impl_def_id) = impl_def_id. as_local ( ) {
276278 // This is where impl overlap checking happens:
@@ -283,15 +285,21 @@ pub(super) fn specialization_graph_provider(
283285 } ;
284286
285287 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+ ) ) ;
287294 }
288295 } else {
289296 let parent = tcx. impl_parent ( impl_def_id) . unwrap_or ( trait_id) ;
290297 sg. record_impl_from_cstore ( tcx, parent, impl_def_id)
291298 }
292299 }
300+ errored?;
293301
294- sg
302+ Ok ( tcx . arena . alloc ( sg ) )
295303}
296304
297305// This function is only used when
@@ -304,36 +312,31 @@ fn report_overlap_conflict<'tcx>(
304312 overlap : OverlapError < ' tcx > ,
305313 impl_def_id : LocalDefId ,
306314 used_to_be_allowed : Option < FutureCompatOverlapErrorKind > ,
307- sg : & mut specialization_graph:: Graph ,
308- ) {
315+ ) -> Result < ( ) , ErrorGuaranteed > {
309316 let impl_polarity = tcx. impl_polarity ( impl_def_id. to_def_id ( ) ) ;
310317 let other_polarity = tcx. impl_polarity ( overlap. with_impl ) ;
311318 match ( impl_polarity, other_polarity) {
312319 ( ty:: ImplPolarity :: Negative , ty:: ImplPolarity :: Positive ) => {
313- report_negative_positive_conflict (
320+ Err ( report_negative_positive_conflict (
314321 tcx,
315322 & overlap,
316323 impl_def_id,
317324 impl_def_id. to_def_id ( ) ,
318325 overlap. with_impl ,
319- sg,
320- ) ;
326+ ) )
321327 }
322328
323329 ( ty:: ImplPolarity :: Positive , ty:: ImplPolarity :: Negative ) => {
324- report_negative_positive_conflict (
330+ Err ( report_negative_positive_conflict (
325331 tcx,
326332 & overlap,
327333 impl_def_id,
328334 overlap. with_impl ,
329335 impl_def_id. to_def_id ( ) ,
330- sg,
331- ) ;
336+ ) )
332337 }
333338
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) ,
337340 }
338341}
339342
@@ -343,25 +346,24 @@ fn report_negative_positive_conflict<'tcx>(
343346 local_impl_def_id : LocalDefId ,
344347 negative_impl_def_id : DefId ,
345348 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 ( )
356359}
357360
358361fn report_conflicting_impls < ' tcx > (
359362 tcx : TyCtxt < ' tcx > ,
360363 overlap : OverlapError < ' tcx > ,
361364 impl_def_id : LocalDefId ,
362365 used_to_be_allowed : Option < FutureCompatOverlapErrorKind > ,
363- sg : & mut specialization_graph:: Graph ,
364- ) {
366+ ) -> Result < ( ) , ErrorGuaranteed > {
365367 let impl_span = tcx. def_span ( impl_def_id) ;
366368
367369 // Work to be done after we've built the DiagnosticBuilder. We have to define it
@@ -429,14 +431,11 @@ fn report_conflicting_impls<'tcx>(
429431 let mut err = tcx. dcx ( ) . struct_span_err ( impl_span, msg) ;
430432 err. code ( error_code ! ( E0119 ) ) ;
431433 decorate ( tcx, & overlap, impl_span, & mut err) ;
432- Some ( err. emit ( ) )
434+ err. emit ( )
433435 } 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" )
438437 } ;
439- sg . has_errored = reported;
438+ Err ( reported)
440439 }
441440 Some ( kind) => {
442441 let lint = match kind {
@@ -452,8 +451,9 @@ fn report_conflicting_impls<'tcx>(
452451 decorate ( tcx, & overlap, impl_span, err) ;
453452 } ,
454453 ) ;
454+ Ok ( ( ) )
455455 }
456- } ;
456+ }
457457}
458458
459459/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
0 commit comments