@@ -17,6 +17,7 @@ use crate::solve::{GenerateProofTree, InferCtxtEvalExt, UseGlobalCache};
17
17
use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
18
18
use crate :: traits:: specialize:: to_pretty_impl_header;
19
19
use crate :: traits:: NormalizeExt ;
20
+ use ambiguity:: Ambiguity :: * ;
20
21
use on_unimplemented:: { AppendConstMessage , OnUnimplementedNote , TypeErrCtxtExt as _} ;
21
22
use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap } ;
22
23
use rustc_errors:: {
@@ -2366,14 +2367,28 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2366
2367
)
2367
2368
} ;
2368
2369
2369
- let ambiguities = ambiguity:: recompute_applicable_impls (
2370
+ let mut ambiguities = ambiguity:: recompute_applicable_impls (
2370
2371
self . infcx ,
2371
2372
& obligation. with ( self . tcx , trait_ref) ,
2372
2373
) ;
2373
2374
let has_non_region_infer =
2374
2375
trait_ref. skip_binder ( ) . args . types ( ) . any ( |t| !t. is_ty_or_numeric_infer ( ) ) ;
2375
- // It doesn't make sense to talk about applicable impls if there are more
2376
- // than a handful of them.
2376
+ // It doesn't make sense to talk about applicable impls if there are more than a
2377
+ // handful of them. If there are a lot of them, but only a few of them have no type
2378
+ // params, we only show those, as they are more likely to be useful/intended.
2379
+ if ambiguities. len ( ) > 20 {
2380
+ let infcx = self . infcx ;
2381
+ if !ambiguities. iter ( ) . all ( |option| match option {
2382
+ DefId ( did) => infcx. fresh_args_for_item ( DUMMY_SP , * did) . is_empty ( ) ,
2383
+ ParamEnv ( _) => true ,
2384
+ } ) {
2385
+ // If not all are blanket impls, we filter blanked impls out.
2386
+ ambiguities. retain ( |option| match option {
2387
+ DefId ( did) => infcx. fresh_args_for_item ( DUMMY_SP , * did) . is_empty ( ) ,
2388
+ ParamEnv ( _) => true ,
2389
+ } ) ;
2390
+ }
2391
+ }
2377
2392
if ambiguities. len ( ) > 1 && ambiguities. len ( ) < 10 && has_non_region_infer {
2378
2393
if self . tainted_by_errors ( ) . is_some ( ) && subst. is_none ( ) {
2379
2394
// If `subst.is_none()`, then this is probably two param-env
@@ -2392,7 +2407,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2392
2407
err. note ( format ! ( "cannot satisfy `{predicate}`" ) ) ;
2393
2408
let impl_candidates = self
2394
2409
. find_similar_impl_candidates ( predicate. to_opt_poly_trait_pred ( ) . unwrap ( ) ) ;
2395
- if impl_candidates. len ( ) < 10 {
2410
+ if impl_candidates. len ( ) < 40 {
2396
2411
self . report_similar_impl_candidates (
2397
2412
impl_candidates. as_slice ( ) ,
2398
2413
trait_ref,
0 commit comments