1
+ mod ambiguity;
1
2
pub mod on_unimplemented;
2
3
pub mod suggestions;
3
4
@@ -535,15 +536,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
535
536
let mut span = obligation. cause . span ;
536
537
537
538
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
- }
547
539
SelectionError :: Unimplemented => {
548
540
// If this obligation was generated as a result of well-formedness checking, see if we
549
541
// can get a better error message by performing HIR-based well-formedness checking.
@@ -2144,12 +2136,25 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2144
2136
crate :: traits:: TraitQueryMode :: Standard ,
2145
2137
) ;
2146
2138
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. delay_as_bug ( ) ;
2150
+ return ;
2151
+ }
2152
+ err. note ( & format ! ( "cannot satisfy `{}`" , predicate) ) ;
2153
+ }
2149
2154
}
2150
2155
_ => {
2151
2156
if self . is_tainted_by_errors ( ) {
2152
- err. cancel ( ) ;
2157
+ err. delay_as_bug ( ) ;
2153
2158
return ;
2154
2159
}
2155
2160
err. note ( & format ! ( "cannot satisfy `{}`" , predicate) ) ;
@@ -2441,7 +2446,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2441
2446
}
2442
2447
}
2443
2448
}
2444
- let msg = format ! ( "multiple `impl`s satisfying `{}` found" , predicate) ;
2445
2449
let mut crate_names: Vec < _ > = crates. iter ( ) . map ( |n| format ! ( "`{}`" , n) ) . collect ( ) ;
2446
2450
crate_names. sort ( ) ;
2447
2451
crate_names. dedup ( ) ;
@@ -2462,13 +2466,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2462
2466
err. downgrade_to_delayed_bug ( ) ;
2463
2467
return ;
2464
2468
}
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' ) ) {
2472
2472
format ! ( ":\n {}" , post. iter( ) . map( |p| format!( "- {}" , p) ) . collect:: <Vec <_>>( ) . join( "\n " ) , )
2473
2473
} else if post. len ( ) == 1 {
2474
2474
format ! ( ": `{}`" , post[ 0 ] )
0 commit comments