Skip to main content

rustc_trait_selection/error_reporting/traits/
ambiguity.rs

1use std::ops::ControlFlow;
2
3use rustc_attr_ir::lang_items::LangItem;
4use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_span_code_err};
5use rustc_hir as hir;
6use rustc_hir::def::{DefKind, Res};
7use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
8use rustc_hir::intravisit::Visitor as _;
9use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt};
10use rustc_infer::traits::util::elaborate;
11use rustc_infer::traits::{
12    Obligation, ObligationCause, ObligationCauseCode, PolyTraitObligation, PredicateObligation,
13};
14use rustc_middle::ty::print::PrintPolyTraitClauseExt;
15use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _, Unnormalized};
16use rustc_session::diagnostics::feature_err_unstable_feature_bound;
17use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
18use tracing::{debug, instrument};
19
20use crate::error_reporting::TypeErrCtxt;
21use crate::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
22use crate::error_reporting::traits::{FindExprBySpan, to_pretty_impl_header};
23use crate::traits::query::evaluate_obligation::InferCtxtExt;
24use crate::traits::{FulfillmentError, ObligationCtxt};
25
26#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CandidateSource {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::DefId(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "DefId",
                    &__self_0),
            Self::ParamEnv(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ParamEnv", &__self_0),
        }
    }
}Debug)]
27pub enum CandidateSource {
28    DefId(DefId),
29    ParamEnv(Span),
30}
31
32pub fn compute_applicable_impls_for_diagnostics<'tcx>(
33    infcx: &InferCtxt<'tcx>,
34    obligation: &PolyTraitObligation<'tcx>,
35    ignore_predicates_of_impls: bool,
36) -> Vec<CandidateSource> {
37    let tcx = infcx.tcx;
38    let param_env = obligation.param_env;
39
40    let predicate_polarity = obligation.predicate.skip_binder().polarity;
41
42    let impl_may_apply = |impl_def_id| {
43        let ocx = ObligationCtxt::new(infcx);
44        infcx.enter_forall(obligation.predicate, |placeholder_obligation| {
45            let obligation_trait_ref = ocx.normalize(
46                &ObligationCause::dummy(),
47                param_env,
48                Unnormalized::new_wip(placeholder_obligation.trait_ref),
49            );
50
51            let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
52            let impl_trait_ref =
53                tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip();
54            let impl_trait_ref = ocx.normalize(
55                &ObligationCause::dummy(),
56                param_env,
57                Unnormalized::new_wip(impl_trait_ref),
58            );
59
60            if let Err(_) =
61                ocx.eq(&ObligationCause::dummy(), param_env, obligation_trait_ref, impl_trait_ref)
62            {
63                return false;
64            }
65
66            let impl_trait_header = tcx.impl_trait_header(impl_def_id);
67            let impl_polarity = impl_trait_header.polarity;
68
69            match (impl_polarity, predicate_polarity) {
70                (ty::ImplPolarity::Positive, ty::ClausePolarity::Positive)
71                | (ty::ImplPolarity::Negative, ty::ClausePolarity::Negative) => {}
72                _ => return false,
73            }
74
75            if !ignore_predicates_of_impls {
76                let obligations = tcx
77                    .clauses_of(impl_def_id)
78                    .instantiate(tcx, impl_args)
79                    .into_iter()
80                    .map(|(clause, _)| {
81                        Obligation::new(
82                            tcx,
83                            ObligationCause::dummy(),
84                            param_env,
85                            clause.skip_norm_wip(),
86                        )
87                    })
88                    // Kinda hacky, but let's just throw away obligations that overflow.
89                    // This may reduce the accuracy of this check (if the obligation guides
90                    // inference or it actually resulted in error after others are processed)
91                    // ... but this is diagnostics code.
92                    .filter(|obligation| {
93                        infcx.next_trait_solver() || infcx.evaluate_obligation(obligation).is_ok()
94                    });
95                ocx.register_obligations(obligations);
96            }
97
98            ocx.try_evaluate_obligations().no_errors()
99        })
100    };
101
102    let param_env_candidate_may_apply = |poly_trait_predicate: ty::PolyTraitClause<'tcx>| {
103        let ocx = ObligationCtxt::new(infcx);
104        infcx.enter_forall(obligation.predicate, |placeholder_obligation| {
105            let obligation_trait_ref = ocx.normalize(
106                &ObligationCause::dummy(),
107                param_env,
108                Unnormalized::new_wip(placeholder_obligation.trait_ref),
109            );
110
111            let param_env_predicate = infcx.instantiate_binder_with_fresh_vars(
112                DUMMY_SP,
113                BoundRegionConversionTime::HigherRankedType,
114                poly_trait_predicate,
115            );
116            let param_env_trait_ref = ocx.normalize(
117                &ObligationCause::dummy(),
118                param_env,
119                Unnormalized::new_wip(param_env_predicate.trait_ref),
120            );
121
122            if let Err(_) = ocx.eq(
123                &ObligationCause::dummy(),
124                param_env,
125                obligation_trait_ref,
126                param_env_trait_ref,
127            ) {
128                return false;
129            }
130
131            ocx.try_evaluate_obligations().no_errors()
132        })
133    };
134
135    let mut ambiguities = Vec::new();
136
137    tcx.for_each_relevant_impl(
138        obligation.predicate.def_id(),
139        obligation.predicate.skip_binder().trait_ref.self_ty(),
140        |impl_def_id| {
141            if infcx.probe(|_| impl_may_apply(impl_def_id)) {
142                ambiguities.push(CandidateSource::DefId(impl_def_id))
143            }
144        },
145    );
146
147    // If our `body_def_id` has been set (and isn't just from a dummy obligation cause),
148    // then try to look for a param-env clause that would apply. The way we compute
149    // this is somewhat manual, since we need the spans, so we elaborate this directly
150    // from `clauses_of` rather than actually looking at the param-env which
151    // otherwise would be more appropriate.
152    let body_def_id = obligation.cause.body_def_id;
153    if body_def_id != CRATE_DEF_ID {
154        let clauses = tcx.clauses_of(body_def_id.to_def_id()).instantiate_identity(tcx);
155        for (clause, span) in
156            elaborate(tcx, clauses.into_iter().map(|(c, s)| (c.skip_norm_wip(), s)))
157        {
158            let kind = clause.kind();
159            if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder()
160                && param_env_candidate_may_apply(kind.rebind(trait_pred))
161            {
162                if kind.rebind(trait_pred.trait_ref)
163                    == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id()))
164                {
165                    ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id())))
166                } else {
167                    ambiguities.push(CandidateSource::ParamEnv(span))
168                }
169            }
170        }
171    }
172
173    ambiguities
174}
175
176impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
177    /// The term of an ambiguous obligation's predicate that gets blamed for the
178    /// missing type annotation: the first one still containing inference variables.
179    ///
180    /// Besides `maybe_report_ambiguity` pointing its diagnostics at this term,
181    /// `report_fulfillment_errors` merges the ambiguity errors whose blamed terms
182    /// share an inference variable into a single diagnostic.
183    pub(super) fn ambiguity_term(&self, predicate: ty::Predicate<'tcx>) -> Option<ty::Term<'tcx>> {
184        match predicate.kind().skip_binder() {
185            ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
186                data.trait_ref.args.terms().find(|term| term.has_non_region_infer())
187            }
188            ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => data
189                .projection_term
190                .args
191                .terms()
192                .chain([data.term])
193                .find(|term| term.has_non_region_infer()),
194            ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => Some(term),
195            ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(data)) => {
196                data.walk().filter_map(ty::GenericArg::as_term).find(|term| term.is_infer())
197            }
198            ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) => Some(ct.into()),
199            ty::PredicateKind::Subtype(data) => Some(data.a.into()),
200            ty::PredicateKind::NormalizesTo(data) if data.term.is_infer() => Some(data.term),
201            _ => None,
202        }
203    }
204
205    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("maybe_report_ambiguity",
                                    "rustc_trait_selection::error_reporting::traits::ambiguity",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs"),
                                    ::tracing_core::__macro_support::Option::Some(205u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::ambiguity"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("obligation")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("obligation");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("related")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("related");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&related)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: ErrorGuaranteed = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let predicate =
                self.deeply_resolve_ignoring_regions(obligation.predicate);
            let span = obligation.cause.span;
            let mut long_ty_path = None;
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs:220",
                                    "rustc_trait_selection::error_reporting::traits::ambiguity",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs"),
                                    ::tracing_core::__macro_support::Option::Some(220u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::ambiguity"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("predicate")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("predicate");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("obligation.cause.code")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("obligation.cause.code");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&predicate)
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation.cause.code())
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let bound_predicate = predicate.kind();
            let mut err =
                match bound_predicate.skip_binder() {
                    ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
                        let trait_pred = bound_predicate.rebind(data);
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs:229",
                                                "rustc_trait_selection::error_reporting::traits::ambiguity",
                                                ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs"),
                                                ::tracing_core::__macro_support::Option::Some(229u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::ambiguity"),
                                                ::tracing_core::field::FieldSet::new(&[{
                                                                    const NAME:
                                                                        ::tracing::__macro_support::FieldName<{
                                                                            ::tracing::__macro_support::FieldName::len("trait_pred")
                                                                        }> =
                                                                        ::tracing::__macro_support::FieldName::new("trait_pred");
                                                                    NAME.as_str()
                                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                ::tracing::metadata::Kind::EVENT)
                                        };
                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                };
                            let enabled =
                                ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                        ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::LevelFilter::current() &&
                                    {
                                        let interest = __CALLSITE.interest();
                                        !interest.is_never() &&
                                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                interest)
                                    };
                            if enabled {
                                (|value_set: ::tracing::field::ValueSet|
                                            {
                                                let meta = __CALLSITE.metadata();
                                                ::tracing::Event::dispatch(meta, &value_set);
                                                ;
                                            })({
                                        #[allow(unused_imports)]
                                        use ::tracing::field::{debug, display, Value};
                                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_pred)
                                                                    as &dyn ::tracing::field::Value))])
                                    });
                            } else { ; }
                        };
                        if let Err(e) = predicate.error_reported() { return e; }
                        if let Err(guar) =
                                self.tcx.ensure_result().coherent_trait(trait_pred.def_id())
                            {
                            return guar;
                        }
                        if #[allow(non_exhaustive_omitted_patterns)] match self.tcx.as_lang_item(trait_pred.def_id())
                                {
                                Some(LangItem::Sized | LangItem::MetaSized) => true,
                                _ => false,
                            } {
                            return match self.tainted_by_errors() {
                                    None =>
                                        self.emit_inference_failure_err(obligation.cause.body_def_id,
                                                span, trait_pred.self_ty().skip_binder().into(),
                                                TypeAnnotationNeeded::E0282, false).emit_err(),
                                    Some(e) => e,
                                };
                        }
                        let term = self.ambiguity_term(predicate);
                        let mut err =
                            if let Some(term) = term {
                                let candidates: Vec<_> =
                                    self.tcx.all_impls(trait_pred.def_id()).filter_map(|def_id|
                                                {
                                                    let imp = self.tcx.impl_trait_header(def_id);
                                                    if imp.polarity != ty::ImplPolarity::Positive ||
                                                            !self.tcx.is_user_visible_dep(def_id.krate) {
                                                        return None;
                                                    }
                                                    let imp = imp.trait_ref.skip_binder();
                                                    if imp.with_replaced_self_ty(self.tcx,
                                                                trait_pred.skip_binder().self_ty()) ==
                                                            trait_pred.skip_binder().trait_ref {
                                                        Some(imp.self_ty())
                                                    } else { None }
                                                }).collect();
                                self.emit_inference_failure_err_with_type_hint(obligation.cause.body_def_id,
                                    span, term, TypeAnnotationNeeded::E0283, true,
                                    match &candidates[..] {
                                        [candidate] => Some(*candidate),
                                        _ => None,
                                    })
                            } else {
                                {
                                        self.dcx().struct_span_err(span,
                                                ::alloc::__export::must_use({
                                                        ::alloc::fmt::format(format_args!("type annotations needed: cannot satisfy `{0}`",
                                                                self.tcx.short_string(predicate, &mut long_ty_path)))
                                                    })).with_code(E0283)
                                    }.with_long_ty_path(long_ty_path)
                            };
                        if let Some(ambiguities) =
                                self.applicable_impls_to_mention(obligation, trait_pred) {
                            if let Some(e) = self.tainted_by_errors() && term.is_none()
                                {
                                err.cancel();
                                return e;
                            }
                            self.annotate_source_of_ambiguity(&mut err, &ambiguities,
                                predicate);
                        } else {
                            if let Some(e) = self.tainted_by_errors() {
                                err.cancel();
                                return e;
                            }
                            if let Some(clause) = predicate.as_trait_clause() &&
                                    let ty::Infer(_) = clause.self_ty().skip_binder().kind() {
                                let tr =
                                    self.tcx.short_string(clause.print_modifiers_and_trait_path(),
                                        &mut err.long_ty_path());
                                err.note(::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("the type must implement `{0}`",
                                                    tr))
                                        }));
                            } else {
                                let pred =
                                    self.tcx.short_string(predicate, &mut err.long_ty_path());
                                err.note(::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("cannot satisfy `{0}`",
                                                    pred))
                                        }));
                            }
                            let clause = predicate.as_trait_clause().unwrap();
                            let impl_candidates =
                                self.find_similar_impl_candidates(clause.def_id(),
                                    clause.self_ty().skip_binder());
                            if impl_candidates.len() < 40 {
                                self.report_similar_impl_candidates(impl_candidates.as_slice(),
                                    obligation, trait_pred, obligation.cause.body_def_id,
                                    &mut err, false, obligation.param_env);
                            }
                        }
                        if let ObligationCauseCode::WhereClause(def_id, _) |
                                ObligationCauseCode::WhereClauseInExpr(def_id, ..) =
                                *obligation.cause.code() {
                            self.suggest_fully_qualified_path(&mut err, def_id, span,
                                trait_pred.def_id());
                        }
                        if term.is_some_and(|term| term.as_type().is_some()) &&
                                let Some(body) =
                                    self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id)
                            {
                            let mut expr_finder = FindExprBySpan::new(span, self.tcx);
                            expr_finder.visit_expr(&body.value);
                            if let Some(hir::Expr {
                                                    kind: hir::ExprKind::Call(hir::Expr {
                                                        kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
                                                        .. }, _) |
                                                        hir::ExprKind::Path(hir::QPath::Resolved(None, path)), .. })
                                                    = expr_finder.result &&
                                                let [.., trait_path_segment @ hir::PathSegment {
                                                    res: Res::Def(DefKind::Trait, trait_id), .. },
                                                    hir::PathSegment {
                                                    ident: assoc_item_ident, res: Res::Def(_, item_id), .. }] =
                                                    path.segments && data.trait_ref.def_id == *trait_id &&
                                        self.tcx.trait_of_assoc(*item_id) == Some(*trait_id) &&
                                    let None = self.tainted_by_errors() {
                                let assoc_item = self.tcx.associated_item(*item_id);
                                let (verb, noun) =
                                    match assoc_item.kind {
                                        ty::AssocKind::Const { .. } => ("refer to the", "constant"),
                                        ty::AssocKind::Fn { .. } => ("call", "function"),
                                        ty::AssocKind::Type { .. } => ("refer to the", "type"),
                                    };
                                err.cancel();
                                err =
                                    self.dcx().struct_span_err(span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("cannot {0} associated {1} on trait without specifying the corresponding `impl` type",
                                                        verb, noun))
                                            }));
                                err.code(E0790);
                                if item_id.is_local() {
                                    let trait_ident = self.tcx.item_name(*trait_id);
                                    err.span_label(self.tcx.def_span(*item_id),
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("`{0}::{1}` defined here",
                                                        trait_ident, assoc_item_ident))
                                            }));
                                }
                                err.span_label(span,
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("cannot {0} associated {1} of trait",
                                                    verb, noun))
                                        }));
                                let trait_impls =
                                    self.tcx.trait_impls_of(data.trait_ref.def_id);
                                if let Some(&impl_def_id) =
                                        trait_impls.non_blanket_impls().values().flatten().next() {
                                    let non_blanket_impl_count =
                                        trait_impls.non_blanket_impls().values().flatten().count();
                                    let (message, self_types) =
                                        if non_blanket_impl_count == 1 {
                                            ("use the fully-qualified path to the only available \
                                     implementation",
                                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                                                        [::alloc::__export::must_use({
                                                                        ::alloc::fmt::format(format_args!("{0}",
                                                                                self.tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip()))
                                                                    })])))
                                        } else if non_blanket_impl_count < 20 {
                                            ("use a fully-qualified path to one of the available \
                                     implementations",
                                                trait_impls.non_blanket_impls().values().flatten().map(|&id|
                                                            {
                                                                ::alloc::__export::must_use({
                                                                        ::alloc::fmt::format(format_args!("{0}",
                                                                                self.tcx.type_of(id).instantiate_identity().skip_norm_wip()))
                                                                    })
                                                            }).collect::<Vec<String>>())
                                        } else {
                                            ("use a fully-qualified path to a specific available \
                                     implementation",
                                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                                                        ["/* self type */".to_string()])))
                                        };
                                    let suggestions: Vec<_> =
                                        self_types.into_iter().map(|self_type|
                                                    {
                                                        let mut suggestions =
                                                            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                                                                    [(path.span.shrink_to_lo(),
                                                                                ::alloc::__export::must_use({
                                                                                        ::alloc::fmt::format(format_args!("<{0} as ", self_type))
                                                                                    }))]));
                                                        if let Some(generic_arg) = trait_path_segment.args {
                                                            let between_span =
                                                                trait_path_segment.ident.span.between(generic_arg.span_ext);
                                                            suggestions.push((between_span, "".to_string()));
                                                            suggestions.push((generic_arg.span_ext.shrink_to_hi(),
                                                                    ">".to_string()));
                                                        } else {
                                                            suggestions.push((trait_path_segment.ident.span.shrink_to_hi(),
                                                                    ">".to_string()));
                                                        }
                                                        suggestions
                                                    }).collect();
                                    err.multipart_suggestions(message, suggestions,
                                        Applicability::MaybeIncorrect);
                                }
                            }
                        };
                        err
                    }
                    ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term))
                        => {
                        if let Err(e) = term.error_reported() { return e; }
                        if let Some(e) = self.tainted_by_errors() { return e; }
                        self.emit_inference_failure_err(obligation.cause.body_def_id,
                            span, term, TypeAnnotationNeeded::E0282, false)
                    }
                    ty::PredicateKind::Subtype(data) => {
                        if let Err(e) = data.error_reported() { return e; }
                        if let Some(e) = self.tainted_by_errors() { return e; }
                        let ty::SubtypePredicate { a_is_expected: _, a, b } = data;
                        if !(a.is_ty_var() && b.is_ty_var()) {
                            ::core::panicking::panic("assertion failed: a.is_ty_var() && b.is_ty_var()")
                        };
                        self.emit_inference_failure_err(obligation.cause.body_def_id,
                            span, a.into(), TypeAnnotationNeeded::E0282, true)
                    }
                    ty::PredicateKind::Clause(ty::ClauseKind::Projection(data))
                        => {
                        if let Err(e) = predicate.error_reported() { return e; }
                        if let Some(e) = self.tainted_by_errors() { return e; }
                        if data.projection_term.kind.is_trait_projection() &&
                                let Err(guar) =
                                    self.tcx.ensure_result().coherent_trait(self.tcx.parent(data.def_id()))
                            {
                            return guar;
                        }
                        let term = self.ambiguity_term(predicate);
                        let predicate =
                            self.tcx.short_string(predicate, &mut long_ty_path);
                        if let Some(term) = term {
                            self.emit_inference_failure_err(obligation.cause.body_def_id,
                                        span, term, TypeAnnotationNeeded::E0284,
                                        true).with_note(::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("cannot satisfy `{0}`",
                                                    predicate))
                                        })).with_long_ty_path(long_ty_path)
                        } else {
                            {
                                        self.dcx().struct_span_err(span,
                                                ::alloc::__export::must_use({
                                                        ::alloc::fmt::format(format_args!("type annotations needed: cannot satisfy `{0}`",
                                                                predicate))
                                                    })).with_code(E0284)
                                    }.with_span_label(span,
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("cannot satisfy `{0}`",
                                                    predicate))
                                        })).with_long_ty_path(long_ty_path)
                        }
                    }
                    ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_))
                        => {
                        if let Err(e) = predicate.error_reported() { return e; }
                        if let Some(e) = self.tainted_by_errors() { return e; }
                        if let Some(term) = self.ambiguity_term(predicate) {
                            self.emit_inference_failure_err(obligation.cause.body_def_id,
                                span, term, TypeAnnotationNeeded::E0284, true)
                        } else {
                            let predicate =
                                self.tcx.short_string(predicate, &mut long_ty_path);
                            {
                                        self.dcx().struct_span_err(span,
                                                ::alloc::__export::must_use({
                                                        ::alloc::fmt::format(format_args!("type annotations needed: cannot satisfy `{0}`",
                                                                predicate))
                                                    })).with_code(E0284)
                                    }.with_span_label(span,
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("cannot satisfy `{0}`",
                                                    predicate))
                                        })).with_long_ty_path(long_ty_path)
                        }
                    }
                    ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct,
                        ..)) =>
                        self.emit_inference_failure_err(obligation.cause.body_def_id,
                            span, ct.into(), TypeAnnotationNeeded::E0284, true),
                    ty::PredicateKind::NormalizesTo(ty::NormalizesTo {
                        alias, term }) if term.is_infer() => {
                        if let Some(e) = self.tainted_by_errors() { return e; }
                        let alias = self.tcx.short_string(alias, &mut long_ty_path);
                        {
                                    self.dcx().struct_span_err(span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("type annotations needed: cannot normalize `{0}`",
                                                            alias))
                                                })).with_code(E0284)
                                }.with_span_label(span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("cannot normalize `{0}`",
                                                alias))
                                    })).with_long_ty_path(long_ty_path)
                    }
                    ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(sym))
                        => {
                        if let Some(e) = self.tainted_by_errors() { return e; }
                        if self.tcx.features().staged_api() {
                            self.dcx().struct_span_err(span,
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("unstable feature `{0}` is used without being enabled.",
                                                    sym))
                                        })).with_help(::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("The feature can be enabled by marking the current item with `#[unstable_feature_bound({0})]`",
                                                sym))
                                    }))
                        } else {
                            feature_err_unstable_feature_bound(&self.tcx.sess, sym,
                                span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("use of unstable library feature `{0}`",
                                                sym))
                                    }))
                        }
                    }
                    _ => {
                        if let Some(e) = self.tainted_by_errors() { return e; }
                        let predicate =
                            self.tcx.short_string(predicate, &mut long_ty_path);
                        {
                                    self.dcx().struct_span_err(span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("type annotations needed: cannot satisfy `{0}`",
                                                            predicate))
                                                })).with_code(E0284)
                                }.with_span_label(span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("cannot satisfy `{0}`",
                                                predicate))
                                    })).with_long_ty_path(long_ty_path)
                    }
                };
            let mut mentioned =
                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                        [predicate]));
            let mut mentioned_strs: Vec<String> = ::alloc::vec::Vec::new();
            for &error in related {
                let related_pred =
                    self.deeply_resolve_ignoring_regions(error.obligation.predicate);
                if mentioned.contains(&related_pred) { continue; }
                let note =
                    match related_pred.kind().skip_binder() {
                        ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) if
                            !#[allow(non_exhaustive_omitted_patterns)] match self.tcx.as_lang_item(data.def_id())
                                    {
                                    Some(LangItem::Sized | LangItem::MetaSized |
                                        LangItem::PointeeSized) => true,
                                    _ => false,
                                } => {
                            let clause = related_pred.kind().rebind(data);
                            if let ty::Infer(_) = clause.self_ty().skip_binder().kind()
                                {
                                let tr =
                                    self.tcx.short_string(clause.print_modifiers_and_trait_path(),
                                        &mut err.long_ty_path());
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("the type must also implement `{0}`",
                                                tr))
                                    })
                            } else {
                                let pred =
                                    self.tcx.short_string(related_pred,
                                        &mut err.long_ty_path());
                                let note =
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("cannot satisfy `{0}`",
                                                    pred))
                                        });
                                if !mentioned_strs.contains(&note) &&
                                            self.tainted_by_errors().is_none() &&
                                        let Some(ambiguities) =
                                            self.applicable_impls_to_mention(&error.obligation, clause)
                                    {
                                    self.annotate_source_of_ambiguity(&mut err, &ambiguities,
                                        related_pred);
                                    mentioned_strs.push(note);
                                    mentioned.push(related_pred);
                                    continue;
                                }
                                note
                            }
                        }
                        ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) =>
                            {
                            let pred =
                                self.tcx.short_string(related_pred,
                                    &mut err.long_ty_path());
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("cannot satisfy `{0}`",
                                            pred))
                                })
                        }
                        _ => { mentioned.push(related_pred); continue; }
                    };
                if !mentioned_strs.contains(&note) {
                    err.note(note.clone());
                    mentioned_strs.push(note);
                }
                mentioned.push(related_pred);
            }
            self.note_obligation_cause(&mut err, obligation);
            for &error in related {
                if error.obligation.cause.code() != obligation.cause.code() {
                    self.note_obligation_cause(&mut err, &error.obligation);
                }
            }
            err.emit_err()
        }
    }
}#[instrument(skip(self), level = "debug")]
206    pub(super) fn maybe_report_ambiguity(
207        &self,
208        obligation: &PredicateObligation<'tcx>,
209        related: &[&FulfillmentError<'tcx>],
210    ) -> ErrorGuaranteed {
211        // Unable to successfully determine, probably means
212        // insufficient type information, but could mean
213        // ambiguous impls. The latter *ought* to be a
214        // coherence violation, so we don't report it here.
215
216        let predicate = self.deeply_resolve_ignoring_regions(obligation.predicate);
217        let span = obligation.cause.span;
218        let mut long_ty_path = None;
219
220        debug!(?predicate, obligation.cause.code = ?obligation.cause.code());
221
222        // Ambiguity errors are often caused as fallout from earlier errors.
223        // We ignore them if this `infcx` is tainted in some cases below.
224
225        let bound_predicate = predicate.kind();
226        let mut err = match bound_predicate.skip_binder() {
227            ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
228                let trait_pred = bound_predicate.rebind(data);
229                debug!(?trait_pred);
230
231                if let Err(e) = predicate.error_reported() {
232                    return e;
233                }
234
235                if let Err(guar) = self.tcx.ensure_result().coherent_trait(trait_pred.def_id()) {
236                    // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for
237                    // Foo` in case other `Foo` impls are incoherent.
238                    return guar;
239                }
240
241                // This is kind of a hack: it frequently happens that some earlier
242                // error prevents types from being fully inferred, and then we get
243                // a bunch of uninteresting errors saying something like "<generic
244                // #0> doesn't implement Sized". It may even be true that we
245                // could just skip over all checks where the self-ty is an
246                // inference variable, but I was afraid that there might be an
247                // inference variable created, registered as an obligation, and
248                // then never forced by writeback, and hence by skipping here we'd
249                // be ignoring the fact that we don't KNOW the type works
250                // out. Though even that would probably be harmless, given that
251                // we're only talking about builtin traits, which are known to be
252                // inhabited. We used to check for `self.tainted_by_errors()` to
253                // avoid inundating the user with unnecessary errors, but we now
254                // check upstream for type errors and don't add the obligations to
255                // begin with in those cases.
256                if matches!(
257                    self.tcx.as_lang_item(trait_pred.def_id()),
258                    Some(LangItem::Sized | LangItem::MetaSized)
259                ) {
260                    return match self.tainted_by_errors() {
261                        None => self
262                            .emit_inference_failure_err(
263                                obligation.cause.body_def_id,
264                                span,
265                                trait_pred.self_ty().skip_binder().into(),
266                                TypeAnnotationNeeded::E0282,
267                                false,
268                            )
269                            .emit_err(),
270                        Some(e) => e,
271                    };
272                }
273
274                // Typically, this ambiguity should only happen if
275                // there are unresolved type inference variables
276                // (otherwise it would suggest a coherence
277                // failure). But given #21974 that is not necessarily
278                // the case -- we can have multiple where clauses that
279                // are only distinguished by a region, which results
280                // in an ambiguity even when all types are fully
281                // known, since we don't dispatch based on region
282                // relationships.
283
284                // Pick the first generic parameter that still contains inference variables as the one
285                // we're going to emit an error for. If there are none (see above), fall back to
286                // a more general error.
287                let term = self.ambiguity_term(predicate);
288
289                let mut err = if let Some(term) = term {
290                    let candidates: Vec<_> = self
291                        .tcx
292                        .all_impls(trait_pred.def_id())
293                        .filter_map(|def_id| {
294                            let imp = self.tcx.impl_trait_header(def_id);
295                            if imp.polarity != ty::ImplPolarity::Positive
296                                || !self.tcx.is_user_visible_dep(def_id.krate)
297                            {
298                                return None;
299                            }
300                            let imp = imp.trait_ref.skip_binder();
301                            if imp
302                                .with_replaced_self_ty(self.tcx, trait_pred.skip_binder().self_ty())
303                                == trait_pred.skip_binder().trait_ref
304                            {
305                                Some(imp.self_ty())
306                            } else {
307                                None
308                            }
309                        })
310                        .collect();
311                    self.emit_inference_failure_err_with_type_hint(
312                        obligation.cause.body_def_id,
313                        span,
314                        term,
315                        TypeAnnotationNeeded::E0283,
316                        true,
317                        match &candidates[..] {
318                            [candidate] => Some(*candidate),
319                            _ => None,
320                        },
321                    )
322                } else {
323                    struct_span_code_err!(
324                        self.dcx(),
325                        span,
326                        E0283,
327                        "type annotations needed: cannot satisfy `{}`",
328                        self.tcx.short_string(predicate, &mut long_ty_path),
329                    )
330                    .with_long_ty_path(long_ty_path)
331                };
332
333                if let Some(ambiguities) = self.applicable_impls_to_mention(obligation, trait_pred)
334                {
335                    if let Some(e) = self.tainted_by_errors()
336                        && term.is_none()
337                    {
338                        // If `arg.is_none()`, then this is probably two param-env
339                        // candidates or impl candidates that are equal modulo lifetimes.
340                        // Therefore, if we've already emitted an error, just skip this
341                        // one, since it's not particularly actionable.
342                        err.cancel();
343                        return e;
344                    }
345                    self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
346                } else {
347                    if let Some(e) = self.tainted_by_errors() {
348                        err.cancel();
349                        return e;
350                    }
351                    if let Some(clause) = predicate.as_trait_clause()
352                        && let ty::Infer(_) = clause.self_ty().skip_binder().kind()
353                    {
354                        let tr = self.tcx.short_string(
355                            clause.print_modifiers_and_trait_path(),
356                            &mut err.long_ty_path(),
357                        );
358                        err.note(format!("the type must implement `{tr}`"));
359                    } else {
360                        let pred = self.tcx.short_string(predicate, &mut err.long_ty_path());
361                        err.note(format!("cannot satisfy `{pred}`"));
362                    }
363                    let clause = predicate.as_trait_clause().unwrap();
364                    let impl_candidates = self.find_similar_impl_candidates(
365                        clause.def_id(),
366                        clause.self_ty().skip_binder(),
367                    );
368                    if impl_candidates.len() < 40 {
369                        self.report_similar_impl_candidates(
370                            impl_candidates.as_slice(),
371                            obligation,
372                            trait_pred,
373                            obligation.cause.body_def_id,
374                            &mut err,
375                            false,
376                            obligation.param_env,
377                        );
378                    }
379                }
380
381                if let ObligationCauseCode::WhereClause(def_id, _)
382                | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *obligation.cause.code()
383                {
384                    self.suggest_fully_qualified_path(&mut err, def_id, span, trait_pred.def_id());
385                }
386
387                if term.is_some_and(|term| term.as_type().is_some())
388                    && let Some(body) =
389                        self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id)
390                {
391                    let mut expr_finder = FindExprBySpan::new(span, self.tcx);
392                    expr_finder.visit_expr(&body.value);
393
394                    if let Some(hir::Expr {
395                        kind:
396                            hir::ExprKind::Call(
397                                hir::Expr {
398                                    kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
399                                    ..
400                                },
401                                _,
402                            )
403                            | hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
404                        ..
405                    }) = expr_finder.result
406                        && let [
407                            ..,
408                            trait_path_segment @ hir::PathSegment {
409                                res: Res::Def(DefKind::Trait, trait_id),
410                                ..
411                            },
412                            hir::PathSegment {
413                                ident: assoc_item_ident,
414                                res: Res::Def(_, item_id),
415                                ..
416                            },
417                        ] = path.segments
418                        && data.trait_ref.def_id == *trait_id
419                        && self.tcx.trait_of_assoc(*item_id) == Some(*trait_id)
420                        && let None = self.tainted_by_errors()
421                    {
422                        let assoc_item = self.tcx.associated_item(*item_id);
423                        let (verb, noun) = match assoc_item.kind {
424                            ty::AssocKind::Const { .. } => ("refer to the", "constant"),
425                            ty::AssocKind::Fn { .. } => ("call", "function"),
426                            // This is already covered by E0223, but this following single match
427                            // arm doesn't hurt here.
428                            ty::AssocKind::Type { .. } => ("refer to the", "type"),
429                        };
430
431                        // Replace the more general E0283 with a more specific error
432                        err.cancel();
433                        err = self.dcx().struct_span_err(
434                            span,
435                            format!(
436                                "cannot {verb} associated {noun} on trait without specifying the \
437                                 corresponding `impl` type",
438                            ),
439                        );
440                        err.code(E0790);
441
442                        if item_id.is_local() {
443                            let trait_ident = self.tcx.item_name(*trait_id);
444                            err.span_label(
445                                self.tcx.def_span(*item_id),
446                                format!("`{trait_ident}::{assoc_item_ident}` defined here"),
447                            );
448                        }
449
450                        err.span_label(span, format!("cannot {verb} associated {noun} of trait"));
451
452                        let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id);
453
454                        if let Some(&impl_def_id) =
455                            trait_impls.non_blanket_impls().values().flatten().next()
456                        {
457                            let non_blanket_impl_count =
458                                trait_impls.non_blanket_impls().values().flatten().count();
459                            // If there is only one implementation of the trait, suggest using it.
460                            // Otherwise, use a placeholder comment for the implementation.
461                            let (message, self_types) = if non_blanket_impl_count == 1 {
462                                (
463                                    "use the fully-qualified path to the only available \
464                                     implementation",
465                                    vec![format!(
466                                        "{}",
467                                        self.tcx
468                                            .type_of(impl_def_id)
469                                            .instantiate_identity()
470                                            .skip_norm_wip()
471                                    )],
472                                )
473                            } else if non_blanket_impl_count < 20 {
474                                (
475                                    "use a fully-qualified path to one of the available \
476                                     implementations",
477                                    trait_impls
478                                        .non_blanket_impls()
479                                        .values()
480                                        .flatten()
481                                        .map(|&id| {
482                                            format!(
483                                                "{}",
484                                                self.tcx
485                                                    .type_of(id)
486                                                    .instantiate_identity()
487                                                    .skip_norm_wip()
488                                            )
489                                        })
490                                        .collect::<Vec<String>>(),
491                                )
492                            } else {
493                                (
494                                    "use a fully-qualified path to a specific available \
495                                     implementation",
496                                    vec!["/* self type */".to_string()],
497                                )
498                            };
499                            let suggestions: Vec<_> = self_types
500                                .into_iter()
501                                .map(|self_type| {
502                                    let mut suggestions = vec![(
503                                        path.span.shrink_to_lo(),
504                                        format!("<{self_type} as "),
505                                    )];
506                                    if let Some(generic_arg) = trait_path_segment.args {
507                                        let between_span = trait_path_segment
508                                            .ident
509                                            .span
510                                            .between(generic_arg.span_ext);
511                                        // get rid of :: between Trait and <type>
512                                        // must be '::' between them, otherwise the parser won't accept the code
513                                        suggestions.push((between_span, "".to_string()));
514                                        suggestions.push((
515                                            generic_arg.span_ext.shrink_to_hi(),
516                                            ">".to_string(),
517                                        ));
518                                    } else {
519                                        suggestions.push((
520                                            trait_path_segment.ident.span.shrink_to_hi(),
521                                            ">".to_string(),
522                                        ));
523                                    }
524                                    suggestions
525                                })
526                                .collect();
527                            err.multipart_suggestions(
528                                message,
529                                suggestions,
530                                Applicability::MaybeIncorrect,
531                            );
532                        }
533                    }
534                };
535
536                err
537            }
538
539            ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
540                // Same hacky approach as above to avoid deluging user
541                // with error messages.
542
543                if let Err(e) = term.error_reported() {
544                    return e;
545                }
546                if let Some(e) = self.tainted_by_errors() {
547                    return e;
548                }
549
550                self.emit_inference_failure_err(
551                    obligation.cause.body_def_id,
552                    span,
553                    term,
554                    TypeAnnotationNeeded::E0282,
555                    false,
556                )
557            }
558
559            ty::PredicateKind::Subtype(data) => {
560                if let Err(e) = data.error_reported() {
561                    return e;
562                }
563                if let Some(e) = self.tainted_by_errors() {
564                    return e;
565                }
566                let ty::SubtypePredicate { a_is_expected: _, a, b } = data;
567                // both must be type variables, or the other would've been instantiated
568                assert!(a.is_ty_var() && b.is_ty_var());
569                self.emit_inference_failure_err(
570                    obligation.cause.body_def_id,
571                    span,
572                    a.into(),
573                    TypeAnnotationNeeded::E0282,
574                    true,
575                )
576            }
577
578            ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
579                if let Err(e) = predicate.error_reported() {
580                    return e;
581                }
582                if let Some(e) = self.tainted_by_errors() {
583                    return e;
584                }
585
586                if data.projection_term.kind.is_trait_projection()
587                    && let Err(guar) =
588                        self.tcx.ensure_result().coherent_trait(self.tcx.parent(data.def_id()))
589                {
590                    // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
591                    // other `Foo` impls are incoherent.
592                    return guar;
593                }
594                let term = self.ambiguity_term(predicate);
595                let predicate = self.tcx.short_string(predicate, &mut long_ty_path);
596                if let Some(term) = term {
597                    self.emit_inference_failure_err(
598                        obligation.cause.body_def_id,
599                        span,
600                        term,
601                        TypeAnnotationNeeded::E0284,
602                        true,
603                    )
604                    .with_note(format!("cannot satisfy `{predicate}`"))
605                    .with_long_ty_path(long_ty_path)
606                } else {
607                    // If we can't find a generic parameter, just print a generic error
608                    struct_span_code_err!(
609                        self.dcx(),
610                        span,
611                        E0284,
612                        "type annotations needed: cannot satisfy `{predicate}`",
613                    )
614                    .with_span_label(span, format!("cannot satisfy `{predicate}`"))
615                    .with_long_ty_path(long_ty_path)
616                }
617            }
618
619            ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) => {
620                if let Err(e) = predicate.error_reported() {
621                    return e;
622                }
623                if let Some(e) = self.tainted_by_errors() {
624                    return e;
625                }
626                if let Some(term) = self.ambiguity_term(predicate) {
627                    self.emit_inference_failure_err(
628                        obligation.cause.body_def_id,
629                        span,
630                        term,
631                        TypeAnnotationNeeded::E0284,
632                        true,
633                    )
634                } else {
635                    // If we can't find a generic parameter, just print a generic error
636                    let predicate = self.tcx.short_string(predicate, &mut long_ty_path);
637                    struct_span_code_err!(
638                        self.dcx(),
639                        span,
640                        E0284,
641                        "type annotations needed: cannot satisfy `{predicate}`",
642                    )
643                    .with_span_label(span, format!("cannot satisfy `{predicate}`"))
644                    .with_long_ty_path(long_ty_path)
645                }
646            }
647
648            ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self
649                .emit_inference_failure_err(
650                    obligation.cause.body_def_id,
651                    span,
652                    ct.into(),
653                    TypeAnnotationNeeded::E0284,
654                    true,
655                ),
656
657            ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })
658                if term.is_infer() =>
659            {
660                if let Some(e) = self.tainted_by_errors() {
661                    return e;
662                }
663                let alias = self.tcx.short_string(alias, &mut long_ty_path);
664                struct_span_code_err!(
665                    self.dcx(),
666                    span,
667                    E0284,
668                    "type annotations needed: cannot normalize `{alias}`",
669                )
670                .with_span_label(span, format!("cannot normalize `{alias}`"))
671                .with_long_ty_path(long_ty_path)
672            }
673
674            ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(sym)) => {
675                if let Some(e) = self.tainted_by_errors() {
676                    return e;
677                }
678
679                if self.tcx.features().staged_api() {
680                    self.dcx().struct_span_err(
681                        span,
682                        format!("unstable feature `{sym}` is used without being enabled."),
683                    ).with_help(format!("The feature can be enabled by marking the current item with `#[unstable_feature_bound({sym})]`"))
684                } else {
685                    feature_err_unstable_feature_bound(
686                        &self.tcx.sess,
687                        sym,
688                        span,
689                        format!("use of unstable library feature `{sym}`"),
690                    )
691                }
692            }
693
694            _ => {
695                if let Some(e) = self.tainted_by_errors() {
696                    return e;
697                }
698                let predicate = self.tcx.short_string(predicate, &mut long_ty_path);
699                struct_span_code_err!(
700                    self.dcx(),
701                    span,
702                    E0284,
703                    "type annotations needed: cannot satisfy `{predicate}`",
704                )
705                .with_span_label(span, format!("cannot satisfy `{predicate}`"))
706                .with_long_ty_path(long_ty_path)
707            }
708        };
709
710        // The related obligations are ambiguous because of the same inference variable,
711        // so they belong to this diagnostic: annotating the variable has to satisfy all
712        // of them at once. Mention their requirements, except for bookkeeping predicates
713        // (`WellFormed`, sizedness, ...) whose mention wouldn't be actionable.
714        let mut mentioned = vec![predicate];
715        let mut mentioned_strs: Vec<String> = vec![];
716        for &error in related {
717            let related_pred = self.deeply_resolve_ignoring_regions(error.obligation.predicate);
718            if mentioned.contains(&related_pred) {
719                continue;
720            }
721            let note = match related_pred.kind().skip_binder() {
722                ty::PredicateKind::Clause(ty::ClauseKind::Trait(data))
723                    if !matches!(
724                        self.tcx.as_lang_item(data.def_id()),
725                        Some(LangItem::Sized | LangItem::MetaSized | LangItem::PointeeSized)
726                    ) =>
727                {
728                    let clause = related_pred.kind().rebind(data);
729                    if let ty::Infer(_) = clause.self_ty().skip_binder().kind() {
730                        let tr = self.tcx.short_string(
731                            clause.print_modifiers_and_trait_path(),
732                            &mut err.long_ty_path(),
733                        );
734                        format!("the type must also implement `{tr}`")
735                    } else {
736                        let pred = self.tcx.short_string(related_pred, &mut err.long_ty_path());
737                        let note = format!("cannot satisfy `{pred}`");
738                        // The self type is known, so the `impl`s that could have applied to it are
739                        // few and worth pointing at, like the blamed bound does. When it is still
740                        // an inference variable the list is every `impl` of the trait, which is
741                        // why the branch above only names the trait.
742                        //
743                        // `tainted_by_errors` is checked because `annotate_source_of_ambiguity`
744                        // downgrades the whole diagnostic once an error was already emitted.
745                        if !mentioned_strs.contains(&note)
746                            && self.tainted_by_errors().is_none()
747                            && let Some(ambiguities) =
748                                self.applicable_impls_to_mention(&error.obligation, clause)
749                        {
750                            self.annotate_source_of_ambiguity(&mut err, &ambiguities, related_pred);
751                            mentioned_strs.push(note);
752                            mentioned.push(related_pred);
753                            continue;
754                        }
755                        note
756                    }
757                }
758                ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
759                    let pred = self.tcx.short_string(related_pred, &mut err.long_ty_path());
760                    format!("cannot satisfy `{pred}`")
761                }
762                _ => {
763                    mentioned.push(related_pred);
764                    continue;
765                }
766            };
767            // Two predicates can print identically (e.g. `From<?0>` and `From<?1>` both show as
768            // `From<_>`); only emit each unique note string once.
769            if !mentioned_strs.contains(&note) {
770                err.note(note.clone());
771                mentioned_strs.push(note);
772            }
773            mentioned.push(related_pred);
774        }
775
776        self.note_obligation_cause(&mut err, obligation);
777        // The merged errors are not reported on their own anymore, so the bounds they came from
778        // have to be explained here too. Causes shared with the blamed obligation are already
779        // described by the call above.
780        for &error in related {
781            if error.obligation.cause.code() != obligation.cause.code() {
782                self.note_obligation_cause(&mut err, &error.obligation);
783            }
784        }
785        err.emit_err()
786    }
787
788    /// The `impl`s and `where` clauses that could have satisfied `trait_pred`, when listing them
789    /// is likely to help. `None` means the caller should describe the bound some other way.
790    fn applicable_impls_to_mention(
791        &self,
792        obligation: &PredicateObligation<'tcx>,
793        trait_pred: ty::PolyTraitClause<'tcx>,
794    ) -> Option<Vec<CandidateSource>> {
795        let mut ambiguities = compute_applicable_impls_for_diagnostics(
796            self.infcx,
797            &obligation.with(self.tcx, trait_pred),
798            false,
799        );
800        let has_non_region_infer =
801            trait_pred.skip_binder().trait_ref.args.types().any(|t| !t.is_ty_or_numeric_infer());
802        // It doesn't make sense to talk about applicable impls if there are more than a
803        // handful of them. If there are a lot of them, but only a few of them have no type
804        // params, we only show those, as they are more likely to be useful/intended.
805        if ambiguities.len() > 5 {
806            let infcx = self.infcx;
807            if !ambiguities.iter().all(|option| match option {
808                CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0,
809                CandidateSource::ParamEnv(_) => true,
810            }) {
811                // If not all are blanket impls, we filter blanked impls out.
812                ambiguities.retain(|option| match option {
813                    CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0,
814                    CandidateSource::ParamEnv(_) => true,
815                });
816            }
817        }
818        (ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer)
819            .then_some(ambiguities)
820    }
821
822    fn annotate_source_of_ambiguity(
823        &self,
824        err: &mut Diag<'_>,
825        ambiguities: &[CandidateSource],
826        predicate: ty::Predicate<'tcx>,
827    ) {
828        let mut spans = ::alloc::vec::Vec::new()vec![];
829        let mut crates = ::alloc::vec::Vec::new()vec![];
830        let mut post = ::alloc::vec::Vec::new()vec![];
831        let mut has_param_env = false;
832        for ambiguity in ambiguities {
833            match ambiguity {
834                CandidateSource::DefId(impl_def_id) => match self.tcx.span_of_impl(*impl_def_id) {
835                    Ok(span) => spans.push(span),
836                    Err(name) => {
837                        crates.push(name);
838                        if let Some(header) = to_pretty_impl_header(self.tcx, *impl_def_id) {
839                            post.push(header);
840                        }
841                    }
842                },
843                CandidateSource::ParamEnv(span) => {
844                    has_param_env = true;
845                    spans.push(*span);
846                }
847            }
848        }
849        let mut crate_names: Vec<_> = crates.iter().map(|n| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}`", n))
    })format!("`{n}`")).collect();
850        crate_names.sort();
851        crate_names.dedup();
852        post.sort();
853        post.dedup();
854
855        if self.tainted_by_errors().is_some()
856            && (crate_names.len() == 1
857                && spans.len() == 0
858                && ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str())
859                || predicate.visit_with(&mut HasNumericInferVisitor).is_break())
860        {
861            // Avoid complaining about other inference issues for expressions like
862            // `42 >> 1`, where the types are still `{integer}`, but we want to
863            // Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too?
864            // NOTE(eddyb) this was `.cancel()`, but `err`
865            // is borrowed, so we can't fully defuse it.
866            err.downgrade_to_delayed_bug();
867            return;
868        }
869
870        let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("multiple `impl`s{0} satisfying `{1}` found",
                if has_param_env { " or `where` clauses" } else { "" },
                predicate))
    })format!(
871            "multiple `impl`s{} satisfying `{}` found",
872            if has_param_env { " or `where` clauses" } else { "" },
873            predicate
874        );
875        let post = if post.len() > 1 || (post.len() == 1 && post[0].contains('\n')) {
876            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(":\n{0}",
                post.iter().map(|p|
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("- {0}", p))
                                    })).collect::<Vec<_>>().join("\n")))
    })format!(":\n{}", post.iter().map(|p| format!("- {p}")).collect::<Vec<_>>().join("\n"))
877        } else if post.len() == 1 {
878            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(": `{0}`", post[0]))
    })format!(": `{}`", post[0])
879        } else {
880            String::new()
881        };
882
883        match (spans.len(), crates.len(), crate_names.len()) {
884            (0, 0, 0) => {
885                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("cannot satisfy `{0}`", predicate))
    })format!("cannot satisfy `{predicate}`"));
886            }
887            (0, _, 1) => {
888                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{1} in the `{0}` crate{2}",
                crates[0], msg, post))
    })format!("{msg} in the `{}` crate{post}", crates[0]));
889            }
890            (0, _, _) => {
891                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} in the following crates: {1}{2}",
                msg, crate_names.join(", "), post))
    })format!(
892                    "{} in the following crates: {}{}",
893                    msg,
894                    crate_names.join(", "),
895                    post,
896                ));
897            }
898            (_, 0, 0) => {
899                let span: MultiSpan = spans.into();
900                err.span_note(span, msg);
901            }
902            (_, 1, 1) => {
903                let span: MultiSpan = spans.into();
904                err.span_note(span, msg);
905                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("and another `impl` found in the `{0}` crate{1}",
                crates[0], post))
    })format!("and another `impl` found in the `{}` crate{post}", crates[0]));
906            }
907            _ => {
908                let span: MultiSpan = spans.into();
909                err.span_note(span, msg);
910                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("and more `impl`s found in the following crates: {0}{1}",
                crate_names.join(", "), post))
    })format!(
911                    "and more `impl`s found in the following crates: {}{}",
912                    crate_names.join(", "),
913                    post,
914                ));
915            }
916        }
917    }
918}
919
920struct HasNumericInferVisitor;
921
922impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for HasNumericInferVisitor {
923    type Result = ControlFlow<()>;
924
925    fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
926        if #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Infer(ty::FloatVar(_) | ty::IntVar(_)) => true,
    _ => false,
}matches!(ty.kind(), ty::Infer(ty::FloatVar(_) | ty::IntVar(_))) {
927            ControlFlow::Break(())
928        } else {
929            ControlFlow::Continue(())
930        }
931    }
932}