@@ -42,6 +42,7 @@ pub struct OverlapError {
42
42
pub trait_desc : String ,
43
43
pub self_desc : Option < String > ,
44
44
pub intercrate_ambiguity_causes : Vec < IntercrateAmbiguityCause > ,
45
+ pub used_to_be_allowed : bool ,
45
46
}
46
47
47
48
/// Given a subst for the requested impl, translate it to a subst
@@ -324,29 +325,48 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
324
325
def_id. index . as_array_index ( ) )
325
326
} ) ;
326
327
328
+ let mut overlaps = Vec :: new ( ) ;
329
+
327
330
for impl_def_id in trait_impls {
328
331
if impl_def_id. is_local ( ) {
329
- // This is where impl overlap checking happens:
330
332
let insert_result = sg. insert ( tcx, impl_def_id) ;
331
- // Report error if there was one.
332
- let ( overlap, used_to_be_allowed) = match insert_result {
333
- Err ( overlap) => ( Some ( overlap) , false ) ,
334
- Ok ( opt_overlap) => ( opt_overlap, true )
333
+ match insert_result {
334
+ Ok ( Some ( mut opt_overlaps) ) => {
335
+ // record any overlap that occurs between two impl
336
+ // later those recordings are processed to establish
337
+ // if an intersection impl is present between two overlapping impls
338
+ // if no an overlap error is emitted
339
+ for opt_overlap in opt_overlaps {
340
+ overlaps. push ( ( impl_def_id, opt_overlap) ) ;
341
+ }
342
+ } ,
343
+ _ => { } ,
335
344
} ;
336
345
337
- if let Some ( overlap) = overlap {
346
+ } else {
347
+ let parent = tcx. impl_parent ( impl_def_id) . unwrap_or ( trait_id) ;
348
+ sg. record_impl_from_cstore ( tcx, parent, impl_def_id)
349
+ }
350
+ }
351
+
352
+ if overlaps. len ( ) > 0 {
353
+ // Build the graph only if there is at least an overlap
354
+ let ( graph, nodes_idx) = sg. build_graph ( ) ;
355
+ for ( impl_def_id, overlap) in overlaps {
356
+ if !sg. check_overlap ( & graph, & nodes_idx, impl_def_id, overlap. with_impl ) {
357
+
338
358
let msg = format ! ( "conflicting implementations of trait `{}`{}:{}" ,
339
359
overlap. trait_desc,
340
360
overlap. self_desc. clone( ) . map_or(
341
361
String :: new( ) , |ty| {
342
362
format!( " for type `{}`" , ty)
343
363
} ) ,
344
- if used_to_be_allowed { " (E0119)" } else { "" }
364
+ if overlap . used_to_be_allowed { " (E0119)" } else { "" }
345
365
) ;
346
366
let impl_span = tcx. sess . codemap ( ) . def_span (
347
367
tcx. span_of_impl ( impl_def_id) . unwrap ( )
348
368
) ;
349
- let mut err = if used_to_be_allowed {
369
+ let mut err = if overlap . used_to_be_allowed {
350
370
tcx. struct_span_lint_node (
351
371
lint:: builtin:: INCOHERENT_FUNDAMENTAL_IMPLS ,
352
372
tcx. hir . as_local_node_id ( impl_def_id) . unwrap ( ) ,
@@ -386,9 +406,6 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
386
406
387
407
err. emit ( ) ;
388
408
}
389
- } else {
390
- let parent = tcx. impl_parent ( impl_def_id) . unwrap_or ( trait_id) ;
391
- sg. record_impl_from_cstore ( tcx, parent, impl_def_id)
392
409
}
393
410
}
394
411
0 commit comments