@@ -23,7 +23,7 @@ use rustc_hir::GenericParam;
2323use  rustc_hir:: Item ; 
2424use  rustc_hir:: Node ; 
2525use  rustc_infer:: infer:: error_reporting:: same_type_modulo_infer; 
26- use  rustc_infer:: traits:: TraitEngine ; 
26+ use  rustc_infer:: traits:: { AmbiguousSelection ,   TraitEngine } ; 
2727use  rustc_middle:: thir:: abstract_const:: NotConstEvaluatable ; 
2828use  rustc_middle:: traits:: select:: OverflowError ; 
2929use  rustc_middle:: ty:: error:: ExpectedFound ; 
@@ -1404,7 +1404,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
14041404    fn  annotate_source_of_ambiguity ( 
14051405        & self , 
14061406        err :  & mut  Diagnostic , 
1407-         impls :  & [ DefId ] , 
1407+         impls :  & [ AmbiguousSelection ] , 
14081408        predicate :  ty:: Predicate < ' tcx > , 
14091409    ) ; 
14101410
@@ -2020,6 +2020,14 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
20202020                ) ; 
20212021                match  selcx. select_from_obligation ( & obligation)  { 
20222022                    Err ( SelectionError :: Ambiguous ( impls) )  if  impls. len ( )  > 1  => { 
2023+                         if  self . is_tainted_by_errors ( )  && subst. is_none ( )  { 
2024+                             // If `subst.is_none()`, then this is probably two param-env 
2025+                             // candidates or impl candidates that are equal modulo lifetimes. 
2026+                             // Therefore, if we've already emitted an error, just skip this 
2027+                             // one, since it's not particularly actionable. 
2028+                             err. cancel ( ) ; 
2029+                             return ; 
2030+                         } 
20232031                        self . annotate_source_of_ambiguity ( & mut  err,  & impls,  predicate) ; 
20242032                    } 
20252033                    _ => { 
@@ -2170,24 +2178,35 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
21702178    fn  annotate_source_of_ambiguity ( 
21712179        & self , 
21722180        err :  & mut  Diagnostic , 
2173-         impls :  & [ DefId ] , 
2181+         impls :  & [ AmbiguousSelection ] , 
21742182        predicate :  ty:: Predicate < ' tcx > , 
21752183    )  { 
21762184        let  mut  spans = vec ! [ ] ; 
21772185        let  mut  crates = vec ! [ ] ; 
21782186        let  mut  post = vec ! [ ] ; 
2179-         for  def_id in  impls { 
2180-             match  self . tcx . span_of_impl ( * def_id)  { 
2181-                 Ok ( span)  => spans. push ( span) , 
2182-                 Err ( name)  => { 
2183-                     crates. push ( name) ; 
2184-                     if  let  Some ( header)  = to_pretty_impl_header ( self . tcx ,  * def_id)  { 
2185-                         post. push ( header) ; 
2187+         let  mut  or_where_clause = false ; 
2188+         for  ambig in  impls { 
2189+             match  ambig { 
2190+                 AmbiguousSelection :: Impl ( def_id)  => match  self . tcx . span_of_impl ( * def_id)  { 
2191+                     Ok ( span)  => spans. push ( span) , 
2192+                     Err ( name)  => { 
2193+                         crates. push ( name) ; 
2194+                         if  let  Some ( header)  = to_pretty_impl_header ( self . tcx ,  * def_id)  { 
2195+                             post. push ( header) ; 
2196+                         } 
21862197                    } 
2198+                 } , 
2199+                 AmbiguousSelection :: ParamEnv ( span)  => { 
2200+                     or_where_clause = true ; 
2201+                     spans. push ( * span) ; 
21872202                } 
21882203            } 
21892204        } 
2190-         let  msg = format ! ( "multiple `impl`s satisfying `{}` found" ,  predicate) ; 
2205+         let  msg = format ! ( 
2206+             "multiple `impl`s{} satisfying `{}` found" , 
2207+             if  or_where_clause {  " or `where` clauses"  }  else {  ""  } , 
2208+             predicate
2209+         ) ; 
21912210        let  mut  crate_names:  Vec < _ >  = crates. iter ( ) . map ( |n| format ! ( "`{}`" ,  n) ) . collect ( ) ; 
21922211        crate_names. sort ( ) ; 
21932212        crate_names. dedup ( ) ; 
0 commit comments