Repository: rust-lang/rust
File: compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs (Rust)

Code before:
            }
            _ => (), // FIXME(#22750) handle traits and stuff
        }
        false
    }

    fn suggest_param_env_shadowing(
        &self,
        diag: &mut Diag<'_>,
        expected: Ty<'tcx>,
        found: Ty<'tcx>,
    ) {
        let (alias, concrete) = match (expected.kind(), found.kind()) {
            (ty::Alias(ty::Projection, proj), _) => (proj, found),
            (_, ty::Alias(ty::Projection, proj)) => (proj, expected),
            _ => return,
        };

        let tcx = self.tcx;
        let trait_def_id = alias.trait_def_id(tcx);
        let impls = tcx.trait_impls_of(trait_def_id);

        let all_impls =
            impls.blanket_impls().iter().chain(impls.non_blanket_impls().values().flatten());

        for &impl_def_id in all_impls {
            let is_shadowed = self.infcx.probe(|_| {
                let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);

                let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs);

                let expected_trait_ref = alias.trait_ref(tcx);

                if self.infcx.can_eq(ty::ParamEnv::empty(), expected_trait_ref, impl_trait_ref) {
                    let name = tcx.item_name(alias.def_id);
                    let assoc_item = tcx
                        .associated_items(impl_def_id)
                        .filter_by_name_unhygienic(name)
                        .find(|item| matches!(item.kind, ty::AssocKind::Type { .. }));

                    if let Some(item) = assoc_item {
                        let impl_assoc_ty = tcx.type_of(item.def_id).instantiate(tcx, impl_substs);
                        if self.infcx.can_eq(ty::ParamEnv::empty(), impl_assoc_ty, concrete) {
                            return true;
                        }
                    }
                }
                false
            });

            if is_shadowed {

Review comment (suggestion):
use `compute_applicable_impls_for_diagnostics` instead of `all_impls` here

Code after:
                    err,
                    exp_found.expected,
                    [exp_found.found].into_iter(),
                    |did| vec![self.tcx.def_span(did)],
                    "trait",
                );
            }
            _ => (), // FIXME(#22750) handle traits and stuff
        }
        false
    }

    fn suggest_param_env_shadowing(
        &self,
        diag: &mut Diag<'_>,
        expected: Ty<'tcx>,
        found: Ty<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
    ) {
        let (alias, concrete) = match (expected.kind(), found.kind()) {
            (ty::Alias(ty::Projection, proj), _) => (proj, found),
            (_, ty::Alias(ty::Projection, proj)) => (proj, expected),
            _ => return,
        };

        let tcx = self.tcx;

        let trait_ref = alias.trait_ref(tcx);
        let obligation =
            Obligation::new(tcx, ObligationCause::dummy(), param_env, ty::Binder::dummy(trait_ref));

        let applicable_impls = compute_applicable_impls_for_diagnostics(self.infcx, &obligation);

        for candidate in applicable_impls {
            let impl_def_id = match candidate {
                CandidateSource::DefId(did) => did,
                CandidateSource::ParamEnv(_) => continue,
            };

            let is_shadowed = self.infcx.probe(|_| {
                let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
                let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs);

                let expected_trait_ref = alias.trait_ref(tcx);

                if let Err(_) = self.infcx.at(&ObligationCause::dummy(), param_env).eq(
                    DefineOpaqueTypes::No,
                    expected_trait_ref,
                    impl_trait_ref,
                ) {
                    return false;