1+ mod ambiguity;
12pub mod on_unimplemented;
23pub mod suggestions;
34
@@ -535,15 +536,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
535536 let mut span = obligation. cause . span ;
536537
537538 let mut err = match * error {
538- SelectionError :: Ambiguous ( ref impls) => {
539- let mut err = self . tcx . sess . struct_span_err (
540- obligation. cause . span ,
541- & format ! ( "multiple applicable `impl`s for `{}`" , obligation. predicate) ,
542- ) ;
543- self . annotate_source_of_ambiguity ( & mut err, impls, obligation. predicate ) ;
544- err. emit ( ) ;
545- return ;
546- }
547539 SelectionError :: Unimplemented => {
548540 // If this obligation was generated as a result of well-formedness checking, see if we
549541 // can get a better error message by performing HIR-based well-formedness checking.
@@ -2144,8 +2136,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
21442136 crate :: traits:: TraitQueryMode :: Standard ,
21452137 ) ;
21462138 match selcx. select_from_obligation ( & obligation) {
2147- Err ( SelectionError :: Ambiguous ( impls) ) if impls. len ( ) > 1 => {
2148- self . annotate_source_of_ambiguity ( & mut err, & impls, predicate) ;
2139+ Ok ( None ) => {
2140+ let impls = ambiguity:: recompute_applicable_impls ( self . infcx , & obligation) ;
2141+ let has_non_region_infer =
2142+ trait_ref. skip_binder ( ) . substs . types ( ) . any ( |t| !t. is_ty_infer ( ) ) ;
2143+ // It doesn't make sense to talk about applicable impls if there are more
2144+ // than a handful of them.
2145+ if impls. len ( ) > 1 && impls. len ( ) < 5 && has_non_region_infer {
2146+ self . annotate_source_of_ambiguity ( & mut err, & impls, predicate) ;
2147+ } else {
2148+ if self . is_tainted_by_errors ( ) {
2149+ err. cancel ( ) ;
2150+ return ;
2151+ }
2152+ err. note ( & format ! ( "cannot satisfy `{}`" , predicate) ) ;
2153+ }
21492154 }
21502155 _ => {
21512156 if self . is_tainted_by_errors ( ) {
@@ -2441,7 +2446,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24412446 }
24422447 }
24432448 }
2444- let msg = format ! ( "multiple `impl`s satisfying `{}` found" , predicate) ;
24452449 let mut crate_names: Vec < _ > = crates. iter ( ) . map ( |n| format ! ( "`{}`" , n) ) . collect ( ) ;
24462450 crate_names. sort ( ) ;
24472451 crate_names. dedup ( ) ;
@@ -2462,13 +2466,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24622466 err. downgrade_to_delayed_bug ( ) ;
24632467 return ;
24642468 }
2465- let post = if post. len ( ) > 4 {
2466- format ! (
2467- ":\n {}\n and {} more" ,
2468- post. iter( ) . map( |p| format!( "- {}" , p) ) . take( 4 ) . collect:: <Vec <_>>( ) . join( "\n " ) ,
2469- post. len( ) - 4 ,
2470- )
2471- } else if post. len ( ) > 1 || ( post. len ( ) == 1 && post[ 0 ] . contains ( '\n' ) ) {
2469+
2470+ let msg = format ! ( "multiple `impl`s satisfying `{}` found" , predicate) ;
2471+ let post = if post. len ( ) > 1 || ( post. len ( ) == 1 && post[ 0 ] . contains ( '\n' ) ) {
24722472 format ! ( ":\n {}" , post. iter( ) . map( |p| format!( "- {}" , p) ) . collect:: <Vec <_>>( ) . join( "\n " ) , )
24732473 } else if post. len ( ) == 1 {
24742474 format ! ( ": `{}`" , post[ 0 ] )
0 commit comments