Skip to main content

rustc_trait_selection/error_reporting/traits/
suggestions.rs

1// ignore-tidy-filelength
2
3use std::borrow::Cow;
4use std::path::PathBuf;
5use std::{debug_assert_matches, iter};
6
7use itertools::{EitherOrBoth, Itertools};
8use rustc_abi::ExternAbi;
9use rustc_data_structures::fx::FxHashSet;
10use rustc_data_structures::stack::ensure_sufficient_stack;
11use rustc_errors::codes::*;
12use rustc_errors::{
13    Applicability, Diag, EmissionGuarantee, MultiSpan, Style, SuggestionStyle, pluralize,
14    struct_span_code_err,
15};
16use rustc_hir::def::{CtorOf, DefKind, Res};
17use rustc_hir::def_id::DefId;
18use rustc_hir::intravisit::{Visitor, VisitorExt};
19use rustc_hir::lang_items::LangItem;
20use rustc_hir::{
21    self as hir, AmbigArg, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node,
22    expr_needs_parens,
23};
24use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk};
25use rustc_infer::traits::ImplSource;
26use rustc_middle::middle::privacy::Level;
27use rustc_middle::traits::IsConstable;
28use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
29use rustc_middle::ty::error::TypeError;
30use rustc_middle::ty::print::{
31    PrintPolyTraitPredicateExt as _, PrintPolyTraitRefExt, PrintTraitPredicateExt as _,
32    PrintTraitRefExt as _, with_forced_trimmed_paths, with_no_trimmed_paths,
33    with_types_for_suggestion,
34};
35use rustc_middle::ty::{
36    self, AdtKind, GenericArgs, InferTy, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeFolder,
37    TypeSuperFoldable, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, TypeckResults,
38    Unnormalized, Upcast, suggest_arbitrary_trait_bound, suggest_constraining_type_param,
39};
40use rustc_middle::{bug, span_bug};
41use rustc_span::def_id::LocalDefId;
42use rustc_span::{
43    BytePos, DUMMY_SP, DesugaringKind, ExpnKind, Ident, MacroKind, Span, Symbol, kw, sym,
44};
45use tracing::{debug, instrument};
46
47use super::{
48    DefIdOrName, FindExprBySpan, ImplCandidate, Obligation, ObligationCause, ObligationCauseCode,
49    PredicateObligation,
50};
51use crate::diagnostics;
52use crate::error_reporting::TypeErrCtxt;
53use crate::infer::InferCtxtExt as _;
54use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
55use crate::traits::{ImplDerivedCause, NormalizeExt, ObligationCtxt, SelectionContext};
56
57#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CoroutineInteriorOrUpvar {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            CoroutineInteriorOrUpvar::Interior(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "Interior", __self_0, &__self_1),
            CoroutineInteriorOrUpvar::Upvar(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Upvar",
                    &__self_0),
        }
    }
}Debug)]
58pub enum CoroutineInteriorOrUpvar {
59    // span of interior type
60    Interior(Span, Option<(Span, Option<Span>)>),
61    // span of upvar
62    Upvar(Span),
63}
64
65// This type provides a uniform interface to retrieve data on coroutines, whether it originated from
66// the local crate being compiled or from a foreign crate.
67#[derive(#[automatically_derived]
impl<'a, 'tcx> ::core::fmt::Debug for CoroutineData<'a, 'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "CoroutineData",
            &&self.0)
    }
}Debug)]
68struct CoroutineData<'a, 'tcx>(&'a TypeckResults<'tcx>);
69
70impl<'a, 'tcx> CoroutineData<'a, 'tcx> {
71    /// Try to get information about variables captured by the coroutine that matches a type we are
72    /// looking for with `ty_matches` function. We uses it to find upvar which causes a failure to
73    /// meet an obligation
74    fn try_get_upvar_span<F>(
75        &self,
76        infer_context: &InferCtxt<'tcx>,
77        coroutine_did: DefId,
78        ty_matches: F,
79    ) -> Option<CoroutineInteriorOrUpvar>
80    where
81        F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
82    {
83        infer_context.tcx.upvars_mentioned(coroutine_did).and_then(|upvars| {
84            upvars.iter().find_map(|(upvar_id, upvar)| {
85                let upvar_ty = self.0.node_type(*upvar_id);
86                let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty);
87                ty_matches(ty::Binder::dummy(upvar_ty))
88                    .then(|| CoroutineInteriorOrUpvar::Upvar(upvar.span))
89            })
90        })
91    }
92
93    /// Try to get the span of a type being awaited on that matches the type we are looking with the
94    /// `ty_matches` function. We uses it to find awaited type which causes a failure to meet an
95    /// obligation
96    fn get_from_await_ty<F>(
97        &self,
98        visitor: AwaitsVisitor,
99        tcx: TyCtxt<'tcx>,
100        ty_matches: F,
101    ) -> Option<Span>
102    where
103        F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
104    {
105        visitor
106            .awaits
107            .into_iter()
108            .map(|id| tcx.hir_expect_expr(id))
109            .find(|await_expr| ty_matches(ty::Binder::dummy(self.0.expr_ty_adjusted(await_expr))))
110            .map(|expr| expr.span)
111    }
112}
113
114fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
115    (
116        generics.tail_span_for_predicate_suggestion(),
117        {
    let _guard =
        ::rustc_middle::ty::print::pretty::RtnModeHelper::with(RtnMode::ForSuggestion);
    ::alloc::__export::must_use({
            ::alloc::fmt::format(format_args!("{0} {1}",
                    generics.add_where_or_trailing_comma(), pred))
        })
}with_types_for_suggestion!(format!("{} {}", generics.add_where_or_trailing_comma(), pred)),
118    )
119}
120
121/// Type parameter needs more bounds. The trivial case is `T` `where T: Bound`, but
122/// it can also be an `impl Trait` param that needs to be decomposed to a type
123/// param for cleaner code.
124pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
125    tcx: TyCtxt<'tcx>,
126    item_id: LocalDefId,
127    hir_generics: &hir::Generics<'tcx>,
128    msg: &str,
129    err: &mut Diag<'_, G>,
130    fn_sig: Option<&hir::FnSig<'_>>,
131    projection: Option<ty::ProjectionAliasTy<'_>>,
132    trait_pred: ty::PolyTraitPredicate<'tcx>,
133    // When we are dealing with a trait, `super_traits` will be `Some`:
134    // Given `trait T: A + B + C {}`
135    //              -  ^^^^^^^^^ GenericBounds
136    //              |
137    //              &Ident
138    super_traits: Option<(&Ident, &hir::GenericBounds<'_>)>,
139) {
140    if hir_generics.where_clause_span.from_expansion()
141        || hir_generics.where_clause_span.desugaring_kind().is_some()
142        || projection.is_some_and(|projection| {
143            (tcx.is_impl_trait_in_trait(projection.kind) && !tcx.features().return_type_notation())
144                || tcx.lookup_stability(projection.kind).is_some_and(|stab| stab.is_unstable())
145        })
146    {
147        return;
148    }
149    let generics = tcx.generics_of(item_id);
150    // Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`...
151    if let Some((param, bound_str, fn_sig)) =
152        fn_sig.zip(projection).and_then(|(sig, p)| match *p.projection_self_ty().kind() {
153            // Shenanigans to get the `Trait` from the `impl Trait`.
154            ty::Param(param) => {
155                let param_def = generics.type_param(param, tcx);
156                if param_def.kind.is_synthetic() {
157                    let bound_str =
158                        param_def.name.as_str().strip_prefix("impl ")?.trim_start().to_string();
159                    return Some((param_def, bound_str, sig));
160                }
161                None
162            }
163            _ => None,
164        })
165    {
166        let type_param_name = hir_generics.params.next_type_param_name(Some(&bound_str));
167        let trait_pred = trait_pred.fold_with(&mut ReplaceImplTraitFolder {
168            tcx,
169            param,
170            replace_ty: ty::ParamTy::new(generics.count() as u32, Symbol::intern(&type_param_name))
171                .to_ty(tcx),
172        });
173        if !trait_pred.is_suggestable(tcx, false) {
174            return;
175        }
176        // We know we have an `impl Trait` that doesn't satisfy a required projection.
177
178        // Find all of the occurrences of `impl Trait` for `Trait` in the function arguments'
179        // types. There should be at least one, but there might be *more* than one. In that
180        // case we could just ignore it and try to identify which one needs the restriction,
181        // but instead we choose to suggest replacing all instances of `impl Trait` with `T`
182        // where `T: Trait`.
183        let mut ty_spans = ::alloc::vec::Vec::new()vec![];
184        for input in fn_sig.decl.inputs {
185            ReplaceImplTraitVisitor { ty_spans: &mut ty_spans, param_did: param.def_id }
186                .visit_ty_unambig(input);
187        }
188        // The type param `T: Trait` we will suggest to introduce.
189        let type_param = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}: {1}", type_param_name,
                bound_str))
    })format!("{type_param_name}: {bound_str}");
190
191        let mut sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [if let Some(span) = hir_generics.span_for_param_suggestion() {
                    (span,
                        ::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!(", {0}", type_param))
                            }))
                } else {
                    (hir_generics.span,
                        ::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("<{0}>", type_param))
                            }))
                },
                predicate_constraint(hir_generics, trait_pred.upcast(tcx))]))vec![
192            if let Some(span) = hir_generics.span_for_param_suggestion() {
193                (span, format!(", {type_param}"))
194            } else {
195                (hir_generics.span, format!("<{type_param}>"))
196            },
197            // `fn foo(t: impl Trait)`
198            //                       ^ suggest `where <T as Trait>::A: Bound`
199            predicate_constraint(hir_generics, trait_pred.upcast(tcx)),
200        ];
201        sugg.extend(ty_spans.into_iter().map(|s| (s, type_param_name.to_string())));
202
203        // Suggest `fn foo<T: Trait>(t: T) where <T as Trait>::A: Bound`.
204        // FIXME: we should suggest `fn foo(t: impl Trait<A: Bound>)` instead.
205        err.multipart_suggestion(
206            "introduce a type parameter with a trait bound instead of using `impl Trait`",
207            sugg,
208            Applicability::MaybeIncorrect,
209        );
210    } else {
211        if !trait_pred.is_suggestable(tcx, false) {
212            return;
213        }
214        // Trivial case: `T` needs an extra bound: `T: Bound`.
215        let (sp, suggestion) = match (
216            hir_generics
217                .params
218                .iter()
219                .find(|p| !#[allow(non_exhaustive_omitted_patterns)] match p.kind {
    hir::GenericParamKind::Type { synthetic: true, .. } => true,
    _ => false,
}matches!(p.kind, hir::GenericParamKind::Type { synthetic: true, .. })),
220            super_traits,
221        ) {
222            (_, None) => predicate_constraint(hir_generics, trait_pred.upcast(tcx)),
223            (None, Some((ident, []))) => (
224                ident.span.shrink_to_hi(),
225                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(": {0}",
                trait_pred.print_modifiers_and_trait_path()))
    })format!(": {}", trait_pred.print_modifiers_and_trait_path()),
226            ),
227            (_, Some((_, [.., bounds]))) => (
228                bounds.span().shrink_to_hi(),
229                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" + {0}",
                trait_pred.print_modifiers_and_trait_path()))
    })format!(" + {}", trait_pred.print_modifiers_and_trait_path()),
230            ),
231            (Some(_), Some((_, []))) => (
232                hir_generics.span.shrink_to_hi(),
233                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(": {0}",
                trait_pred.print_modifiers_and_trait_path()))
    })format!(": {}", trait_pred.print_modifiers_and_trait_path()),
234            ),
235        };
236
237        err.span_suggestion_verbose(
238            sp,
239            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider further restricting {0}",
                msg))
    })format!("consider further restricting {msg}"),
240            suggestion,
241            Applicability::MachineApplicable,
242        );
243    }
244}
245
246/// A single layer of `&` peeled from an expression, used by
247/// [`TypeErrCtxt::peel_expr_refs`].
248struct PeeledRef<'tcx> {
249    /// The span covering the `&` (and any whitespace/mutability keyword) to remove.
250    span: Span,
251    /// The type after peeling this layer (and all prior layers).
252    peeled_ty: Ty<'tcx>,
253}
254
255impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
256    pub fn note_field_shadowed_by_private_candidate_in_cause(
257        &self,
258        err: &mut Diag<'_>,
259        cause: &ObligationCause<'tcx>,
260        param_env: ty::ParamEnv<'tcx>,
261    ) {
262        let mut hir_ids = FxHashSet::default();
263        // Walk the parent chain so we can recover
264        // the source expression from whichever layer carries them.
265        let mut next_code = Some(cause.code());
266        while let Some(cause_code) = next_code {
267            match cause_code {
268                ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, .. } => {
269                    hir_ids.insert(*lhs_hir_id);
270                    hir_ids.insert(*rhs_hir_id);
271                }
272                ObligationCauseCode::FunctionArg { arg_hir_id, .. }
273                | ObligationCauseCode::ReturnValue(arg_hir_id)
274                | ObligationCauseCode::AwaitableExpr(arg_hir_id)
275                | ObligationCauseCode::BlockTailExpression(arg_hir_id, _)
276                | ObligationCauseCode::UnOp { hir_id: arg_hir_id } => {
277                    hir_ids.insert(*arg_hir_id);
278                }
279                ObligationCauseCode::OpaqueReturnType(Some((_, hir_id))) => {
280                    hir_ids.insert(*hir_id);
281                }
282                _ => {}
283            }
284            next_code = cause_code.parent();
285        }
286
287        if !cause.span.is_dummy()
288            && let Some(body) = self.tcx.hir_maybe_body_owned_by(cause.body_id)
289        {
290            let mut expr_finder = FindExprBySpan::new(cause.span, self.tcx);
291            expr_finder.visit_body(body);
292            if let Some(expr) = expr_finder.result {
293                hir_ids.insert(expr.hir_id);
294            }
295        }
296
297        // we will sort immediately by source order before emitting any diagnostics
298        #[allow(rustc::potential_query_instability)]
299        let mut hir_ids: Vec<_> = hir_ids.into_iter().collect();
300        let source_map = self.tcx.sess.source_map();
301        hir_ids.sort_by_cached_key(|hir_id| {
302            let span = self.tcx.hir_span(*hir_id);
303            let lo = source_map.lookup_byte_offset(span.lo());
304            let hi = source_map.lookup_byte_offset(span.hi());
305            (lo.sf.name.prefer_remapped_unconditionally().to_string(), lo.pos.0, hi.pos.0)
306        });
307
308        for hir_id in hir_ids {
309            self.note_field_shadowed_by_private_candidate(err, hir_id, param_env);
310        }
311    }
312
313    pub fn note_field_shadowed_by_private_candidate(
314        &self,
315        err: &mut Diag<'_>,
316        hir_id: hir::HirId,
317        param_env: ty::ParamEnv<'tcx>,
318    ) {
319        let Some(typeck_results) = &self.typeck_results else {
320            return;
321        };
322        let Node::Expr(expr) = self.tcx.hir_node(hir_id) else {
323            return;
324        };
325        let hir::ExprKind::Field(base_expr, field_ident) = expr.kind else {
326            return;
327        };
328
329        let Some(base_ty) = typeck_results.expr_ty_opt(base_expr) else {
330            return;
331        };
332        let base_ty = self.resolve_vars_if_possible(base_ty);
333        if base_ty.references_error() {
334            return;
335        }
336
337        let mut private_candidate: Option<(Ty<'tcx>, Ty<'tcx>, Span)> = None;
338
339        for (deref_base_ty, _) in (self.autoderef_steps)(base_ty) {
340            let ty::Adt(base_def, args) = deref_base_ty.kind() else {
341                continue;
342            };
343
344            if base_def.is_enum() {
345                continue;
346            }
347
348            let (adjusted_ident, def_scope) = self.tcx.adjust_ident_and_get_scope(
349                field_ident,
350                base_def.did(),
351                typeck_results.hir_owner.def_id,
352            );
353
354            let Some((_, field_def)) =
355                base_def.non_enum_variant().fields.iter_enumerated().find(|(_, field)| {
356                    field.ident(self.tcx).normalize_to_macros_2_0() == adjusted_ident
357                })
358            else {
359                continue;
360            };
361            let field_span = self
362                .tcx
363                .def_ident_span(field_def.did)
364                .unwrap_or_else(|| self.tcx.def_span(field_def.did));
365
366            if field_def.vis.is_accessible_from(def_scope, self.tcx) {
367                let accessible_field_ty = field_def.ty(self.tcx, args).skip_norm_wip();
368                if let Some((private_base_ty, private_field_ty, private_field_span)) =
369                    private_candidate
370                    && !self.can_eq(param_env, private_field_ty, accessible_field_ty)
371                {
372                    let private_struct_span = match private_base_ty.kind() {
373                        ty::Adt(private_base_def, _) => self
374                            .tcx
375                            .def_ident_span(private_base_def.did())
376                            .unwrap_or_else(|| self.tcx.def_span(private_base_def.did())),
377                        _ => DUMMY_SP,
378                    };
379                    let accessible_struct_span = self
380                        .tcx
381                        .def_ident_span(base_def.did())
382                        .unwrap_or_else(|| self.tcx.def_span(base_def.did()));
383                    let deref_impl_span = (typeck_results
384                        .expr_adjustments(base_expr)
385                        .iter()
386                        .filter(|adj| {
387                            #[allow(non_exhaustive_omitted_patterns)] match adj.kind {
    Adjust::Deref(DerefAdjustKind::Overloaded(_)) => true,
    _ => false,
}matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Overloaded(_)))
388                        })
389                        .count()
390                        == 1)
391                        .then(|| {
392                            self.probe(|_| {
393                                let deref_trait_did =
394                                    self.tcx.require_lang_item(LangItem::Deref, DUMMY_SP);
395                                let trait_ref =
396                                    ty::TraitRef::new(self.tcx, deref_trait_did, [private_base_ty]);
397                                let obligation: Obligation<'tcx, ty::Predicate<'tcx>> =
398                                    Obligation::new(
399                                        self.tcx,
400                                        ObligationCause::dummy(),
401                                        param_env,
402                                        trait_ref,
403                                    );
404                                let Ok(Some(ImplSource::UserDefined(impl_data))) =
405                                    SelectionContext::new(self)
406                                        .select(&obligation.with(self.tcx, trait_ref))
407                                else {
408                                    return None;
409                                };
410                                Some(self.tcx.def_span(impl_data.impl_def_id))
411                            })
412                        })
413                        .flatten();
414
415                    let mut note_spans: MultiSpan = private_struct_span.into();
416                    if private_struct_span != DUMMY_SP {
417                        note_spans.push_span_label(private_struct_span, "in this struct");
418                    }
419                    if private_field_span != DUMMY_SP {
420                        note_spans.push_span_label(
421                            private_field_span,
422                            "if this field wasn't private, it would be accessible",
423                        );
424                    }
425                    if accessible_struct_span != DUMMY_SP {
426                        note_spans.push_span_label(
427                            accessible_struct_span,
428                            "this struct is accessible through auto-deref",
429                        );
430                    }
431                    if field_span != DUMMY_SP {
432                        note_spans
433                            .push_span_label(field_span, "this is the field that was accessed");
434                    }
435                    if let Some(deref_impl_span) = deref_impl_span
436                        && deref_impl_span != DUMMY_SP
437                    {
438                        note_spans.push_span_label(
439                            deref_impl_span,
440                            "the field was accessed through this `Deref`",
441                        );
442                    }
443
444                    err.span_note(
445                        note_spans,
446                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("there is a field `{0}` on `{1}` with type `{2}` but it is private; `{0}` from `{3}` was accessed through auto-deref instead",
                field_ident, private_base_ty, private_field_ty,
                deref_base_ty))
    })format!(
447                            "there is a field `{field_ident}` on `{private_base_ty}` with type `{private_field_ty}` but it is private; `{field_ident}` from `{deref_base_ty}` was accessed through auto-deref instead"
448                        ),
449                    );
450                }
451
452                // we finally get to the accessible field,
453                // so we can return early without checking the rest of the autoderef candidates
454                return;
455            }
456
457            private_candidate.get_or_insert((
458                deref_base_ty,
459                field_def.ty(self.tcx, args).skip_norm_wip(),
460                field_span,
461            ));
462        }
463    }
464
465    pub fn suggest_restricting_param_bound(
466        &self,
467        err: &mut Diag<'_>,
468        trait_pred: ty::PolyTraitPredicate<'tcx>,
469        associated_ty: Option<(&'static str, Ty<'tcx>)>,
470        mut body_id: LocalDefId,
471    ) {
472        if trait_pred.skip_binder().polarity != ty::PredicatePolarity::Positive {
473            return;
474        }
475
476        let trait_pred = self.resolve_numeric_literals_with_default(trait_pred);
477
478        let self_ty = trait_pred.skip_binder().self_ty();
479        let (param_ty, projection) = match *self_ty.kind() {
480            ty::Param(_) => (true, None),
481            ty::Alias(_, alias) => {
482                if let Some(projection) = alias.try_to_projection() {
483                    (false, Some(projection))
484                } else {
485                    (false, None)
486                }
487            }
488            _ => (false, None),
489        };
490
491        let mut finder = ParamFinder { .. };
492        finder.visit_binder(&trait_pred);
493
494        // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
495        //        don't suggest `T: Sized + ?Sized`.
496        loop {
497            let node = self.tcx.hir_node_by_def_id(body_id);
498            match node {
499                hir::Node::Item(hir::Item {
500                    kind: hir::ItemKind::Trait { ident, generics, bounds, .. },
501                    ..
502                }) if self_ty == self.tcx.types.self_param => {
503                    if !param_ty { ::core::panicking::panic("assertion failed: param_ty") };assert!(param_ty);
504                    // Restricting `Self` for a single method.
505                    suggest_restriction(
506                        self.tcx,
507                        body_id,
508                        generics,
509                        "`Self`",
510                        err,
511                        None,
512                        projection,
513                        trait_pred,
514                        Some((&ident, bounds)),
515                    );
516                    return;
517                }
518
519                hir::Node::TraitItem(hir::TraitItem {
520                    generics,
521                    kind: hir::TraitItemKind::Fn(..),
522                    ..
523                }) if self_ty == self.tcx.types.self_param => {
524                    if !param_ty { ::core::panicking::panic("assertion failed: param_ty") };assert!(param_ty);
525                    // Restricting `Self` for a single method.
526                    suggest_restriction(
527                        self.tcx, body_id, generics, "`Self`", err, None, projection, trait_pred,
528                        None,
529                    );
530                    return;
531                }
532
533                hir::Node::TraitItem(hir::TraitItem {
534                    generics,
535                    kind: hir::TraitItemKind::Fn(fn_sig, ..),
536                    ..
537                })
538                | hir::Node::ImplItem(hir::ImplItem {
539                    generics,
540                    kind: hir::ImplItemKind::Fn(fn_sig, ..),
541                    ..
542                })
543                | hir::Node::Item(hir::Item {
544                    kind: hir::ItemKind::Fn { sig: fn_sig, generics, .. },
545                    ..
546                }) if projection.is_some() => {
547                    // Missing restriction on associated type of type parameter (unmet projection).
548                    suggest_restriction(
549                        self.tcx,
550                        body_id,
551                        generics,
552                        "the associated type",
553                        err,
554                        Some(fn_sig),
555                        projection,
556                        trait_pred,
557                        None,
558                    );
559                    return;
560                }
561                hir::Node::Item(hir::Item {
562                    kind:
563                        hir::ItemKind::Trait { generics, .. }
564                        | hir::ItemKind::Impl(hir::Impl { generics, .. }),
565                    ..
566                }) if projection.is_some() => {
567                    // Missing restriction on associated type of type parameter (unmet projection).
568                    suggest_restriction(
569                        self.tcx,
570                        body_id,
571                        generics,
572                        "the associated type",
573                        err,
574                        None,
575                        projection,
576                        trait_pred,
577                        None,
578                    );
579                    return;
580                }
581
582                hir::Node::Item(hir::Item {
583                    kind:
584                        hir::ItemKind::Struct(_, generics, _)
585                        | hir::ItemKind::Enum(_, generics, _)
586                        | hir::ItemKind::Union(_, generics, _)
587                        | hir::ItemKind::Trait { generics, .. }
588                        | hir::ItemKind::Impl(hir::Impl { generics, .. })
589                        | hir::ItemKind::Fn { generics, .. }
590                        | hir::ItemKind::TyAlias(_, generics, _)
591                        | hir::ItemKind::Const(_, generics, _, _)
592                        | hir::ItemKind::TraitAlias(_, _, generics, _),
593                    ..
594                })
595                | hir::Node::TraitItem(hir::TraitItem { generics, .. })
596                | hir::Node::ImplItem(hir::ImplItem { generics, .. })
597                    if param_ty =>
598                {
599                    // We skip the 0'th arg (self) because we do not want
600                    // to consider the predicate as not suggestible if the
601                    // self type is an arg position `impl Trait` -- instead,
602                    // we handle that by adding ` + Bound` below.
603                    // FIXME(compiler-errors): It would be nice to do the same
604                    // this that we do in `suggest_restriction` and pull the
605                    // `impl Trait` into a new generic if it shows up somewhere
606                    // else in the predicate.
607                    if !trait_pred.skip_binder().trait_ref.args[1..]
608                        .iter()
609                        .all(|g| g.is_suggestable(self.tcx, false))
610                    {
611                        return;
612                    }
613                    // Missing generic type parameter bound.
614                    let param_name = self_ty.to_string();
615                    let mut constraint = {
    let _guard = NoTrimmedGuard::new();
    trait_pred.print_modifiers_and_trait_path().to_string()
}with_no_trimmed_paths!(
616                        trait_pred.print_modifiers_and_trait_path().to_string()
617                    );
618
619                    if let Some((name, term)) = associated_ty {
620                        // FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
621                        // That should be extracted into a helper function.
622                        if let Some(stripped) = constraint.strip_suffix('>') {
623                            constraint = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}, {1} = {2}>", stripped, name,
                term))
    })format!("{stripped}, {name} = {term}>");
624                        } else {
625                            constraint.push_str(&::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0} = {1}>", name, term))
    })format!("<{name} = {term}>"));
626                        }
627                    }
628
629                    if suggest_constraining_type_param(
630                        self.tcx,
631                        generics,
632                        err,
633                        &param_name,
634                        &constraint,
635                        Some(trait_pred.def_id()),
636                        None,
637                    ) {
638                        return;
639                    }
640                }
641
642                hir::Node::TraitItem(hir::TraitItem {
643                    generics,
644                    kind: hir::TraitItemKind::Fn(..),
645                    ..
646                })
647                | hir::Node::ImplItem(hir::ImplItem {
648                    generics,
649                    impl_kind: hir::ImplItemImplKind::Inherent { .. },
650                    kind: hir::ImplItemKind::Fn(..),
651                    ..
652                }) if finder.can_suggest_bound(generics) => {
653                    // Missing generic type parameter bound.
654                    suggest_arbitrary_trait_bound(
655                        self.tcx,
656                        generics,
657                        err,
658                        trait_pred,
659                        associated_ty,
660                    );
661                }
662                hir::Node::Item(hir::Item {
663                    kind:
664                        hir::ItemKind::Struct(_, generics, _)
665                        | hir::ItemKind::Enum(_, generics, _)
666                        | hir::ItemKind::Union(_, generics, _)
667                        | hir::ItemKind::Trait { generics, .. }
668                        | hir::ItemKind::Impl(hir::Impl { generics, .. })
669                        | hir::ItemKind::Fn { generics, .. }
670                        | hir::ItemKind::TyAlias(_, generics, _)
671                        | hir::ItemKind::Const(_, generics, _, _)
672                        | hir::ItemKind::TraitAlias(_, _, generics, _),
673                    ..
674                }) if finder.can_suggest_bound(generics) => {
675                    // Missing generic type parameter bound.
676                    if suggest_arbitrary_trait_bound(
677                        self.tcx,
678                        generics,
679                        err,
680                        trait_pred,
681                        associated_ty,
682                    ) {
683                        return;
684                    }
685                }
686                hir::Node::Crate(..) => return,
687
688                _ => {}
689            }
690            body_id = self.tcx.local_parent(body_id);
691        }
692    }
693
694    /// Provide a suggestion to dereference arguments to functions and binary operators, if that
695    /// would satisfy trait bounds.
696    pub(super) fn suggest_dereferences(
697        &self,
698        obligation: &PredicateObligation<'tcx>,
699        err: &mut Diag<'_>,
700        trait_pred: ty::PolyTraitPredicate<'tcx>,
701    ) -> bool {
702        let mut code = obligation.cause.code();
703        if let ObligationCauseCode::FunctionArg { arg_hir_id, call_hir_id, .. } = code
704            && let Some(typeck_results) = &self.typeck_results
705            && let hir::Node::Expr(expr) = self.tcx.hir_node(*arg_hir_id)
706            && let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr)
707        {
708            // Suggest dereferencing the argument to a function/method call if possible
709
710            // Get the root obligation, since the leaf obligation we have may be unhelpful (#87437)
711            let mut real_trait_pred = trait_pred;
712            while let Some((parent_code, parent_trait_pred)) = code.parent_with_predicate() {
713                code = parent_code;
714                if let Some(parent_trait_pred) = parent_trait_pred {
715                    real_trait_pred = parent_trait_pred;
716                }
717            }
718
719            // We `instantiate_bound_regions_with_erased` here because `make_subregion` does not handle
720            // `ReBound`, and we don't particularly care about the regions.
721            let real_ty = self.tcx.instantiate_bound_regions_with_erased(real_trait_pred.self_ty());
722            if !self.can_eq(obligation.param_env, real_ty, arg_ty) {
723                return false;
724            }
725
726            // Potentially, we'll want to place our dereferences under a `&`. We don't try this for
727            // `&mut`, since we can't be sure users will get the side-effects they want from it.
728            // If this doesn't work, we'll try removing the `&` in `suggest_remove_reference`.
729            // FIXME(dianne): this misses the case where users need both to deref and remove `&`s.
730            // This method could be combined with `TypeErrCtxt::suggest_remove_reference` to handle
731            // that, similar to what `FnCtxt::suggest_deref_or_ref` does.
732            let (is_under_ref, base_ty, span) = match expr.kind {
733                hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, subexpr)
734                    if let &ty::Ref(region, base_ty, hir::Mutability::Not) = real_ty.kind() =>
735                {
736                    (Some(region), base_ty, subexpr.span)
737                }
738                // Don't suggest `*&mut`, etc.
739                hir::ExprKind::AddrOf(..) => return false,
740                _ => (None, real_ty, obligation.cause.span),
741            };
742
743            let autoderef = (self.autoderef_steps)(base_ty);
744            let mut is_boxed = base_ty.is_box();
745            if let Some(steps) = autoderef.into_iter().position(|(mut ty, obligations)| {
746                // Ensure one of the following for dereferencing to be valid: we're passing by
747                // reference, `ty` is `Copy`, or we're moving out of a (potentially nested) `Box`.
748                let can_deref = is_under_ref.is_some()
749                    || self.type_is_copy_modulo_regions(obligation.param_env, ty)
750                    || ty.is_numeric() // for inference vars (presumably but not provably `Copy`)
751                    || is_boxed && self.type_is_sized_modulo_regions(obligation.param_env, ty);
752                is_boxed &= ty.is_box();
753
754                // Re-add the `&` if necessary
755                if let Some(region) = is_under_ref {
756                    ty = Ty::new_ref(self.tcx, region, ty, hir::Mutability::Not);
757                }
758
759                // Remapping bound vars here
760                let real_trait_pred_and_ty =
761                    real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
762                let obligation = self.mk_trait_obligation_with_new_self_ty(
763                    obligation.param_env,
764                    real_trait_pred_and_ty,
765                );
766
767                can_deref
768                    && obligations
769                        .iter()
770                        .chain([&obligation])
771                        .all(|obligation| self.predicate_may_hold(obligation))
772            }) && steps > 0
773            {
774                if span.in_external_macro(self.tcx.sess.source_map()) {
775                    return false;
776                }
777                let derefs = "*".repeat(steps);
778                let msg = "consider dereferencing here";
779
780                let call_node = self.tcx.hir_node(*call_hir_id);
781                let is_receiver = #[allow(non_exhaustive_omitted_patterns)] match call_node {
    Node::Expr(hir::Expr {
        kind: hir::ExprKind::MethodCall(_, receiver_expr, ..), .. }) if
        receiver_expr.hir_id == *arg_hir_id => true,
    _ => false,
}matches!(
782                    call_node,
783                    Node::Expr(hir::Expr {
784                        kind: hir::ExprKind::MethodCall(_, receiver_expr, ..),
785                        ..
786                    })
787                    if receiver_expr.hir_id == *arg_hir_id
788                );
789                if is_receiver {
790                    err.multipart_suggestion(
791                        msg,
792                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("({0}", derefs))
                        })), (span.shrink_to_hi(), ")".to_string())]))vec![
793                            (span.shrink_to_lo(), format!("({derefs}")),
794                            (span.shrink_to_hi(), ")".to_string()),
795                        ],
796                        Applicability::MachineApplicable,
797                    )
798                } else {
799                    err.span_suggestion_verbose(
800                        span.shrink_to_lo(),
801                        msg,
802                        derefs,
803                        Applicability::MachineApplicable,
804                    )
805                };
806                return true;
807            }
808        } else if let (
809            ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, .. },
810            predicate,
811        ) = code.peel_derives_with_predicate()
812            && let Some(typeck_results) = &self.typeck_results
813            && let hir::Node::Expr(lhs) = self.tcx.hir_node(*lhs_hir_id)
814            && let hir::Node::Expr(rhs) = self.tcx.hir_node(*rhs_hir_id)
815            && let Some(rhs_ty) = typeck_results.expr_ty_opt(rhs)
816            && let trait_pred = predicate.unwrap_or(trait_pred)
817            // Only run this code on binary operators
818            && hir::lang_items::BINARY_OPERATORS
819                .iter()
820                .filter_map(|&op| self.tcx.lang_items().get(op))
821                .any(|op| {
822                    op == trait_pred.skip_binder().trait_ref.def_id
823                })
824        {
825            // Suggest dereferencing the LHS, RHS, or both terms of a binop if possible
826            let trait_pred = predicate.unwrap_or(trait_pred);
827            let lhs_ty = self.tcx.instantiate_bound_regions_with_erased(trait_pred.self_ty());
828            let lhs_autoderef = (self.autoderef_steps)(lhs_ty);
829            let rhs_autoderef = (self.autoderef_steps)(rhs_ty);
830            let first_lhs = lhs_autoderef.first().unwrap().clone();
831            let first_rhs = rhs_autoderef.first().unwrap().clone();
832            let mut autoderefs = lhs_autoderef
833                .into_iter()
834                .enumerate()
835                .rev()
836                .zip_longest(rhs_autoderef.into_iter().enumerate().rev())
837                .map(|t| match t {
838                    EitherOrBoth::Both(a, b) => (a, b),
839                    EitherOrBoth::Left(a) => (a, (0, first_rhs.clone())),
840                    EitherOrBoth::Right(b) => ((0, first_lhs.clone()), b),
841                })
842                .rev();
843            if let Some((lsteps, rsteps)) =
844                autoderefs.find_map(|((lsteps, (l_ty, _)), (rsteps, (r_ty, _)))| {
845                    // Create a new predicate with the dereferenced LHS and RHS
846                    // We simultaneously dereference both sides rather than doing them
847                    // one at a time to account for cases such as &Box<T> == &&T
848                    let trait_pred_and_ty = trait_pred.map_bound(|inner| {
849                        (
850                            ty::TraitPredicate {
851                                trait_ref: ty::TraitRef::new_from_args(
852                                    self.tcx,
853                                    inner.trait_ref.def_id,
854                                    self.tcx.mk_args(
855                                        &[&[l_ty.into(), r_ty.into()], &inner.trait_ref.args[2..]]
856                                            .concat(),
857                                    ),
858                                ),
859                                ..inner
860                            },
861                            l_ty,
862                        )
863                    });
864                    let obligation = self.mk_trait_obligation_with_new_self_ty(
865                        obligation.param_env,
866                        trait_pred_and_ty,
867                    );
868                    self.predicate_may_hold(&obligation).then_some(match (lsteps, rsteps) {
869                        (_, 0) => (Some(lsteps), None),
870                        (0, _) => (None, Some(rsteps)),
871                        _ => (Some(lsteps), Some(rsteps)),
872                    })
873                })
874            {
875                let make_sugg = |mut expr: &Expr<'_>, mut steps| {
876                    if expr.span.in_external_macro(self.tcx.sess.source_map()) {
877                        return None;
878                    }
879                    let mut prefix_span = expr.span.shrink_to_lo();
880                    let mut msg = "consider dereferencing here";
881                    if let hir::ExprKind::AddrOf(_, _, inner) = expr.kind {
882                        msg = "consider removing the borrow and dereferencing instead";
883                        if let hir::ExprKind::AddrOf(..) = inner.kind {
884                            msg = "consider removing the borrows and dereferencing instead";
885                        }
886                    }
887                    while let hir::ExprKind::AddrOf(_, _, inner) = expr.kind
888                        && steps > 0
889                    {
890                        prefix_span = prefix_span.with_hi(inner.span.lo());
891                        expr = inner;
892                        steps -= 1;
893                    }
894                    // Empty suggestions with empty spans ICE with debug assertions
895                    if steps == 0 {
896                        return Some((
897                            msg.trim_end_matches(" and dereferencing instead"),
898                            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(prefix_span, String::new())]))vec![(prefix_span, String::new())],
899                        ));
900                    }
901                    let derefs = "*".repeat(steps);
902                    let needs_parens = steps > 0 && expr_needs_parens(expr);
903                    let mut suggestion = if needs_parens {
904                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(expr.span.with_lo(prefix_span.hi()).shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("{0}(", derefs))
                        })), (expr.span.shrink_to_hi(), ")".to_string())]))vec![
905                            (
906                                expr.span.with_lo(prefix_span.hi()).shrink_to_lo(),
907                                format!("{derefs}("),
908                            ),
909                            (expr.span.shrink_to_hi(), ")".to_string()),
910                        ]
911                    } else {
912                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(expr.span.with_lo(prefix_span.hi()).shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("{0}", derefs))
                        }))]))vec![(
913                            expr.span.with_lo(prefix_span.hi()).shrink_to_lo(),
914                            format!("{derefs}"),
915                        )]
916                    };
917                    // Empty suggestions with empty spans ICE with debug assertions
918                    if !prefix_span.is_empty() {
919                        suggestion.push((prefix_span, String::new()));
920                    }
921                    Some((msg, suggestion))
922                };
923
924                if let Some(lsteps) = lsteps
925                    && let Some(rsteps) = rsteps
926                    && lsteps > 0
927                    && rsteps > 0
928                {
929                    let Some((_, mut suggestion)) = make_sugg(lhs, lsteps) else {
930                        return false;
931                    };
932                    let Some((_, mut rhs_suggestion)) = make_sugg(rhs, rsteps) else {
933                        return false;
934                    };
935                    suggestion.append(&mut rhs_suggestion);
936                    err.multipart_suggestion(
937                        "consider dereferencing both sides of the expression",
938                        suggestion,
939                        Applicability::MachineApplicable,
940                    );
941                    return true;
942                } else if let Some(lsteps) = lsteps
943                    && lsteps > 0
944                {
945                    let Some((msg, suggestion)) = make_sugg(lhs, lsteps) else {
946                        return false;
947                    };
948                    err.multipart_suggestion(msg, suggestion, Applicability::MachineApplicable);
949                    return true;
950                } else if let Some(rsteps) = rsteps
951                    && rsteps > 0
952                {
953                    let Some((msg, suggestion)) = make_sugg(rhs, rsteps) else {
954                        return false;
955                    };
956                    err.multipart_suggestion(msg, suggestion, Applicability::MachineApplicable);
957                    return true;
958                }
959            }
960        }
961        false
962    }
963
964    /// Given a closure's `DefId`, return the given name of the closure.
965    ///
966    /// This doesn't account for reassignments, but it's only used for suggestions.
967    fn get_closure_name(
968        &self,
969        def_id: DefId,
970        err: &mut Diag<'_>,
971        msg: Cow<'static, str>,
972    ) -> Option<Symbol> {
973        let get_name = |err: &mut Diag<'_>, kind: &hir::PatKind<'_>| -> Option<Symbol> {
974            // Get the local name of this closure. This can be inaccurate because
975            // of the possibility of reassignment, but this should be good enough.
976            match &kind {
977                hir::PatKind::Binding(hir::BindingMode::NONE, _, ident, None) => Some(ident.name),
978                _ => {
979                    err.note(msg);
980                    None
981                }
982            }
983        };
984
985        let hir_id = self.tcx.local_def_id_to_hir_id(def_id.as_local()?);
986        match self.tcx.parent_hir_node(hir_id) {
987            hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Let(local), .. }) => {
988                get_name(err, &local.pat.kind)
989            }
990            // Different to previous arm because one is `&hir::Local` and the other
991            // is `Box<hir::Local>`.
992            hir::Node::LetStmt(local) => get_name(err, &local.pat.kind),
993            _ => None,
994        }
995    }
996
997    /// We tried to apply the bound to an `fn` or closure. Check whether calling it would
998    /// evaluate to a type that *would* satisfy the trait bound. If it would, suggest calling
999    /// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
1000    pub(super) fn suggest_fn_call(
1001        &self,
1002        obligation: &PredicateObligation<'tcx>,
1003        err: &mut Diag<'_>,
1004        trait_pred: ty::PolyTraitPredicate<'tcx>,
1005    ) -> bool {
1006        // It doesn't make sense to make this suggestion outside of typeck...
1007        // (also autoderef will ICE...)
1008        if self.typeck_results.is_none() {
1009            return false;
1010        }
1011
1012        if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) =
1013            obligation.predicate.kind().skip_binder()
1014            && self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized)
1015        {
1016            // Don't suggest calling to turn an unsized type into a sized type
1017            return false;
1018        }
1019
1020        let self_ty = self.instantiate_binder_with_fresh_vars(
1021            DUMMY_SP,
1022            BoundRegionConversionTime::FnCall,
1023            trait_pred.self_ty(),
1024        );
1025
1026        let Some((def_id_or_name, output, inputs)) =
1027            self.extract_callable_info(obligation.cause.body_id, obligation.param_env, self_ty)
1028        else {
1029            return false;
1030        };
1031
1032        // Remapping bound vars here
1033        let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output));
1034
1035        let new_obligation =
1036            self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self);
1037        if !self.predicate_must_hold_modulo_regions(&new_obligation) {
1038            return false;
1039        }
1040
1041        // If this is a zero-argument async closure directly passed as an argument
1042        // and the expected type is `Future`, suggest using `async {}` block instead
1043        // of `async || {}`
1044        if let ty::CoroutineClosure(def_id, args) = *self_ty.kind()
1045            && let sig = args.as_coroutine_closure().coroutine_closure_sig().skip_binder()
1046            && let ty::Tuple(inputs) = *sig.tupled_inputs_ty.kind()
1047            && inputs.is_empty()
1048            && self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Future)
1049            && let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code()
1050            && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) =
1051                self.tcx.hir_node(*arg_hir_id)
1052            && let Some(hir::Node::Expr(hir::Expr {
1053                kind: hir::ExprKind::Closure(closure), ..
1054            })) = self.tcx.hir_get_if_local(def_id)
1055            && let hir::ClosureKind::CoroutineClosure(CoroutineDesugaring::Async) = closure.kind
1056            && let Some(arg_span) = closure.fn_arg_span
1057            && obligation.cause.span.contains(arg_span)
1058        {
1059            let mut body = self.tcx.hir_body(closure.body).value;
1060            let peeled = body.peel_blocks().peel_drop_temps();
1061            if let hir::ExprKind::Closure(inner) = peeled.kind {
1062                body = self.tcx.hir_body(inner.body).value;
1063            }
1064            if !#[allow(non_exhaustive_omitted_patterns)] match body.peel_blocks().peel_drop_temps().kind
    {
    hir::ExprKind::Block(..) => true,
    _ => false,
}matches!(body.peel_blocks().peel_drop_temps().kind, hir::ExprKind::Block(..)) {
1065                return false;
1066            }
1067
1068            let sm = self.tcx.sess.source_map();
1069            let removal_span = if let Ok(snippet) =
1070                sm.span_to_snippet(arg_span.with_hi(arg_span.hi() + rustc_span::BytePos(1)))
1071                && snippet.ends_with(' ')
1072            {
1073                // There's a space after `||`, include it in the removal
1074                arg_span.with_hi(arg_span.hi() + rustc_span::BytePos(1))
1075            } else {
1076                arg_span
1077            };
1078            err.span_suggestion_verbose(
1079                removal_span,
1080                "use `async {}` instead of `async || {}` to introduce an async block",
1081                "",
1082                Applicability::MachineApplicable,
1083            );
1084            return true;
1085        }
1086
1087        // Get the name of the callable and the arguments to be used in the suggestion.
1088        let msg = match def_id_or_name {
1089            DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
1090                DefKind::Ctor(CtorOf::Struct, _) => {
1091                    Cow::from("use parentheses to construct this tuple struct")
1092                }
1093                DefKind::Ctor(CtorOf::Variant, _) => {
1094                    Cow::from("use parentheses to construct this tuple variant")
1095                }
1096                kind => Cow::from(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("use parentheses to call this {0}",
                self.tcx.def_kind_descr(kind, def_id)))
    })format!(
1097                    "use parentheses to call this {}",
1098                    self.tcx.def_kind_descr(kind, def_id)
1099                )),
1100            },
1101            DefIdOrName::Name(name) => Cow::from(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("use parentheses to call this {0}",
                name))
    })format!("use parentheses to call this {name}")),
1102        };
1103
1104        let args = inputs
1105            .into_iter()
1106            .map(|ty| {
1107                if ty.is_suggestable(self.tcx, false) {
1108                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("/* {0} */", ty))
    })format!("/* {ty} */")
1109                } else {
1110                    "/* value */".to_string()
1111                }
1112            })
1113            .collect::<Vec<_>>()
1114            .join(", ");
1115
1116        if let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code()
1117            && obligation.cause.span.can_be_used_for_suggestions()
1118        {
1119            let span = obligation.cause.span;
1120
1121            let arg_expr = match self.tcx.hir_node(*arg_hir_id) {
1122                hir::Node::Expr(expr) => Some(expr),
1123                _ => None,
1124            };
1125
1126            let is_closure_expr =
1127                arg_expr.is_some_and(|expr| #[allow(non_exhaustive_omitted_patterns)] match expr.kind {
    hir::ExprKind::Closure(..) => true,
    _ => false,
}matches!(expr.kind, hir::ExprKind::Closure(..)));
1128
1129            // If the user wrote `|| {}()`, suggesting to call the closure would produce `(|| {}())()`,
1130            // which doesn't help and is often outright wrong.
1131            if args.is_empty()
1132                && let Some(expr) = arg_expr
1133                && let hir::ExprKind::Closure(closure) = expr.kind
1134            {
1135                let mut body = self.tcx.hir_body(closure.body).value;
1136
1137                // Async closures desugar to a closure returning a coroutine
1138                if let hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) =
1139                    closure.kind
1140                {
1141                    let peeled = body.peel_blocks().peel_drop_temps();
1142                    if let hir::ExprKind::Closure(inner) = peeled.kind {
1143                        body = self.tcx.hir_body(inner.body).value;
1144                    }
1145                }
1146
1147                let peeled_body = body.peel_blocks().peel_drop_temps();
1148                if let hir::ExprKind::Call(callee, call_args) = peeled_body.kind
1149                    && call_args.is_empty()
1150                    && let hir::ExprKind::Block(..) = callee.peel_blocks().peel_drop_temps().kind
1151                {
1152                    return false;
1153                }
1154            }
1155
1156            if is_closure_expr {
1157                err.multipart_suggestions(
1158                    msg,
1159                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                        [(span.shrink_to_lo(), "(".to_string()),
                                (span.shrink_to_hi(),
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!(")({0})", args))
                                        }))]))]))vec![vec![
1160                        (span.shrink_to_lo(), "(".to_string()),
1161                        (span.shrink_to_hi(), format!(")({args})")),
1162                    ]],
1163                    Applicability::HasPlaceholders,
1164                );
1165            } else {
1166                err.span_suggestion_verbose(
1167                    span.shrink_to_hi(),
1168                    msg,
1169                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("({0})", args))
    })format!("({args})"),
1170                    Applicability::HasPlaceholders,
1171                );
1172            }
1173        } else if let DefIdOrName::DefId(def_id) = def_id_or_name {
1174            let name = match self.tcx.hir_get_if_local(def_id) {
1175                Some(hir::Node::Expr(hir::Expr {
1176                    kind: hir::ExprKind::Closure(hir::Closure { fn_decl_span, .. }),
1177                    ..
1178                })) => {
1179                    err.span_label(*fn_decl_span, "consider calling this closure");
1180                    let Some(name) = self.get_closure_name(def_id, err, msg.clone()) else {
1181                        return false;
1182                    };
1183                    name.to_string()
1184                }
1185                Some(hir::Node::Item(hir::Item {
1186                    kind: hir::ItemKind::Fn { ident, .. }, ..
1187                })) => {
1188                    err.span_label(ident.span, "consider calling this function");
1189                    ident.to_string()
1190                }
1191                Some(hir::Node::Ctor(..)) => {
1192                    let name = self.tcx.def_path_str(def_id);
1193                    err.span_label(
1194                        self.tcx.def_span(def_id),
1195                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider calling the constructor for `{0}`",
                name))
    })format!("consider calling the constructor for `{name}`"),
1196                    );
1197                    name
1198                }
1199                _ => return false,
1200            };
1201            err.help(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}: `{1}({2})`", msg, name, args))
    })format!("{msg}: `{name}({args})`"));
1202        }
1203        true
1204    }
1205
1206    pub(super) fn suggest_cast_to_fn_pointer(
1207        &self,
1208        obligation: &PredicateObligation<'tcx>,
1209        err: &mut Diag<'_>,
1210        leaf_trait_predicate: ty::PolyTraitPredicate<'tcx>,
1211        main_trait_predicate: ty::PolyTraitPredicate<'tcx>,
1212        span: Span,
1213    ) -> bool {
1214        let &[candidate] = &self.find_similar_impl_candidates(leaf_trait_predicate)[..] else {
1215            return false;
1216        };
1217        let candidate = candidate.trait_ref;
1218
1219        if !#[allow(non_exhaustive_omitted_patterns)] match (candidate.self_ty().kind(),
        main_trait_predicate.self_ty().skip_binder().kind()) {
    (ty::FnPtr(..), ty::FnDef(..)) => true,
    _ => false,
}matches!(
1220            (candidate.self_ty().kind(), main_trait_predicate.self_ty().skip_binder().kind(),),
1221            (ty::FnPtr(..), ty::FnDef(..))
1222        ) {
1223            return false;
1224        }
1225
1226        let parenthesized_cast = |span: Span| {
1227            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(), "(".to_string()),
                (span.shrink_to_hi(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(" as {0})",
                                    candidate.self_ty()))
                        }))]))vec![
1228                (span.shrink_to_lo(), "(".to_string()),
1229                (span.shrink_to_hi(), format!(" as {})", candidate.self_ty())),
1230            ]
1231        };
1232        // Wrap method receivers and `&`-references in parens.
1233        let suggestion = if self.tcx.sess.source_map().span_followed_by(span, ".").is_some() {
1234            parenthesized_cast(span)
1235        } else if let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) {
1236            let mut expr_finder = FindExprBySpan::new(span, self.tcx);
1237            expr_finder.visit_expr(body.value);
1238            if let Some(expr) = expr_finder.result
1239                && let hir::ExprKind::AddrOf(_, _, expr) = expr.kind
1240            {
1241                parenthesized_cast(expr.span)
1242            } else {
1243                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_hi(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(" as {0}",
                                    candidate.self_ty()))
                        }))]))vec![(span.shrink_to_hi(), format!(" as {}", candidate.self_ty()))]
1244            }
1245        } else {
1246            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_hi(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(" as {0}",
                                    candidate.self_ty()))
                        }))]))vec![(span.shrink_to_hi(), format!(" as {}", candidate.self_ty()))]
1247        };
1248
1249        let trait_ = self.tcx.short_string(candidate.print_trait_sugared(), err.long_ty_path());
1250        let self_ty = self.tcx.short_string(candidate.self_ty(), err.long_ty_path());
1251        err.multipart_suggestion(
1252            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the trait `{0}` is implemented for fn pointer `{1}`, try casting using `as`",
                trait_, self_ty))
    })format!(
1253                "the trait `{trait_}` is implemented for fn pointer \
1254                 `{self_ty}`, try casting using `as`",
1255            ),
1256            suggestion,
1257            Applicability::MaybeIncorrect,
1258        );
1259        true
1260    }
1261
1262    pub(super) fn check_for_binding_assigned_block_without_tail_expression(
1263        &self,
1264        obligation: &PredicateObligation<'tcx>,
1265        err: &mut Diag<'_>,
1266        trait_pred: ty::PolyTraitPredicate<'tcx>,
1267    ) {
1268        let mut span = obligation.cause.span;
1269        while span.from_expansion() {
1270            // Remove all the desugaring and macro contexts.
1271            span.remove_mark();
1272        }
1273        let mut expr_finder = FindExprBySpan::new(span, self.tcx);
1274        let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else {
1275            return;
1276        };
1277        expr_finder.visit_expr(body.value);
1278        let Some(expr) = expr_finder.result else {
1279            return;
1280        };
1281        let Some(typeck) = &self.typeck_results else {
1282            return;
1283        };
1284        let Some(ty) = typeck.expr_ty_adjusted_opt(expr) else {
1285            return;
1286        };
1287        if !ty.is_unit() {
1288            return;
1289        };
1290        let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind else {
1291            return;
1292        };
1293        let Res::Local(hir_id) = path.res else {
1294            return;
1295        };
1296        let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
1297            return;
1298        };
1299        let hir::Node::LetStmt(hir::LetStmt { ty: None, init: Some(init), .. }) =
1300            self.tcx.parent_hir_node(pat.hir_id)
1301        else {
1302            return;
1303        };
1304        let hir::ExprKind::Block(block, None) = init.kind else {
1305            return;
1306        };
1307        if block.expr.is_some() {
1308            return;
1309        }
1310        let [.., stmt] = block.stmts else {
1311            err.span_label(block.span, "this empty block is missing a tail expression");
1312            return;
1313        };
1314        // FIXME expr and stmt have the same span if expr comes from expansion
1315        // cc: https://github.com/rust-lang/rust/pull/147416#discussion_r2499407523
1316        if stmt.span.from_expansion() {
1317            return;
1318        }
1319        let hir::StmtKind::Semi(tail_expr) = stmt.kind else {
1320            return;
1321        };
1322        let Some(ty) = typeck.expr_ty_opt(tail_expr) else {
1323            err.span_label(block.span, "this block is missing a tail expression");
1324            return;
1325        };
1326        let ty = self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(ty));
1327        let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, ty));
1328
1329        let new_obligation =
1330            self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self);
1331        if !#[allow(non_exhaustive_omitted_patterns)] match tail_expr.kind {
    hir::ExprKind::Err(_) => true,
    _ => false,
}matches!(tail_expr.kind, hir::ExprKind::Err(_))
1332            && self.predicate_must_hold_modulo_regions(&new_obligation)
1333        {
1334            err.span_suggestion_short(
1335                stmt.span.with_lo(tail_expr.span.hi()),
1336                "remove this semicolon",
1337                "",
1338                Applicability::MachineApplicable,
1339            );
1340        } else {
1341            err.span_label(block.span, "this block is missing a tail expression");
1342        }
1343    }
1344
1345    pub(super) fn suggest_add_clone_to_arg(
1346        &self,
1347        obligation: &PredicateObligation<'tcx>,
1348        err: &mut Diag<'_>,
1349        trait_pred: ty::PolyTraitPredicate<'tcx>,
1350    ) -> bool {
1351        let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
1352        self.enter_forall(self_ty, |ty: Ty<'_>| {
1353            let Some(generics) = self.tcx.hir_get_generics(obligation.cause.body_id) else {
1354                return false;
1355            };
1356            let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false };
1357            let ty::Param(param) = inner_ty.kind() else { return false };
1358            let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code()
1359            else {
1360                return false;
1361            };
1362
1363            let clone_trait = self.tcx.require_lang_item(LangItem::Clone, obligation.cause.span);
1364            let has_clone = |ty| {
1365                self.type_implements_trait(clone_trait, [ty], obligation.param_env)
1366                    .must_apply_modulo_regions()
1367            };
1368
1369            let existing_clone_call = match self.tcx.hir_node(*arg_hir_id) {
1370                // It's just a variable. Propose cloning it.
1371                Node::Expr(Expr { kind: hir::ExprKind::Path(_), .. }) => None,
1372                // It's already a call to `clone()`. We might be able to suggest
1373                // adding a `+ Clone` bound, though.
1374                Node::Expr(Expr {
1375                    kind:
1376                        hir::ExprKind::MethodCall(
1377                            hir::PathSegment { ident, .. },
1378                            _receiver,
1379                            [],
1380                            call_span,
1381                        ),
1382                    hir_id,
1383                    ..
1384                }) if ident.name == sym::clone
1385                    && !call_span.from_expansion()
1386                    && !has_clone(*inner_ty) =>
1387                {
1388                    // We only care about method calls corresponding to the real `Clone` trait.
1389                    let Some(typeck_results) = self.typeck_results.as_ref() else { return false };
1390                    let Some((DefKind::AssocFn, did)) = typeck_results.type_dependent_def(*hir_id)
1391                    else {
1392                        return false;
1393                    };
1394                    if self.tcx.trait_of_assoc(did) != Some(clone_trait) {
1395                        return false;
1396                    }
1397                    Some(ident.span)
1398                }
1399                _ => return false,
1400            };
1401
1402            let new_obligation = self.mk_trait_obligation_with_new_self_ty(
1403                obligation.param_env,
1404                trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)),
1405            );
1406
1407            if self.predicate_may_hold(&new_obligation) && has_clone(ty) {
1408                if !has_clone(param.to_ty(self.tcx)) {
1409                    suggest_constraining_type_param(
1410                        self.tcx,
1411                        generics,
1412                        err,
1413                        param.name.as_str(),
1414                        "Clone",
1415                        Some(clone_trait),
1416                        None,
1417                    );
1418                }
1419                if let Some(existing_clone_call) = existing_clone_call {
1420                    err.span_note(
1421                        existing_clone_call,
1422                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this `clone()` copies the reference, which does not do anything, because `{0}` does not implement `Clone`",
                inner_ty))
    })format!(
1423                            "this `clone()` copies the reference, \
1424                            which does not do anything, \
1425                            because `{inner_ty}` does not implement `Clone`"
1426                        ),
1427                    );
1428                } else {
1429                    err.span_suggestion_verbose(
1430                        obligation.cause.span.shrink_to_hi(),
1431                        "consider using clone here",
1432                        ".clone()".to_string(),
1433                        Applicability::MaybeIncorrect,
1434                    );
1435                }
1436                return true;
1437            }
1438            false
1439        })
1440    }
1441
1442    /// Extracts information about a callable type for diagnostics. This is a
1443    /// heuristic -- it doesn't necessarily mean that a type is always callable,
1444    /// because the callable type must also be well-formed to be called.
1445    pub fn extract_callable_info(
1446        &self,
1447        body_id: LocalDefId,
1448        param_env: ty::ParamEnv<'tcx>,
1449        found: Ty<'tcx>,
1450    ) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
1451        // Autoderef is useful here because sometimes we box callables, etc.
1452        let Some((def_id_or_name, output, inputs)) =
1453            (self.autoderef_steps)(found).into_iter().find_map(|(found, _)| match *found.kind() {
1454                ty::FnPtr(sig_tys, _) => Some((
1455                    DefIdOrName::Name("function pointer"),
1456                    sig_tys.output(),
1457                    sig_tys.inputs(),
1458                )),
1459                ty::FnDef(def_id, _) => {
1460                    let fn_sig = found.fn_sig(self.tcx);
1461                    Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
1462                }
1463                ty::Closure(def_id, args) => {
1464                    let fn_sig = args.as_closure().sig();
1465                    Some((
1466                        DefIdOrName::DefId(def_id),
1467                        fn_sig.output(),
1468                        fn_sig.inputs().map_bound(|inputs| inputs[0].tuple_fields().as_slice()),
1469                    ))
1470                }
1471                ty::CoroutineClosure(def_id, args) => {
1472                    let sig_parts = args.as_coroutine_closure().coroutine_closure_sig();
1473                    Some((
1474                        DefIdOrName::DefId(def_id),
1475                        sig_parts.map_bound(|sig| {
1476                            sig.to_coroutine(
1477                                self.tcx,
1478                                args.as_coroutine_closure().parent_args(),
1479                                // Just use infer vars here, since we  don't really care
1480                                // what these types are, just that we're returning a coroutine.
1481                                self.next_ty_var(DUMMY_SP),
1482                                self.tcx.coroutine_for_closure(def_id),
1483                                self.next_ty_var(DUMMY_SP),
1484                            )
1485                        }),
1486                        sig_parts.map_bound(|sig| sig.tupled_inputs_ty.tuple_fields().as_slice()),
1487                    ))
1488                }
1489                ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
1490                    self.tcx
1491                        .item_self_bounds(def_id)
1492                        .instantiate(self.tcx, args)
1493                        .skip_norm_wip()
1494                        .iter()
1495                        .find_map(|pred| {
1496                            if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
1497                            && self
1498                                .tcx
1499                                .is_lang_item(proj.def_id(), LangItem::FnOnceOutput)
1500                            // args tuple will always be args[1]
1501                            && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
1502                            {
1503                                Some((
1504                                    DefIdOrName::DefId(def_id),
1505                                    pred.kind().rebind(proj.term.expect_type()),
1506                                    pred.kind().rebind(args.as_slice()),
1507                                ))
1508                            } else {
1509                                None
1510                            }
1511                        })
1512                }
1513                ty::Dynamic(data, _) => data.iter().find_map(|pred| {
1514                    if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
1515                        && self.tcx.is_lang_item(proj.def_id, LangItem::FnOnceOutput)
1516                        // for existential projection, args are shifted over by 1
1517                        && let ty::Tuple(args) = proj.args.type_at(0).kind()
1518                    {
1519                        Some((
1520                            DefIdOrName::Name("trait object"),
1521                            pred.rebind(proj.term.expect_type()),
1522                            pred.rebind(args.as_slice()),
1523                        ))
1524                    } else {
1525                        None
1526                    }
1527                }),
1528                ty::Param(param) => {
1529                    let generics = self.tcx.generics_of(body_id);
1530                    let name = if generics.count() > param.index as usize
1531                        && let def = generics.param_at(param.index as usize, self.tcx)
1532                        && #[allow(non_exhaustive_omitted_patterns)] match def.kind {
    ty::GenericParamDefKind::Type { .. } => true,
    _ => false,
}matches!(def.kind, ty::GenericParamDefKind::Type { .. })
1533                        && def.name == param.name
1534                    {
1535                        DefIdOrName::DefId(def.def_id)
1536                    } else {
1537                        DefIdOrName::Name("type parameter")
1538                    };
1539                    param_env.caller_bounds().iter().find_map(|pred| {
1540                        if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
1541                            && self
1542                                .tcx
1543                                .is_lang_item(proj.def_id(), LangItem::FnOnceOutput)
1544                            && proj.projection_term.self_ty() == found
1545                            // args tuple will always be args[1]
1546                            && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
1547                        {
1548                            Some((
1549                                name,
1550                                pred.kind().rebind(proj.term.expect_type()),
1551                                pred.kind().rebind(args.as_slice()),
1552                            ))
1553                        } else {
1554                            None
1555                        }
1556                    })
1557                }
1558                _ => None,
1559            })
1560        else {
1561            return None;
1562        };
1563
1564        let output = self.instantiate_binder_with_fresh_vars(
1565            DUMMY_SP,
1566            BoundRegionConversionTime::FnCall,
1567            output,
1568        );
1569        let inputs = inputs
1570            .skip_binder()
1571            .iter()
1572            .map(|ty| {
1573                self.instantiate_binder_with_fresh_vars(
1574                    DUMMY_SP,
1575                    BoundRegionConversionTime::FnCall,
1576                    inputs.rebind(*ty),
1577                )
1578            })
1579            .collect();
1580
1581        // We don't want to register any extra obligations, which should be
1582        // implied by wf, but also because that would possibly result in
1583        // erroneous errors later on.
1584        let InferOk { value: output, obligations: _ } =
1585            self.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(output));
1586
1587        if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) }
1588    }
1589
1590    pub(super) fn where_clause_expr_matches_failed_self_ty(
1591        &self,
1592        obligation: &PredicateObligation<'tcx>,
1593        old_self_ty: Ty<'tcx>,
1594    ) -> bool {
1595        let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() else {
1596            return true;
1597        };
1598        let (Some(typeck_results), Some(body)) = (
1599            self.typeck_results.as_ref(),
1600            self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id),
1601        ) else {
1602            return true;
1603        };
1604
1605        let mut expr_finder = FindExprBySpan::new(obligation.cause.span, self.tcx);
1606        expr_finder.visit_expr(body.value);
1607        let Some(expr) = expr_finder.result else {
1608            return true;
1609        };
1610
1611        let inner_old_self_ty = match old_self_ty.kind() {
1612            ty::Ref(_, inner_ty, _) => Some(*inner_ty),
1613            _ => None,
1614        };
1615
1616        typeck_results.expr_ty_adjusted_opt(expr).is_some_and(|expr_ty| {
1617            self.can_eq(obligation.param_env, expr_ty, old_self_ty)
1618                || inner_old_self_ty
1619                    .is_some_and(|inner_ty| self.can_eq(obligation.param_env, expr_ty, inner_ty))
1620        })
1621    }
1622
1623    pub(super) fn suggest_add_reference_to_arg(
1624        &self,
1625        obligation: &PredicateObligation<'tcx>,
1626        err: &mut Diag<'_>,
1627        poly_trait_pred: ty::PolyTraitPredicate<'tcx>,
1628        has_custom_message: bool,
1629    ) -> bool {
1630        let span = obligation.cause.span;
1631        let param_env = obligation.param_env;
1632
1633        let mk_result = |trait_pred_and_new_ty| {
1634            let obligation =
1635                self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
1636            self.predicate_must_hold_modulo_regions(&obligation)
1637        };
1638
1639        let code = match obligation.cause.code() {
1640            ObligationCauseCode::FunctionArg { parent_code, .. } => parent_code,
1641            // FIXME(compiler-errors): This is kind of a mess, but required for obligations
1642            // that come from a path expr to affect the *call* expr.
1643            c @ ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, _)
1644                if self.tcx.hir_span(*hir_id).lo() == span.lo() =>
1645            {
1646                // `hir_id` corresponds to the HIR node that introduced a `where`-clause obligation.
1647                // If that obligation comes from a type in an associated method call, we need
1648                // special handling here.
1649                if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(*hir_id)
1650                    && let hir::ExprKind::Call(base, _) = expr.kind
1651                    && let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, segment)) = base.kind
1652                    && let hir::Node::Expr(outer) = self.tcx.parent_hir_node(expr.hir_id)
1653                    && let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mtbl, _) = outer.kind
1654                    && ty.span == span
1655                {
1656                    // We've encountered something like `&str::from("")`, where the intended code
1657                    // was likely `<&str>::from("")`. The former is interpreted as "call method
1658                    // `from` on `str` and borrow the result", while the latter means "call method
1659                    // `from` on `&str`".
1660
1661                    let trait_pred_and_imm_ref = poly_trait_pred.map_bound(|p| {
1662                        (p, Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, p.self_ty()))
1663                    });
1664                    let trait_pred_and_mut_ref = poly_trait_pred.map_bound(|p| {
1665                        (p, Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_static, p.self_ty()))
1666                    });
1667
1668                    let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref);
1669                    let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
1670                    let sugg_msg = |pre: &str| {
1671                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("you likely meant to call the associated function `{0}` for type `&{2}{1}`, but the code as written calls associated function `{0}` on type `{1}`",
                segment.ident, poly_trait_pred.self_ty(), pre))
    })format!(
1672                            "you likely meant to call the associated function `{FN}` for type \
1673                             `&{pre}{TY}`, but the code as written calls associated function `{FN}` on \
1674                             type `{TY}`",
1675                            FN = segment.ident,
1676                            TY = poly_trait_pred.self_ty(),
1677                        )
1678                    };
1679                    match (imm_ref_self_ty_satisfies_pred, mut_ref_self_ty_satisfies_pred, mtbl) {
1680                        (true, _, hir::Mutability::Not) | (_, true, hir::Mutability::Mut) => {
1681                            err.multipart_suggestion(
1682                                sugg_msg(mtbl.prefix_str()),
1683                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(outer.span.shrink_to_lo(), "<".to_string()),
                (span.shrink_to_hi(), ">".to_string())]))vec![
1684                                    (outer.span.shrink_to_lo(), "<".to_string()),
1685                                    (span.shrink_to_hi(), ">".to_string()),
1686                                ],
1687                                Applicability::MachineApplicable,
1688                            );
1689                        }
1690                        (true, _, hir::Mutability::Mut) => {
1691                            // There's an associated function found on the immutable borrow of the
1692                            err.multipart_suggestion(
1693                                sugg_msg("mut "),
1694                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(outer.span.shrink_to_lo().until(span), "<&".to_string()),
                (span.shrink_to_hi(), ">".to_string())]))vec![
1695                                    (outer.span.shrink_to_lo().until(span), "<&".to_string()),
1696                                    (span.shrink_to_hi(), ">".to_string()),
1697                                ],
1698                                Applicability::MachineApplicable,
1699                            );
1700                        }
1701                        (_, true, hir::Mutability::Not) => {
1702                            err.multipart_suggestion(
1703                                sugg_msg(""),
1704                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(outer.span.shrink_to_lo().until(span), "<&mut ".to_string()),
                (span.shrink_to_hi(), ">".to_string())]))vec![
1705                                    (outer.span.shrink_to_lo().until(span), "<&mut ".to_string()),
1706                                    (span.shrink_to_hi(), ">".to_string()),
1707                                ],
1708                                Applicability::MachineApplicable,
1709                            );
1710                        }
1711                        _ => {}
1712                    }
1713                    // If we didn't return early here, we would instead suggest `&&str::from("")`.
1714                    return false;
1715                }
1716                c
1717            }
1718            c if #[allow(non_exhaustive_omitted_patterns)] match span.ctxt().outer_expn_data().kind
    {
    ExpnKind::Desugaring(DesugaringKind::ForLoop) => true,
    _ => false,
}matches!(
1719                span.ctxt().outer_expn_data().kind,
1720                ExpnKind::Desugaring(DesugaringKind::ForLoop)
1721            ) =>
1722            {
1723                c
1724            }
1725            _ => return false,
1726        };
1727
1728        // List of traits for which it would be nonsensical to suggest borrowing.
1729        // For instance, immutable references are always Copy, so suggesting to
1730        // borrow would always succeed, but it's probably not what the user wanted.
1731        let mut never_suggest_borrow: Vec<_> =
1732            [LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized]
1733                .iter()
1734                .filter_map(|lang_item| self.tcx.lang_items().get(*lang_item))
1735                .collect();
1736
1737        if let Some(def_id) = self.tcx.get_diagnostic_item(sym::Send) {
1738            never_suggest_borrow.push(def_id);
1739        }
1740
1741        // Try to apply the original trait bound by borrowing.
1742        let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
1743                                 blacklist: &[DefId]|
1744         -> bool {
1745            if blacklist.contains(&old_pred.def_id()) {
1746                return false;
1747            }
1748            // We map bounds to `&T` and `&mut T`
1749            let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| {
1750                (
1751                    trait_pred,
1752                    Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, trait_pred.self_ty()),
1753                )
1754            });
1755            let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| {
1756                (
1757                    trait_pred,
1758                    Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_static, trait_pred.self_ty()),
1759                )
1760            });
1761
1762            let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref);
1763            let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
1764
1765            let (ref_inner_ty_satisfies_pred, ref_inner_ty_is_mut) =
1766                if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code()
1767                    && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind()
1768                {
1769                    (
1770                        mk_result(old_pred.map_bound(|trait_pred| (trait_pred, *ty))),
1771                        mutability.is_mut(),
1772                    )
1773                } else {
1774                    (false, false)
1775                };
1776
1777            let is_immut = imm_ref_self_ty_satisfies_pred
1778                || (ref_inner_ty_satisfies_pred && !ref_inner_ty_is_mut);
1779            let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_is_mut;
1780            if !is_immut && !is_mut {
1781                return false;
1782            }
1783            let Ok(_snippet) = self.tcx.sess.source_map().span_to_snippet(span) else {
1784                return false;
1785            };
1786            // We don't want a borrowing suggestion on the fields in structs
1787            // ```
1788            // #[derive(Clone)]
1789            // struct Foo {
1790            //     the_foos: Vec<Foo>
1791            // }
1792            // ```
1793            if !#[allow(non_exhaustive_omitted_patterns)] match span.ctxt().outer_expn_data().kind
    {
    ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => true,
    _ => false,
}matches!(
1794                span.ctxt().outer_expn_data().kind,
1795                ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
1796            ) {
1797                return false;
1798            }
1799            // We have a very specific type of error, where just borrowing this argument
1800            // might solve the problem. In cases like this, the important part is the
1801            // original type obligation, not the last one that failed, which is arbitrary.
1802            // Because of this, we modify the error to refer to the original obligation and
1803            // return early in the caller.
1804
1805            let mut label = || {
1806                // Special case `Sized` as `old_pred` will be the trait itself instead of
1807                // `Sized` when the trait bound is the source of the error.
1808                let is_sized = match obligation.predicate.kind().skip_binder() {
1809                    ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
1810                        self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized)
1811                    }
1812                    _ => false,
1813                };
1814
1815                let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the trait bound `{0}` is not satisfied",
                self.tcx.short_string(old_pred, err.long_ty_path())))
    })format!(
1816                    "the trait bound `{}` is not satisfied",
1817                    self.tcx.short_string(old_pred, err.long_ty_path()),
1818                );
1819                let self_ty_str = self.tcx.short_string(old_pred.self_ty(), err.long_ty_path());
1820                let trait_path = self
1821                    .tcx
1822                    .short_string(old_pred.print_modifiers_and_trait_path(), err.long_ty_path());
1823
1824                if has_custom_message {
1825                    let msg = if is_sized {
1826                        "the trait bound `Sized` is not satisfied".into()
1827                    } else {
1828                        msg
1829                    };
1830                    err.note(msg);
1831                } else {
1832                    err.messages = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]))vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)];
1833                }
1834                if is_sized {
1835                    err.span_label(
1836                        span,
1837                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the trait `Sized` is not implemented for `{0}`",
                self_ty_str))
    })format!("the trait `Sized` is not implemented for `{self_ty_str}`"),
1838                    );
1839                } else {
1840                    err.span_label(
1841                        span,
1842                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the trait `{0}` is not implemented for `{1}`",
                trait_path, self_ty_str))
    })format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"),
1843                    );
1844                }
1845            };
1846
1847            let mut sugg_prefixes = ::alloc::vec::Vec::new()vec![];
1848            if is_immut {
1849                sugg_prefixes.push("&");
1850            }
1851            if is_mut {
1852                sugg_prefixes.push("&mut ");
1853            }
1854            let sugg_msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider{0} borrowing here",
                if is_mut && !is_immut { " mutably" } else { "" }))
    })format!(
1855                "consider{} borrowing here",
1856                if is_mut && !is_immut { " mutably" } else { "" },
1857            );
1858
1859            // Issue #104961, we need to add parentheses properly for compound expressions
1860            // for example, `x.starts_with("hi".to_string() + "you")`
1861            // should be `x.starts_with(&("hi".to_string() + "you"))`
1862            let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else {
1863                return false;
1864            };
1865            let mut expr_finder = FindExprBySpan::new(span, self.tcx);
1866            expr_finder.visit_expr(body.value);
1867
1868            if let Some(ty) = expr_finder.ty_result {
1869                if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(ty.hir_id)
1870                    && let hir::ExprKind::Path(hir::QPath::TypeRelative(_, _)) = expr.kind
1871                    && ty.span == span
1872                {
1873                    // We've encountered something like `str::from("")`, where the intended code
1874                    // was likely `<&str>::from("")`. #143393.
1875                    label();
1876                    err.multipart_suggestions(
1877                        sugg_msg,
1878                        sugg_prefixes.into_iter().map(|sugg_prefix| {
1879                            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("<{0}", sugg_prefix))
                        })), (span.shrink_to_hi(), ">".to_string())]))vec![
1880                                (span.shrink_to_lo(), format!("<{sugg_prefix}")),
1881                                (span.shrink_to_hi(), ">".to_string()),
1882                            ]
1883                        }),
1884                        Applicability::MaybeIncorrect,
1885                    );
1886                    return true;
1887                }
1888                return false;
1889            }
1890            let Some(expr) = expr_finder.result else {
1891                return false;
1892            };
1893            if let hir::ExprKind::AddrOf(_, _, _) = expr.kind {
1894                return false;
1895            }
1896            let old_self_ty = old_pred.skip_binder().self_ty();
1897            if !old_self_ty.has_escaping_bound_vars()
1898                && !self.where_clause_expr_matches_failed_self_ty(
1899                    obligation,
1900                    self.tcx.instantiate_bound_regions_with_erased(old_pred.self_ty()),
1901                )
1902            {
1903                return false;
1904            }
1905            let needs_parens_post = expr_needs_parens(expr);
1906            let needs_parens_pre = match self.tcx.parent_hir_node(expr.hir_id) {
1907                Node::Expr(e)
1908                    if let hir::ExprKind::MethodCall(_, base, _, _) = e.kind
1909                        && base.hir_id == expr.hir_id =>
1910                {
1911                    true
1912                }
1913                _ => false,
1914            };
1915
1916            label();
1917            let suggestions = sugg_prefixes.into_iter().map(|sugg_prefix| {
1918                match (needs_parens_pre, needs_parens_post) {
1919                    (false, false) => ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(), sugg_prefix.to_string())]))vec![(span.shrink_to_lo(), sugg_prefix.to_string())],
1920                    // We have something like `foo.bar()`, where we want to bororw foo, so we need
1921                    // to suggest `(&mut foo).bar()`.
1922                    (false, true) => ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("{0}(", sugg_prefix))
                        })), (span.shrink_to_hi(), ")".to_string())]))vec![
1923                        (span.shrink_to_lo(), format!("{sugg_prefix}(")),
1924                        (span.shrink_to_hi(), ")".to_string()),
1925                    ],
1926                    // Issue #109436, we need to add parentheses properly for method calls
1927                    // for example, `foo.into()` should be `(&foo).into()`
1928                    (true, false) => ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("({0}", sugg_prefix))
                        })), (span.shrink_to_hi(), ")".to_string())]))vec![
1929                        (span.shrink_to_lo(), format!("({sugg_prefix}")),
1930                        (span.shrink_to_hi(), ")".to_string()),
1931                    ],
1932                    (true, true) => ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("({0}(", sugg_prefix))
                        })), (span.shrink_to_hi(), "))".to_string())]))vec![
1933                        (span.shrink_to_lo(), format!("({sugg_prefix}(")),
1934                        (span.shrink_to_hi(), "))".to_string()),
1935                    ],
1936                }
1937            });
1938            err.multipart_suggestions(sugg_msg, suggestions, Applicability::MaybeIncorrect);
1939            return true;
1940        };
1941
1942        if let ObligationCauseCode::ImplDerived(cause) = &*code {
1943            try_borrowing(cause.derived.parent_trait_pred, &[])
1944        } else if let ObligationCauseCode::WhereClause(..)
1945        | ObligationCauseCode::WhereClauseInExpr(..) = code
1946        {
1947            try_borrowing(poly_trait_pred, &never_suggest_borrow)
1948        } else {
1949            false
1950        }
1951    }
1952
1953    // Suggest borrowing the type
1954    pub(super) fn suggest_borrowing_for_object_cast(
1955        &self,
1956        err: &mut Diag<'_>,
1957        obligation: &PredicateObligation<'tcx>,
1958        self_ty: Ty<'tcx>,
1959        target_ty: Ty<'tcx>,
1960    ) {
1961        let ty::Ref(_, object_ty, hir::Mutability::Not) = target_ty.kind() else {
1962            return;
1963        };
1964        let ty::Dynamic(predicates, _) = object_ty.kind() else {
1965            return;
1966        };
1967        let self_ref_ty = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, self_ty);
1968
1969        for predicate in predicates.iter() {
1970            if !self.predicate_must_hold_modulo_regions(
1971                &obligation.with(self.tcx, predicate.with_self_ty(self.tcx, self_ref_ty)),
1972            ) {
1973                return;
1974            }
1975        }
1976
1977        err.span_suggestion_verbose(
1978            obligation.cause.span.shrink_to_lo(),
1979            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider borrowing the value, since `&{0}` can be coerced into `{1}`",
                self_ty, target_ty))
    })format!(
1980                "consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`"
1981            ),
1982            "&",
1983            Applicability::MaybeIncorrect,
1984        );
1985    }
1986
1987    /// Peel `&`-borrows from an expression, following through untyped let-bindings.
1988    /// Returns a list of removable `&` layers (each with the span to remove and the
1989    /// resulting type), plus an optional terminal [`hir::Param`] when the chain ends
1990    /// at a function parameter (including async-fn desugared parameters).
1991    fn peel_expr_refs(
1992        &self,
1993        mut expr: &'tcx hir::Expr<'tcx>,
1994        mut ty: Ty<'tcx>,
1995    ) -> (Vec<PeeledRef<'tcx>>, Option<&'tcx hir::Param<'tcx>>) {
1996        let mut refs = Vec::new();
1997        'outer: loop {
1998            while let hir::ExprKind::AddrOf(_, _, borrowed) = expr.kind {
1999                let span =
2000                    if let Some(borrowed_span) = borrowed.span.find_ancestor_inside(expr.span) {
2001                        expr.span.until(borrowed_span)
2002                    } else {
2003                        break 'outer;
2004                    };
2005
2006                // Double check that the span actually corresponds to a borrow,
2007                // rather than some macro garbage.
2008                // The span may include leading parens from parenthesized expressions
2009                // (e.g., `(&expr)` where HIR removes the Paren but keeps the span).
2010                // In that case, trim the span to start at the `&`.
2011                let span = match self.tcx.sess.source_map().span_to_snippet(span) {
2012                    Ok(ref snippet) if snippet.starts_with("&") => span,
2013                    Ok(ref snippet) if let Some(amp) = snippet.find('&') => {
2014                        span.with_lo(span.lo() + BytePos(amp as u32))
2015                    }
2016                    _ => break 'outer,
2017                };
2018
2019                let ty::Ref(_, inner_ty, _) = ty.kind() else {
2020                    break 'outer;
2021                };
2022                ty = *inner_ty;
2023                refs.push(PeeledRef { span, peeled_ty: ty });
2024                expr = borrowed;
2025            }
2026            if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
2027                && let Res::Local(hir_id) = path.res
2028                && let hir::Node::Pat(binding) = self.tcx.hir_node(hir_id)
2029            {
2030                match self.tcx.parent_hir_node(binding.hir_id) {
2031                    // Untyped let-binding: follow to its initializer.
2032                    hir::Node::LetStmt(local)
2033                        if local.ty.is_none()
2034                            && let Some(init) = local.init =>
2035                    {
2036                        expr = init;
2037                        continue;
2038                    }
2039                    // Async fn desugared parameter: `let x = __arg0;` with AsyncFn source.
2040                    // Follow to the original parameter.
2041                    hir::Node::LetStmt(local)
2042                        if #[allow(non_exhaustive_omitted_patterns)] match local.source {
    hir::LocalSource::AsyncFn => true,
    _ => false,
}matches!(local.source, hir::LocalSource::AsyncFn)
2043                            && let Some(init) = local.init
2044                            && let hir::ExprKind::Path(hir::QPath::Resolved(None, arg_path)) =
2045                                init.kind
2046                            && let Res::Local(arg_hir_id) = arg_path.res
2047                            && let hir::Node::Pat(arg_binding) = self.tcx.hir_node(arg_hir_id)
2048                            && let hir::Node::Param(param) =
2049                                self.tcx.parent_hir_node(arg_binding.hir_id) =>
2050                    {
2051                        return (refs, Some(param));
2052                    }
2053                    // Direct parameter reference.
2054                    hir::Node::Param(param) => {
2055                        return (refs, Some(param));
2056                    }
2057                    _ => break 'outer,
2058                }
2059            } else {
2060                break 'outer;
2061            }
2062        }
2063        (refs, None)
2064    }
2065
2066    /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
2067    /// suggest removing these references until we reach a type that implements the trait.
2068    pub(super) fn suggest_remove_reference(
2069        &self,
2070        obligation: &PredicateObligation<'tcx>,
2071        err: &mut Diag<'_>,
2072        trait_pred: ty::PolyTraitPredicate<'tcx>,
2073    ) -> bool {
2074        let mut span = obligation.cause.span;
2075        let mut trait_pred = trait_pred;
2076        let mut code = obligation.cause.code();
2077        while let Some((c, Some(parent_trait_pred))) = code.parent_with_predicate() {
2078            // We want the root obligation, in order to detect properly handle
2079            // `for _ in &mut &mut vec![] {}`.
2080            code = c;
2081            trait_pred = parent_trait_pred;
2082        }
2083        while span.desugaring_kind().is_some() {
2084            // Remove all the hir desugaring contexts while maintaining the macro contexts.
2085            span.remove_mark();
2086        }
2087        let mut expr_finder = super::FindExprBySpan::new(span, self.tcx);
2088        let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else {
2089            return false;
2090        };
2091        expr_finder.visit_expr(body.value);
2092        let mut maybe_suggest = |suggested_ty, count, suggestions| {
2093            // Remapping bound vars here
2094            let trait_pred_and_suggested_ty =
2095                trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty));
2096
2097            let new_obligation = self.mk_trait_obligation_with_new_self_ty(
2098                obligation.param_env,
2099                trait_pred_and_suggested_ty,
2100            );
2101
2102            if self.predicate_may_hold(&new_obligation) {
2103                let msg = if count == 1 {
2104                    "consider removing the leading `&`-reference".to_string()
2105                } else {
2106                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider removing {0} leading `&`-references",
                count))
    })format!("consider removing {count} leading `&`-references")
2107                };
2108
2109                err.multipart_suggestion(msg, suggestions, Applicability::MachineApplicable);
2110                true
2111            } else {
2112                false
2113            }
2114        };
2115
2116        // Maybe suggest removal of borrows from types in type parameters, like in
2117        // `src/test/ui/not-panic/not-panic-safe.rs`.
2118        let mut count = 0;
2119        let mut suggestions = ::alloc::vec::Vec::new()vec![];
2120        // Skipping binder here, remapping below
2121        let mut suggested_ty = trait_pred.self_ty().skip_binder();
2122        if let Some(mut hir_ty) = expr_finder.ty_result {
2123            while let hir::TyKind::Ref(_, mut_ty) = &hir_ty.kind {
2124                count += 1;
2125                let span = hir_ty.span.until(mut_ty.ty.span);
2126                suggestions.push((span, String::new()));
2127
2128                let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
2129                    break;
2130                };
2131                suggested_ty = *inner_ty;
2132
2133                hir_ty = mut_ty.ty;
2134
2135                if maybe_suggest(suggested_ty, count, suggestions.clone()) {
2136                    return true;
2137                }
2138            }
2139        }
2140
2141        // Maybe suggest removal of borrows from expressions, like in `for i in &&&foo {}`.
2142        let Some(expr) = expr_finder.result else {
2143            return false;
2144        };
2145        // Skipping binder here, remapping below
2146        let suggested_ty = trait_pred.self_ty().skip_binder();
2147        let (peeled_refs, _) = self.peel_expr_refs(expr, suggested_ty);
2148        for (i, peeled) in peeled_refs.iter().enumerate() {
2149            let suggestions: Vec<_> =
2150                peeled_refs[..=i].iter().map(|r| (r.span, String::new())).collect();
2151            if maybe_suggest(peeled.peeled_ty, i + 1, suggestions) {
2152                return true;
2153            }
2154        }
2155        false
2156    }
2157
2158    /// Suggest removing `&` from a function parameter type like `&impl Future`.
2159    fn suggest_remove_ref_from_param(&self, param: &hir::Param<'_>, err: &mut Diag<'_>) -> bool {
2160        if let Some(decl) = self.tcx.parent_hir_node(param.hir_id).fn_decl()
2161            && let Some(input_ty) = decl.inputs.iter().find(|t| param.ty_span.contains(t.span))
2162            && let hir::TyKind::Ref(_, mut_ty) = input_ty.kind
2163        {
2164            let ref_span = input_ty.span.until(mut_ty.ty.span);
2165            match self.tcx.sess.source_map().span_to_snippet(ref_span) {
2166                Ok(snippet) if snippet.starts_with("&") => {
2167                    err.span_suggestion_verbose(
2168                        ref_span,
2169                        "consider removing the `&` from the parameter type",
2170                        "",
2171                        Applicability::MaybeIncorrect,
2172                    );
2173                    return true;
2174                }
2175                _ => {}
2176            }
2177        }
2178        false
2179    }
2180
2181    pub(super) fn suggest_remove_await(
2182        &self,
2183        obligation: &PredicateObligation<'tcx>,
2184        err: &mut Diag<'_>,
2185    ) {
2186        if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives()
2187            && let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id)
2188        {
2189            // FIXME: use `obligation.predicate.kind()...trait_ref.self_ty()` to see if we have `()`
2190            // and if not maybe suggest doing something else? If we kept the expression around we
2191            // could also check if it is an fn call (very likely) and suggest changing *that*, if
2192            // it is from the local crate.
2193
2194            // If the type is `&..&T` where `T: Future`, suggest removing `&`
2195            // instead of removing `.await`.
2196            if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) =
2197                obligation.predicate.kind().skip_binder()
2198            {
2199                let self_ty = pred.self_ty();
2200                let future_trait =
2201                    self.tcx.require_lang_item(LangItem::Future, obligation.cause.span);
2202
2203                // Peel through references to check if there's a Future underneath.
2204                let has_future = {
2205                    let mut ty = self_ty;
2206                    loop {
2207                        match *ty.kind() {
2208                            ty::Ref(_, inner_ty, _)
2209                                if !#[allow(non_exhaustive_omitted_patterns)] match inner_ty.kind() {
    ty::Dynamic(..) => true,
    _ => false,
}matches!(inner_ty.kind(), ty::Dynamic(..)) =>
2210                            {
2211                                if self
2212                                    .type_implements_trait(
2213                                        future_trait,
2214                                        [inner_ty],
2215                                        obligation.param_env,
2216                                    )
2217                                    .must_apply_modulo_regions()
2218                                {
2219                                    break true;
2220                                }
2221                                ty = inner_ty;
2222                            }
2223                            _ => break false,
2224                        }
2225                    }
2226                };
2227
2228                if has_future {
2229                    let (peeled_refs, terminal_param) = self.peel_expr_refs(expr, self_ty);
2230
2231                    // Try removing `&`s from the expression.
2232                    for (i, peeled) in peeled_refs.iter().enumerate() {
2233                        if self
2234                            .type_implements_trait(
2235                                future_trait,
2236                                [peeled.peeled_ty],
2237                                obligation.param_env,
2238                            )
2239                            .must_apply_modulo_regions()
2240                        {
2241                            let count = i + 1;
2242                            let msg = if count == 1 {
2243                                "consider removing the leading `&`-reference".to_string()
2244                            } else {
2245                                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider removing {0} leading `&`-references",
                count))
    })format!("consider removing {count} leading `&`-references")
2246                            };
2247                            let suggestions: Vec<_> =
2248                                peeled_refs[..=i].iter().map(|r| (r.span, String::new())).collect();
2249                            err.multipart_suggestion(
2250                                msg,
2251                                suggestions,
2252                                Applicability::MachineApplicable,
2253                            );
2254                            return;
2255                        }
2256                    }
2257
2258                    // Try removing `&` from the parameter type, but only when there's
2259                    // no `&` in the expression itself (otherwise removing from the param
2260                    // alone wouldn't fix the error).
2261                    if peeled_refs.is_empty()
2262                        && let Some(param) = terminal_param
2263                        && self.suggest_remove_ref_from_param(param, err)
2264                    {
2265                        return;
2266                    }
2267
2268                    // Fallback: emit a help message when we can't provide a specific span.
2269                    err.help(
2270                        "a reference to a future is not a future; \
2271                     consider removing the leading `&`-reference",
2272                    );
2273                    return;
2274                }
2275            }
2276
2277            // use nth(1) to skip one layer of desugaring from `IntoIter::into_iter`
2278            if let Some((_, hir::Node::Expr(await_expr))) = self.tcx.hir_parent_iter(*hir_id).nth(1)
2279                && let Some(expr_span) = expr.span.find_ancestor_inside_same_ctxt(await_expr.span)
2280            {
2281                let removal_span = self
2282                    .tcx
2283                    .sess
2284                    .source_map()
2285                    .span_extend_while_whitespace(expr_span)
2286                    .shrink_to_hi()
2287                    .to(await_expr.span.shrink_to_hi());
2288                err.span_suggestion_verbose(
2289                    removal_span,
2290                    "remove the `.await`",
2291                    "",
2292                    Applicability::MachineApplicable,
2293                );
2294            } else {
2295                err.span_label(obligation.cause.span, "remove the `.await`");
2296            }
2297            // FIXME: account for associated `async fn`s.
2298            if let hir::Expr { span, kind: hir::ExprKind::Call(base, _), .. } = expr {
2299                if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) =
2300                    obligation.predicate.kind().skip_binder()
2301                {
2302                    err.span_label(*span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this call returns `{0}`",
                pred.self_ty()))
    })format!("this call returns `{}`", pred.self_ty()));
2303                }
2304                if let Some(typeck_results) = &self.typeck_results
2305                    && let ty = typeck_results.expr_ty_adjusted(base)
2306                    && let ty::FnDef(def_id, _args) = ty.kind()
2307                    && let Some(hir::Node::Item(item)) = self.tcx.hir_get_if_local(*def_id)
2308                {
2309                    let (ident, _, _, _) = item.expect_fn();
2310                    let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("alternatively, consider making `fn {0}` asynchronous",
                ident))
    })format!("alternatively, consider making `fn {ident}` asynchronous");
2311                    if item.vis_span.is_empty() {
2312                        err.span_suggestion_verbose(
2313                            item.span.shrink_to_lo(),
2314                            msg,
2315                            "async ",
2316                            Applicability::MaybeIncorrect,
2317                        );
2318                    } else {
2319                        err.span_suggestion_verbose(
2320                            item.vis_span.shrink_to_hi(),
2321                            msg,
2322                            " async",
2323                            Applicability::MaybeIncorrect,
2324                        );
2325                    }
2326                }
2327            }
2328        }
2329    }
2330
2331    /// Check if the trait bound is implemented for a different mutability and note it in the
2332    /// final error.
2333    pub(super) fn suggest_change_mut(
2334        &self,
2335        obligation: &PredicateObligation<'tcx>,
2336        err: &mut Diag<'_>,
2337        trait_pred: ty::PolyTraitPredicate<'tcx>,
2338    ) {
2339        let points_at_arg =
2340            #[allow(non_exhaustive_omitted_patterns)] match obligation.cause.code() {
    ObligationCauseCode::FunctionArg { .. } => true,
    _ => false,
}matches!(obligation.cause.code(), ObligationCauseCode::FunctionArg { .. },);
2341
2342        let span = obligation.cause.span;
2343        if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
2344            let refs_number =
2345                snippet.chars().filter(|c| !c.is_whitespace()).take_while(|c| *c == '&').count();
2346            if let Some('\'') = snippet.chars().filter(|c| !c.is_whitespace()).nth(refs_number) {
2347                // Do not suggest removal of borrow from type arguments.
2348                return;
2349            }
2350            let trait_pred = self.resolve_vars_if_possible(trait_pred);
2351            if trait_pred.has_non_region_infer() {
2352                // Do not ICE while trying to find if a reborrow would succeed on a trait with
2353                // unresolved bindings.
2354                return;
2355            }
2356
2357            // Skipping binder here, remapping below
2358            if let ty::Ref(region, t_type, mutability) = *trait_pred.skip_binder().self_ty().kind()
2359            {
2360                let suggested_ty = match mutability {
2361                    hir::Mutability::Mut => Ty::new_imm_ref(self.tcx, region, t_type),
2362                    hir::Mutability::Not => Ty::new_mut_ref(self.tcx, region, t_type),
2363                };
2364
2365                // Remapping bound vars here
2366                let trait_pred_and_suggested_ty =
2367                    trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty));
2368
2369                let new_obligation = self.mk_trait_obligation_with_new_self_ty(
2370                    obligation.param_env,
2371                    trait_pred_and_suggested_ty,
2372                );
2373                let suggested_ty_would_satisfy_obligation = self
2374                    .evaluate_obligation_no_overflow(&new_obligation)
2375                    .must_apply_modulo_regions();
2376                if suggested_ty_would_satisfy_obligation {
2377                    let sp = self
2378                        .tcx
2379                        .sess
2380                        .source_map()
2381                        .span_take_while(span, |c| c.is_whitespace() || *c == '&');
2382                    if points_at_arg && mutability.is_not() && refs_number > 0 {
2383                        // If we have a call like foo(&mut buf), then don't suggest foo(&mut mut buf)
2384                        if snippet
2385                            .trim_start_matches(|c: char| c.is_whitespace() || c == '&')
2386                            .starts_with("mut")
2387                        {
2388                            return;
2389                        }
2390                        err.span_suggestion_verbose(
2391                            sp,
2392                            "consider changing this borrow's mutability",
2393                            "&mut ",
2394                            Applicability::MachineApplicable,
2395                        );
2396                    } else {
2397                        err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` is implemented for `{1}`, but not for `{2}`",
                trait_pred.print_modifiers_and_trait_path(), suggested_ty,
                trait_pred.skip_binder().self_ty()))
    })format!(
2398                            "`{}` is implemented for `{}`, but not for `{}`",
2399                            trait_pred.print_modifiers_and_trait_path(),
2400                            suggested_ty,
2401                            trait_pred.skip_binder().self_ty(),
2402                        ));
2403                    }
2404                }
2405            }
2406        }
2407    }
2408
2409    pub(super) fn suggest_semicolon_removal(
2410        &self,
2411        obligation: &PredicateObligation<'tcx>,
2412        err: &mut Diag<'_>,
2413        span: Span,
2414        trait_pred: ty::PolyTraitPredicate<'tcx>,
2415    ) -> bool {
2416        let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
2417        if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn {sig, body: body_id, .. }, .. }) = node
2418            && let hir::ExprKind::Block(blk, _) = &self.tcx.hir_body(*body_id).value.kind
2419            && sig.decl.output.span().overlaps(span)
2420            && blk.expr.is_none()
2421            && trait_pred.self_ty().skip_binder().is_unit()
2422            && let Some(stmt) = blk.stmts.last()
2423            && let hir::StmtKind::Semi(expr) = stmt.kind
2424            // Only suggest this if the expression behind the semicolon implements the predicate
2425            && let Some(typeck_results) = &self.typeck_results
2426            && let Some(ty) = typeck_results.expr_ty_opt(expr)
2427            && self.predicate_may_hold(&self.mk_trait_obligation_with_new_self_ty(
2428                obligation.param_env, trait_pred.map_bound(|trait_pred| (trait_pred, ty))
2429            ))
2430        {
2431            err.span_label(
2432                expr.span,
2433                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this expression has type `{0}`, which implements `{1}`",
                ty, trait_pred.print_modifiers_and_trait_path()))
    })format!(
2434                    "this expression has type `{}`, which implements `{}`",
2435                    ty,
2436                    trait_pred.print_modifiers_and_trait_path()
2437                ),
2438            );
2439            err.span_suggestion(
2440                self.tcx.sess.source_map().end_point(stmt.span),
2441                "remove this semicolon",
2442                "",
2443                Applicability::MachineApplicable,
2444            );
2445            return true;
2446        }
2447        false
2448    }
2449
2450    pub(super) fn suggest_borrow_for_unsized_closure_return<G: EmissionGuarantee>(
2451        &self,
2452        body_id: LocalDefId,
2453        err: &mut Diag<'_, G>,
2454        predicate: ty::Predicate<'tcx>,
2455    ) {
2456        let Some(pred) = predicate.as_trait_clause() else {
2457            return;
2458        };
2459        if !self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) {
2460            return;
2461        }
2462
2463        let Some(span) = err.span.primary_span() else {
2464            return;
2465        };
2466        let Some(node_body_id) = self.tcx.hir_node_by_def_id(body_id).body_id() else {
2467            return;
2468        };
2469        let body = self.tcx.hir_body(node_body_id);
2470        let mut expr_finder = FindExprBySpan::new(span, self.tcx);
2471        expr_finder.visit_expr(body.value);
2472        let Some(expr) = expr_finder.result else {
2473            return;
2474        };
2475
2476        let closure = match expr.kind {
2477            hir::ExprKind::Call(_, args) => args.iter().find_map(|arg| match arg.kind {
2478                hir::ExprKind::Closure(closure) => Some(closure),
2479                _ => None,
2480            }),
2481            hir::ExprKind::MethodCall(_, _, args, _) => {
2482                args.iter().find_map(|arg| match arg.kind {
2483                    hir::ExprKind::Closure(closure) => Some(closure),
2484                    _ => None,
2485                })
2486            }
2487            _ => None,
2488        };
2489        let Some(closure) = closure else {
2490            return;
2491        };
2492        if !#[allow(non_exhaustive_omitted_patterns)] match closure.fn_decl.output {
    hir::FnRetTy::DefaultReturn(_) => true,
    _ => false,
}matches!(closure.fn_decl.output, hir::FnRetTy::DefaultReturn(_)) {
2493            return;
2494        }
2495
2496        err.span_suggestion_verbose(
2497            self.tcx.hir_body(closure.body).value.span.shrink_to_lo(),
2498            "consider borrowing the value",
2499            "&",
2500            Applicability::MaybeIncorrect,
2501        );
2502    }
2503
2504    pub(super) fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
2505        let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig, .. }, .. }) =
2506            self.tcx.hir_node_by_def_id(obligation.cause.body_id)
2507        else {
2508            return None;
2509        };
2510
2511        if let hir::FnRetTy::Return(ret_ty) = sig.decl.output { Some(ret_ty.span) } else { None }
2512    }
2513
2514    /// If all conditions are met to identify a returned `dyn Trait`, suggest using `impl Trait` if
2515    /// applicable and signal that the error has been expanded appropriately and needs to be
2516    /// emitted.
2517    pub(super) fn suggest_impl_trait(
2518        &self,
2519        err: &mut Diag<'_>,
2520        obligation: &PredicateObligation<'tcx>,
2521        trait_pred: ty::PolyTraitPredicate<'tcx>,
2522    ) -> bool {
2523        let ObligationCauseCode::SizedReturnType = obligation.cause.code() else {
2524            return false;
2525        };
2526        let ty::Dynamic(_, _) = trait_pred.self_ty().skip_binder().kind() else {
2527            return false;
2528        };
2529        if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. })
2530        | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. })
2531        | Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(fn_sig, _), .. }) =
2532            self.tcx.hir_node_by_def_id(obligation.cause.body_id)
2533            && let hir::FnRetTy::Return(ty) = fn_sig.decl.output
2534            && let hir::TyKind::Path(qpath) = ty.kind
2535            && let hir::QPath::Resolved(None, path) = qpath
2536            && let Res::Def(DefKind::TyAlias, def_id) = path.res
2537        {
2538            // Do not suggest
2539            // type T = dyn Trait;
2540            // fn foo() -> impl T { .. }
2541            err.span_note(self.tcx.def_span(def_id), "this type alias is unsized");
2542            err.multipart_suggestion(
2543                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider boxing the return type, and wrapping all of the returned values in `Box::new`"))
    })format!(
2544                    "consider boxing the return type, and wrapping all of the returned values in \
2545                    `Box::new`",
2546                ),
2547                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(ty.span.shrink_to_lo(), "Box<".to_string()),
                (ty.span.shrink_to_hi(), ">".to_string())]))vec![
2548                    (ty.span.shrink_to_lo(), "Box<".to_string()),
2549                    (ty.span.shrink_to_hi(), ">".to_string()),
2550                ],
2551                Applicability::MaybeIncorrect,
2552            );
2553            return false;
2554        }
2555
2556        err.code(E0746);
2557        err.primary_message("return type cannot be a trait object without pointer indirection");
2558        err.children.clear();
2559
2560        let mut span = obligation.cause.span;
2561        let mut is_async_fn_return = false;
2562        if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id)
2563            && let parent = self.tcx.local_parent(obligation.cause.body_id)
2564            && let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent)
2565            && self.tcx.asyncness(parent).is_async()
2566            && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. })
2567            | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. })
2568            | Node::TraitItem(hir::TraitItem {
2569                kind: hir::TraitItemKind::Fn(fn_sig, _), ..
2570            }) = self.tcx.hir_node_by_def_id(parent)
2571        {
2572            // Do not suggest (#147894)
2573            // async fn foo() -> dyn Display impl { .. }
2574            // and
2575            // async fn foo() -> dyn Display Box<dyn { .. }>
2576            span = fn_sig.decl.output.span();
2577            is_async_fn_return = true;
2578            err.span(span);
2579        }
2580        let body = self.tcx.hir_body_owned_by(obligation.cause.body_id);
2581
2582        if !is_async_fn_return
2583            && let Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) =
2584                self.tcx.hir_node_by_def_id(obligation.cause.body_id)
2585            && #[allow(non_exhaustive_omitted_patterns)] match closure.fn_decl.output {
    hir::FnRetTy::DefaultReturn(_) => true,
    _ => false,
}matches!(closure.fn_decl.output, hir::FnRetTy::DefaultReturn(_))
2586        {
2587            return true;
2588        }
2589
2590        let mut visitor = ReturnsVisitor::default();
2591        visitor.visit_body(&body);
2592
2593        let (pre, impl_span) = if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span)
2594            && snip.starts_with("dyn ")
2595        {
2596            ("", span.with_hi(span.lo() + BytePos(4)))
2597        } else {
2598            ("dyn ", span.shrink_to_lo())
2599        };
2600
2601        err.span_suggestion_verbose(
2602            impl_span,
2603            "consider returning an `impl Trait` instead of a `dyn Trait`",
2604            "impl ",
2605            Applicability::MaybeIncorrect,
2606        );
2607
2608        let mut sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("Box<{0}", pre))
                        })), (span.shrink_to_hi(), ">".to_string())]))vec![
2609            (span.shrink_to_lo(), format!("Box<{pre}")),
2610            (span.shrink_to_hi(), ">".to_string()),
2611        ];
2612        sugg.extend(visitor.returns.into_iter().flat_map(|expr| {
2613            let span =
2614                expr.span.find_ancestor_in_same_ctxt(obligation.cause.span).unwrap_or(expr.span);
2615            if !span.can_be_used_for_suggestions() {
2616                ::alloc::vec::Vec::new()vec![]
2617            } else if let hir::ExprKind::Call(path, ..) = expr.kind
2618                && let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, method)) = path.kind
2619                && method.ident.name == sym::new
2620                && let hir::TyKind::Path(hir::QPath::Resolved(.., box_path)) = ty.kind
2621                && box_path
2622                    .res
2623                    .opt_def_id()
2624                    .is_some_and(|def_id| self.tcx.is_lang_item(def_id, LangItem::OwnedBox))
2625            {
2626                // Don't box `Box::new`
2627                ::alloc::vec::Vec::new()vec![]
2628            } else {
2629                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(), "Box::new(".to_string()),
                (span.shrink_to_hi(), ")".to_string())]))vec![
2630                    (span.shrink_to_lo(), "Box::new(".to_string()),
2631                    (span.shrink_to_hi(), ")".to_string()),
2632                ]
2633            }
2634        }));
2635
2636        err.multipart_suggestion(
2637            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("alternatively, box the return type, and wrap all of the returned values in `Box::new`"))
    })format!(
2638                "alternatively, box the return type, and wrap all of the returned values in \
2639                 `Box::new`",
2640            ),
2641            sugg,
2642            Applicability::MaybeIncorrect,
2643        );
2644
2645        true
2646    }
2647
2648    pub(super) fn report_closure_arg_mismatch(
2649        &self,
2650        span: Span,
2651        found_span: Option<Span>,
2652        found: ty::TraitRef<'tcx>,
2653        expected: ty::TraitRef<'tcx>,
2654        cause: &ObligationCauseCode<'tcx>,
2655        found_node: Option<Node<'_>>,
2656        param_env: ty::ParamEnv<'tcx>,
2657    ) -> Diag<'a> {
2658        pub(crate) fn build_fn_sig_ty<'tcx>(
2659            infcx: &InferCtxt<'tcx>,
2660            trait_ref: ty::TraitRef<'tcx>,
2661        ) -> Ty<'tcx> {
2662            let inputs = trait_ref.args.type_at(1);
2663            let sig = match inputs.kind() {
2664                ty::Tuple(inputs) if infcx.tcx.is_callable_trait(trait_ref.def_id) => {
2665                    infcx.tcx.mk_fn_sig_safe_rust_abi(*inputs, infcx.next_ty_var(DUMMY_SP))
2666                }
2667                _ => infcx.tcx.mk_fn_sig_safe_rust_abi([inputs], infcx.next_ty_var(DUMMY_SP)),
2668            };
2669
2670            Ty::new_fn_ptr(infcx.tcx, ty::Binder::dummy(sig))
2671        }
2672
2673        let argument_kind = match expected.self_ty().kind() {
2674            ty::Closure(..) => "closure",
2675            ty::Coroutine(..) => "coroutine",
2676            _ => "function",
2677        };
2678        let mut err = {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("type mismatch in {0} arguments",
                            argument_kind))
                })).with_code(E0631)
}struct_span_code_err!(
2679            self.dcx(),
2680            span,
2681            E0631,
2682            "type mismatch in {argument_kind} arguments",
2683        );
2684
2685        err.span_label(span, "expected due to this");
2686
2687        let found_span = found_span.unwrap_or(span);
2688        err.span_label(found_span, "found signature defined here");
2689
2690        let expected = build_fn_sig_ty(self, expected);
2691        let found = build_fn_sig_ty(self, found);
2692
2693        let (expected_str, found_str) = self.cmp(expected, found);
2694
2695        let signature_kind = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} signature", argument_kind))
    })format!("{argument_kind} signature");
2696        err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str);
2697
2698        self.note_conflicting_fn_args(&mut err, cause, expected, found, param_env);
2699        self.note_conflicting_closure_bounds(cause, &mut err);
2700
2701        if let Some(found_node) = found_node {
2702            hint_missing_borrow(self, param_env, span, found, expected, found_node, &mut err);
2703        }
2704
2705        err
2706    }
2707
2708    fn note_conflicting_fn_args(
2709        &self,
2710        err: &mut Diag<'_>,
2711        cause: &ObligationCauseCode<'tcx>,
2712        expected: Ty<'tcx>,
2713        found: Ty<'tcx>,
2714        param_env: ty::ParamEnv<'tcx>,
2715    ) {
2716        let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = cause else {
2717            return;
2718        };
2719        let ty::FnPtr(sig_tys, hdr) = expected.kind() else {
2720            return;
2721        };
2722        let expected = sig_tys.with(*hdr);
2723        let ty::FnPtr(sig_tys, hdr) = found.kind() else {
2724            return;
2725        };
2726        let found = sig_tys.with(*hdr);
2727        let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id) else {
2728            return;
2729        };
2730        let hir::ExprKind::Path(path) = arg.kind else {
2731            return;
2732        };
2733        let expected_inputs = self.tcx.instantiate_bound_regions_with_erased(expected).inputs();
2734        let found_inputs = self.tcx.instantiate_bound_regions_with_erased(found).inputs();
2735        let both_tys = expected_inputs.iter().copied().zip(found_inputs.iter().copied());
2736
2737        let arg_expr = |infcx: &InferCtxt<'tcx>, name, expected: Ty<'tcx>, found: Ty<'tcx>| {
2738            let (expected_ty, expected_refs) = get_deref_type_and_refs(expected);
2739            let (found_ty, found_refs) = get_deref_type_and_refs(found);
2740
2741            if infcx.can_eq(param_env, found_ty, expected_ty) {
2742                if found_refs.len() == expected_refs.len()
2743                    && found_refs.iter().eq(expected_refs.iter())
2744                {
2745                    name
2746                } else if found_refs.len() > expected_refs.len() {
2747                    let refs = &found_refs[..found_refs.len() - expected_refs.len()];
2748                    if found_refs[..expected_refs.len()].iter().eq(expected_refs.iter()) {
2749                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}",
                refs.iter().map(|mutbl|
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("&{0}",
                                                mutbl.prefix_str()))
                                    })).collect::<Vec<_>>().join(""), name))
    })format!(
2750                            "{}{name}",
2751                            refs.iter()
2752                                .map(|mutbl| format!("&{}", mutbl.prefix_str()))
2753                                .collect::<Vec<_>>()
2754                                .join(""),
2755                        )
2756                    } else {
2757                        // The refs have different mutability.
2758                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}*{1}",
                refs.iter().map(|mutbl|
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("&{0}",
                                                mutbl.prefix_str()))
                                    })).collect::<Vec<_>>().join(""), name))
    })format!(
2759                            "{}*{name}",
2760                            refs.iter()
2761                                .map(|mutbl| format!("&{}", mutbl.prefix_str()))
2762                                .collect::<Vec<_>>()
2763                                .join(""),
2764                        )
2765                    }
2766                } else if expected_refs.len() > found_refs.len() {
2767                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}",
                (0..(expected_refs.len() -
                                            found_refs.len())).map(|_|
                                "*").collect::<Vec<_>>().join(""), name))
    })format!(
2768                        "{}{name}",
2769                        (0..(expected_refs.len() - found_refs.len()))
2770                            .map(|_| "*")
2771                            .collect::<Vec<_>>()
2772                            .join(""),
2773                    )
2774                } else {
2775                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}",
                found_refs.iter().map(|mutbl|
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("&{0}",
                                                    mutbl.prefix_str()))
                                        })).chain(found_refs.iter().map(|_|
                                    "*".to_string())).collect::<Vec<_>>().join(""), name))
    })format!(
2776                        "{}{name}",
2777                        found_refs
2778                            .iter()
2779                            .map(|mutbl| format!("&{}", mutbl.prefix_str()))
2780                            .chain(found_refs.iter().map(|_| "*".to_string()))
2781                            .collect::<Vec<_>>()
2782                            .join(""),
2783                    )
2784                }
2785            } else {
2786                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("/* {0} */", found))
    })format!("/* {found} */")
2787            }
2788        };
2789        let args_have_same_underlying_type = both_tys.clone().all(|(expected, found)| {
2790            let (expected_ty, _) = get_deref_type_and_refs(expected);
2791            let (found_ty, _) = get_deref_type_and_refs(found);
2792            self.can_eq(param_env, found_ty, expected_ty)
2793        });
2794        let (closure_names, call_names): (Vec<_>, Vec<_>) = if args_have_same_underlying_type
2795            && !expected_inputs.is_empty()
2796            && expected_inputs.len() == found_inputs.len()
2797            && let Some(typeck) = &self.typeck_results
2798            && let Res::Def(res_kind, fn_def_id) = typeck.qpath_res(&path, *arg_hir_id)
2799            && res_kind.is_fn_like()
2800        {
2801            let closure: Vec<_> = self
2802                .tcx
2803                .fn_arg_idents(fn_def_id)
2804                .iter()
2805                .enumerate()
2806                .map(|(i, ident)| {
2807                    if let Some(ident) = ident
2808                        && !#[allow(non_exhaustive_omitted_patterns)] match ident {
    Ident { name: kw::Underscore | kw::SelfLower, .. } => true,
    _ => false,
}matches!(ident, Ident { name: kw::Underscore | kw::SelfLower, .. })
2809                    {
2810                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}", ident))
    })format!("{ident}")
2811                    } else {
2812                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("arg{0}", i))
    })format!("arg{i}")
2813                    }
2814                })
2815                .collect();
2816            let args = closure
2817                .iter()
2818                .zip(both_tys)
2819                .map(|(name, (expected, found))| {
2820                    arg_expr(self.infcx, name.to_owned(), expected, found)
2821                })
2822                .collect();
2823            (closure, args)
2824        } else {
2825            let closure_args = expected_inputs
2826                .iter()
2827                .enumerate()
2828                .map(|(i, _)| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("arg{0}", i))
    })format!("arg{i}"))
2829                .collect::<Vec<_>>();
2830            let call_args = both_tys
2831                .enumerate()
2832                .map(|(i, (expected, found))| {
2833                    arg_expr(self.infcx, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("arg{0}", i))
    })format!("arg{i}"), expected, found)
2834                })
2835                .collect::<Vec<_>>();
2836            (closure_args, call_args)
2837        };
2838        let closure_names: Vec<_> = closure_names
2839            .into_iter()
2840            .zip(expected_inputs.iter())
2841            .map(|(name, ty)| {
2842                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{1}{0}",
                if ty.has_infer_types() {
                    String::new()
                } else if ty.references_error() {
                    ": /* type */".to_string()
                } else {
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(": {0}", ty))
                        })
                }, name))
    })format!(
2843                    "{name}{}",
2844                    if ty.has_infer_types() {
2845                        String::new()
2846                    } else if ty.references_error() {
2847                        ": /* type */".to_string()
2848                    } else {
2849                        format!(": {ty}")
2850                    }
2851                )
2852            })
2853            .collect();
2854        err.multipart_suggestion(
2855            "consider wrapping the function in a closure",
2856            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(arg.span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("|{0}| ",
                                    closure_names.join(", ")))
                        })),
                (arg.span.shrink_to_hi(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("({0})",
                                    call_names.join(", ")))
                        }))]))vec![
2857                (arg.span.shrink_to_lo(), format!("|{}| ", closure_names.join(", "))),
2858                (arg.span.shrink_to_hi(), format!("({})", call_names.join(", "))),
2859            ],
2860            Applicability::MaybeIncorrect,
2861        );
2862    }
2863
2864    // Add a note if there are two `Fn`-family bounds that have conflicting argument
2865    // requirements, which will always cause a closure to have a type error.
2866    fn note_conflicting_closure_bounds(
2867        &self,
2868        cause: &ObligationCauseCode<'tcx>,
2869        err: &mut Diag<'_>,
2870    ) {
2871        // First, look for an `WhereClauseInExpr`, which means we can get
2872        // the uninstantiated predicate list of the called function. And check
2873        // that the predicate that we failed to satisfy is a `Fn`-like trait.
2874        if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = *cause
2875            && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
2876            && let Some(pred) = predicates.predicates.get(idx).map(|p| p.as_ref().skip_norm_wip())
2877            && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder()
2878            && self.tcx.is_fn_trait(trait_pred.def_id())
2879        {
2880            let expected_self =
2881                self.tcx.anonymize_bound_vars(pred.kind().rebind(trait_pred.self_ty()));
2882            let expected_args =
2883                self.tcx.anonymize_bound_vars(pred.kind().rebind(trait_pred.trait_ref.args));
2884
2885            // Find another predicate whose self-type is equal to the expected self type,
2886            // but whose args don't match.
2887            let other_pred = predicates.into_iter().enumerate().find(|&(other_idx, (pred, _))| {
2888                let pred = pred.skip_norm_wip();
2889                match pred.kind().skip_binder() {
2890                    ty::ClauseKind::Trait(trait_pred)
2891                        if self.tcx.is_fn_trait(trait_pred.def_id())
2892                            && other_idx != idx
2893                            // Make sure that the self type matches
2894                            // (i.e. constraining this closure)
2895                            && expected_self
2896                                == self.tcx.anonymize_bound_vars(
2897                                    pred.kind().rebind(trait_pred.self_ty()),
2898                                )
2899                            // But the args don't match (i.e. incompatible args)
2900                            && expected_args
2901                                != self.tcx.anonymize_bound_vars(
2902                                    pred.kind().rebind(trait_pred.trait_ref.args),
2903                                ) =>
2904                    {
2905                        true
2906                    }
2907                    _ => false,
2908                }
2909            });
2910            // If we found one, then it's very likely the cause of the error.
2911            if let Some((_, (_, other_pred_span))) = other_pred {
2912                err.span_note(
2913                    other_pred_span,
2914                    "closure inferred to have a different signature due to this bound",
2915                );
2916            }
2917        }
2918    }
2919
2920    pub(super) fn suggest_fully_qualified_path(
2921        &self,
2922        err: &mut Diag<'_>,
2923        item_def_id: DefId,
2924        span: Span,
2925        trait_ref: DefId,
2926    ) {
2927        if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id)
2928            && let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind
2929        {
2930            err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}s cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`",
                self.tcx.def_kind_descr(assoc_item.as_def_kind(),
                    item_def_id)))
    })format!(
2931                "{}s cannot be accessed directly on a `trait`, they can only be \
2932                        accessed through a specific `impl`",
2933                self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id)
2934            ));
2935
2936            if !assoc_item.is_impl_trait_in_trait() {
2937                err.span_suggestion_verbose(
2938                    span,
2939                    "use the fully qualified path to an implementation",
2940                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<Type as {0}>::{1}",
                self.tcx.def_path_str(trait_ref), assoc_item.name()))
    })format!(
2941                        "<Type as {}>::{}",
2942                        self.tcx.def_path_str(trait_ref),
2943                        assoc_item.name()
2944                    ),
2945                    Applicability::HasPlaceholders,
2946                );
2947            }
2948        }
2949    }
2950
2951    /// Adds an async-await specific note to the diagnostic when the future does not implement
2952    /// an auto trait because of a captured type.
2953    ///
2954    /// ```text
2955    /// note: future does not implement `Qux` as this value is used across an await
2956    ///   --> $DIR/issue-64130-3-other.rs:17:5
2957    ///    |
2958    /// LL |     let x = Foo;
2959    ///    |         - has type `Foo`
2960    /// LL |     baz().await;
2961    ///    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
2962    /// LL | }
2963    ///    | - `x` is later dropped here
2964    /// ```
2965    ///
2966    /// When the diagnostic does not implement `Send` or `Sync` specifically, then the diagnostic
2967    /// is "replaced" with a different message and a more specific error.
2968    ///
2969    /// ```text
2970    /// error: future cannot be sent between threads safely
2971    ///   --> $DIR/issue-64130-2-send.rs:21:5
2972    ///    |
2973    /// LL | fn is_send<T: Send>(t: T) { }
2974    ///    |               ---- required by this bound in `is_send`
2975    /// ...
2976    /// LL |     is_send(bar());
2977    ///    |     ^^^^^^^ future returned by `bar` is not send
2978    ///    |
2979    ///    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not
2980    ///            implemented for `Foo`
2981    /// note: future is not send as this value is used across an await
2982    ///   --> $DIR/issue-64130-2-send.rs:15:5
2983    ///    |
2984    /// LL |     let x = Foo;
2985    ///    |         - has type `Foo`
2986    /// LL |     baz().await;
2987    ///    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
2988    /// LL | }
2989    ///    | - `x` is later dropped here
2990    /// ```
2991    ///
2992    /// Returns `true` if an async-await specific note was added to the diagnostic.
2993    #[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_note_obligation_cause_for_async_await",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(2993u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["obligation.predicate",
                                                    "obligation.cause.span"],
                                        ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&debug(&obligation.predicate)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&debug(&obligation.cause.span)
                                                            as &dyn 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: bool = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let (mut trait_ref, mut target_ty) =
                match obligation.predicate.kind().skip_binder() {
                    ty::PredicateKind::Clause(ty::ClauseKind::Trait(p)) =>
                        (Some(p), Some(p.self_ty())),
                    _ => (None, None),
                };
            let mut coroutine = None;
            let mut outer_coroutine = None;
            let mut next_code = Some(obligation.cause.code());
            let mut seen_upvar_tys_infer_tuple = false;
            while let Some(code) = next_code {
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3032",
                                        "rustc_trait_selection::error_reporting::traits::suggestions",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                        ::tracing_core::__macro_support::Option::Some(3032u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                        ::tracing_core::field::FieldSet::new(&["code"],
                                            ::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};
                                let mut iter = __CALLSITE.metadata().fields().iter();
                                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&debug(&code) as
                                                            &dyn Value))])
                            });
                    } else { ; }
                };
                match code {
                    ObligationCauseCode::FunctionArg { parent_code, .. } => {
                        next_code = Some(parent_code);
                    }
                    ObligationCauseCode::ImplDerived(cause) => {
                        let ty =
                            cause.derived.parent_trait_pred.skip_binder().self_ty();
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3039",
                                                "rustc_trait_selection::error_reporting::traits::suggestions",
                                                ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                                ::tracing_core::__macro_support::Option::Some(3039u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                                ::tracing_core::field::FieldSet::new(&["message",
                                                                "parent_trait_ref", "self_ty.kind"],
                                                    ::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};
                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&format_args!("ImplDerived")
                                                                    as &dyn Value)),
                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&cause.derived.parent_trait_pred)
                                                                    as &dyn Value)),
                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&ty.kind())
                                                                    as &dyn Value))])
                                    });
                            } else { ; }
                        };
                        match *ty.kind() {
                            ty::Coroutine(did, ..) | ty::CoroutineWitness(did, _) => {
                                coroutine = coroutine.or(Some(did));
                                outer_coroutine = Some(did);
                            }
                            ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
                                seen_upvar_tys_infer_tuple = true;
                            }
                            _ if coroutine.is_none() => {
                                trait_ref =
                                    Some(cause.derived.parent_trait_pred.skip_binder());
                                target_ty = Some(ty);
                            }
                            _ => {}
                        }
                        next_code = Some(&cause.derived.parent_code);
                    }
                    ObligationCauseCode::WellFormedDerived(derived_obligation) |
                        ObligationCauseCode::BuiltinDerived(derived_obligation) => {
                        let ty =
                            derived_obligation.parent_trait_pred.skip_binder().self_ty();
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3069",
                                                "rustc_trait_selection::error_reporting::traits::suggestions",
                                                ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                                ::tracing_core::__macro_support::Option::Some(3069u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                                ::tracing_core::field::FieldSet::new(&["parent_trait_ref",
                                                                "self_ty.kind"],
                                                    ::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};
                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&derived_obligation.parent_trait_pred)
                                                                    as &dyn Value)),
                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&ty.kind())
                                                                    as &dyn Value))])
                                    });
                            } else { ; }
                        };
                        match *ty.kind() {
                            ty::Coroutine(did, ..) | ty::CoroutineWitness(did, ..) => {
                                coroutine = coroutine.or(Some(did));
                                outer_coroutine = Some(did);
                            }
                            ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
                                seen_upvar_tys_infer_tuple = true;
                            }
                            _ if coroutine.is_none() => {
                                trait_ref =
                                    Some(derived_obligation.parent_trait_pred.skip_binder());
                                target_ty = Some(ty);
                            }
                            _ => {}
                        }
                        next_code = Some(&derived_obligation.parent_code);
                    }
                    _ => break,
                }
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3100",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(3100u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["coroutine",
                                                    "trait_ref", "target_ty"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&coroutine)
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&trait_ref)
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&target_ty)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let (Some(coroutine_did), Some(trait_ref), Some(target_ty)) =
                (coroutine, trait_ref, target_ty) else { return false; };
            let span = self.tcx.def_span(coroutine_did);
            let coroutine_did_root =
                self.tcx.typeck_root_def_id(coroutine_did);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3110",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(3110u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["coroutine_did",
                                                    "coroutine_did_root", "typeck_results.hir_owner", "span"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&coroutine_did)
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&coroutine_did_root)
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&self.typeck_results.as_ref().map(|t|
                                                                            t.hir_owner)) as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&span) as
                                                        &dyn Value))])
                        });
                } else { ; }
            };
            let coroutine_body =
                coroutine_did.as_local().and_then(|def_id|
                        self.tcx.hir_maybe_body_owned_by(def_id));
            let mut visitor = AwaitsVisitor::default();
            if let Some(body) = coroutine_body { visitor.visit_body(&body); }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3123",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(3123u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["awaits"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&visitor.awaits)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let target_ty_erased =
                self.tcx.erase_and_anonymize_regions(target_ty);
            let ty_matches =
                |ty| -> bool
                    {
                        let ty_erased =
                            self.tcx.instantiate_bound_regions_with_erased(ty);
                        let ty_erased =
                            self.tcx.erase_and_anonymize_regions(ty_erased);
                        let eq = ty_erased == target_ty_erased;
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3144",
                                                "rustc_trait_selection::error_reporting::traits::suggestions",
                                                ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                                ::tracing_core::__macro_support::Option::Some(3144u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                                ::tracing_core::field::FieldSet::new(&["ty_erased",
                                                                "target_ty_erased", "eq"],
                                                    ::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};
                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&ty_erased)
                                                                    as &dyn Value)),
                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&target_ty_erased)
                                                                    as &dyn Value)),
                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&eq) as
                                                                    &dyn Value))])
                                    });
                            } else { ; }
                        };
                        eq
                    };
            let coroutine_data =
                match &self.typeck_results {
                    Some(t) if t.hir_owner.to_def_id() == coroutine_did_root =>
                        CoroutineData(t),
                    _ if coroutine_did.is_local() => {
                        CoroutineData(self.tcx.typeck(coroutine_did.expect_local()))
                    }
                    _ => return false,
                };
            let coroutine_within_in_progress_typeck =
                match &self.typeck_results {
                    Some(t) => t.hir_owner.to_def_id() == coroutine_did_root,
                    _ => false,
                };
            let mut interior_or_upvar_span = None;
            let from_awaited_ty =
                coroutine_data.get_from_await_ty(visitor, self.tcx,
                    ty_matches);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3168",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(3168u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["from_awaited_ty"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&from_awaited_ty)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            if coroutine_did.is_local() &&
                        !coroutine_within_in_progress_typeck &&
                    let Some(coroutine_info) =
                        self.tcx.mir_coroutine_witnesses(coroutine_did) {
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3176",
                                        "rustc_trait_selection::error_reporting::traits::suggestions",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                        ::tracing_core::__macro_support::Option::Some(3176u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                        ::tracing_core::field::FieldSet::new(&["coroutine_info"],
                                            ::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};
                                let mut iter = __CALLSITE.metadata().fields().iter();
                                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&debug(&coroutine_info)
                                                            as &dyn Value))])
                            });
                    } else { ; }
                };
                'find_source:
                    for (variant, source_info) in
                    coroutine_info.variant_fields.iter().zip(&coroutine_info.variant_source_info)
                    {
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3180",
                                            "rustc_trait_selection::error_reporting::traits::suggestions",
                                            ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                            ::tracing_core::__macro_support::Option::Some(3180u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                            ::tracing_core::field::FieldSet::new(&["variant"],
                                                ::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};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&debug(&variant) as
                                                                &dyn Value))])
                                });
                        } else { ; }
                    };
                    for &local in variant {
                        let decl = &coroutine_info.field_tys[local];
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3183",
                                                "rustc_trait_selection::error_reporting::traits::suggestions",
                                                ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                                ::tracing_core::__macro_support::Option::Some(3183u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                                ::tracing_core::field::FieldSet::new(&["decl"],
                                                    ::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};
                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&decl) as
                                                                    &dyn Value))])
                                    });
                            } else { ; }
                        };
                        if ty_matches(ty::Binder::dummy(decl.ty)) &&
                                !decl.ignore_for_traits {
                            interior_or_upvar_span =
                                Some(CoroutineInteriorOrUpvar::Interior(decl.source_info.span,
                                        Some((source_info.span, from_awaited_ty))));
                            break 'find_source;
                        }
                    }
                }
            }
            if interior_or_upvar_span.is_none() {
                interior_or_upvar_span =
                    coroutine_data.try_get_upvar_span(self, coroutine_did,
                        ty_matches);
            }
            if interior_or_upvar_span.is_none() && !coroutine_did.is_local() {
                interior_or_upvar_span =
                    Some(CoroutineInteriorOrUpvar::Interior(span, None));
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3204",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(3204u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["interior_or_upvar_span"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&interior_or_upvar_span)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            if let Some(interior_or_upvar_span) = interior_or_upvar_span {
                let is_async = self.tcx.coroutine_is_async(coroutine_did);
                self.note_obligation_cause_for_async_await(err,
                    interior_or_upvar_span, is_async, outer_coroutine,
                    trait_ref, target_ty, obligation, next_code);
                true
            } else { false }
        }
    }
}#[instrument(level = "debug", skip_all, fields(?obligation.predicate, ?obligation.cause.span))]
2994    pub fn maybe_note_obligation_cause_for_async_await<G: EmissionGuarantee>(
2995        &self,
2996        err: &mut Diag<'_, G>,
2997        obligation: &PredicateObligation<'tcx>,
2998    ) -> bool {
2999        // Attempt to detect an async-await error by looking at the obligation causes, looking
3000        // for a coroutine to be present.
3001        //
3002        // When a future does not implement a trait because of a captured type in one of the
3003        // coroutines somewhere in the call stack, then the result is a chain of obligations.
3004        //
3005        // Given an `async fn` A that calls an `async fn` B which captures a non-send type and that
3006        // future is passed as an argument to a function C which requires a `Send` type, then the
3007        // chain looks something like this:
3008        //
3009        // - `BuiltinDerivedObligation` with a coroutine witness (B)
3010        // - `BuiltinDerivedObligation` with a coroutine (B)
3011        // - `BuiltinDerivedObligation` with `impl std::future::Future` (B)
3012        // - `BuiltinDerivedObligation` with a coroutine witness (A)
3013        // - `BuiltinDerivedObligation` with a coroutine (A)
3014        // - `BuiltinDerivedObligation` with `impl std::future::Future` (A)
3015        // - `BindingObligation` with `impl_send` (Send requirement)
3016        //
3017        // The first obligation in the chain is the most useful and has the coroutine that captured
3018        // the type. The last coroutine (`outer_coroutine` below) has information about where the
3019        // bound was introduced. At least one coroutine should be present for this diagnostic to be
3020        // modified.
3021        let (mut trait_ref, mut target_ty) = match obligation.predicate.kind().skip_binder() {
3022            ty::PredicateKind::Clause(ty::ClauseKind::Trait(p)) => (Some(p), Some(p.self_ty())),
3023            _ => (None, None),
3024        };
3025        let mut coroutine = None;
3026        let mut outer_coroutine = None;
3027        let mut next_code = Some(obligation.cause.code());
3028
3029        let mut seen_upvar_tys_infer_tuple = false;
3030
3031        while let Some(code) = next_code {
3032            debug!(?code);
3033            match code {
3034                ObligationCauseCode::FunctionArg { parent_code, .. } => {
3035                    next_code = Some(parent_code);
3036                }
3037                ObligationCauseCode::ImplDerived(cause) => {
3038                    let ty = cause.derived.parent_trait_pred.skip_binder().self_ty();
3039                    debug!(
3040                        parent_trait_ref = ?cause.derived.parent_trait_pred,
3041                        self_ty.kind = ?ty.kind(),
3042                        "ImplDerived",
3043                    );
3044
3045                    match *ty.kind() {
3046                        ty::Coroutine(did, ..) | ty::CoroutineWitness(did, _) => {
3047                            coroutine = coroutine.or(Some(did));
3048                            outer_coroutine = Some(did);
3049                        }
3050                        ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
3051                            // By introducing a tuple of upvar types into the chain of obligations
3052                            // of a coroutine, the first non-coroutine item is now the tuple itself,
3053                            // we shall ignore this.
3054
3055                            seen_upvar_tys_infer_tuple = true;
3056                        }
3057                        _ if coroutine.is_none() => {
3058                            trait_ref = Some(cause.derived.parent_trait_pred.skip_binder());
3059                            target_ty = Some(ty);
3060                        }
3061                        _ => {}
3062                    }
3063
3064                    next_code = Some(&cause.derived.parent_code);
3065                }
3066                ObligationCauseCode::WellFormedDerived(derived_obligation)
3067                | ObligationCauseCode::BuiltinDerived(derived_obligation) => {
3068                    let ty = derived_obligation.parent_trait_pred.skip_binder().self_ty();
3069                    debug!(
3070                        parent_trait_ref = ?derived_obligation.parent_trait_pred,
3071                        self_ty.kind = ?ty.kind(),
3072                    );
3073
3074                    match *ty.kind() {
3075                        ty::Coroutine(did, ..) | ty::CoroutineWitness(did, ..) => {
3076                            coroutine = coroutine.or(Some(did));
3077                            outer_coroutine = Some(did);
3078                        }
3079                        ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
3080                            // By introducing a tuple of upvar types into the chain of obligations
3081                            // of a coroutine, the first non-coroutine item is now the tuple itself,
3082                            // we shall ignore this.
3083
3084                            seen_upvar_tys_infer_tuple = true;
3085                        }
3086                        _ if coroutine.is_none() => {
3087                            trait_ref = Some(derived_obligation.parent_trait_pred.skip_binder());
3088                            target_ty = Some(ty);
3089                        }
3090                        _ => {}
3091                    }
3092
3093                    next_code = Some(&derived_obligation.parent_code);
3094                }
3095                _ => break,
3096            }
3097        }
3098
3099        // Only continue if a coroutine was found.
3100        debug!(?coroutine, ?trait_ref, ?target_ty);
3101        let (Some(coroutine_did), Some(trait_ref), Some(target_ty)) =
3102            (coroutine, trait_ref, target_ty)
3103        else {
3104            return false;
3105        };
3106
3107        let span = self.tcx.def_span(coroutine_did);
3108
3109        let coroutine_did_root = self.tcx.typeck_root_def_id(coroutine_did);
3110        debug!(
3111            ?coroutine_did,
3112            ?coroutine_did_root,
3113            typeck_results.hir_owner = ?self.typeck_results.as_ref().map(|t| t.hir_owner),
3114            ?span,
3115        );
3116
3117        let coroutine_body =
3118            coroutine_did.as_local().and_then(|def_id| self.tcx.hir_maybe_body_owned_by(def_id));
3119        let mut visitor = AwaitsVisitor::default();
3120        if let Some(body) = coroutine_body {
3121            visitor.visit_body(&body);
3122        }
3123        debug!(awaits = ?visitor.awaits);
3124
3125        // Look for a type inside the coroutine interior that matches the target type to get
3126        // a span.
3127        let target_ty_erased = self.tcx.erase_and_anonymize_regions(target_ty);
3128        let ty_matches = |ty| -> bool {
3129            // Careful: the regions for types that appear in the
3130            // coroutine interior are not generally known, so we
3131            // want to erase them when comparing (and anyway,
3132            // `Send` and other bounds are generally unaffected by
3133            // the choice of region). When erasing regions, we
3134            // also have to erase late-bound regions. This is
3135            // because the types that appear in the coroutine
3136            // interior generally contain "bound regions" to
3137            // represent regions that are part of the suspended
3138            // coroutine frame. Bound regions are preserved by
3139            // `erase_and_anonymize_regions` and so we must also call
3140            // `instantiate_bound_regions_with_erased`.
3141            let ty_erased = self.tcx.instantiate_bound_regions_with_erased(ty);
3142            let ty_erased = self.tcx.erase_and_anonymize_regions(ty_erased);
3143            let eq = ty_erased == target_ty_erased;
3144            debug!(?ty_erased, ?target_ty_erased, ?eq);
3145            eq
3146        };
3147
3148        // Get the typeck results from the infcx if the coroutine is the function we are currently
3149        // type-checking; otherwise, get them by performing a query. This is needed to avoid
3150        // cycles. If we can't use resolved types because the coroutine comes from another crate,
3151        // we still provide a targeted error but without all the relevant spans.
3152        let coroutine_data = match &self.typeck_results {
3153            Some(t) if t.hir_owner.to_def_id() == coroutine_did_root => CoroutineData(t),
3154            _ if coroutine_did.is_local() => {
3155                CoroutineData(self.tcx.typeck(coroutine_did.expect_local()))
3156            }
3157            _ => return false,
3158        };
3159
3160        let coroutine_within_in_progress_typeck = match &self.typeck_results {
3161            Some(t) => t.hir_owner.to_def_id() == coroutine_did_root,
3162            _ => false,
3163        };
3164
3165        let mut interior_or_upvar_span = None;
3166
3167        let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, self.tcx, ty_matches);
3168        debug!(?from_awaited_ty);
3169
3170        // Avoid disclosing internal information to downstream crates.
3171        if coroutine_did.is_local()
3172            // Try to avoid cycles.
3173            && !coroutine_within_in_progress_typeck
3174            && let Some(coroutine_info) = self.tcx.mir_coroutine_witnesses(coroutine_did)
3175        {
3176            debug!(?coroutine_info);
3177            'find_source: for (variant, source_info) in
3178                coroutine_info.variant_fields.iter().zip(&coroutine_info.variant_source_info)
3179            {
3180                debug!(?variant);
3181                for &local in variant {
3182                    let decl = &coroutine_info.field_tys[local];
3183                    debug!(?decl);
3184                    if ty_matches(ty::Binder::dummy(decl.ty)) && !decl.ignore_for_traits {
3185                        interior_or_upvar_span = Some(CoroutineInteriorOrUpvar::Interior(
3186                            decl.source_info.span,
3187                            Some((source_info.span, from_awaited_ty)),
3188                        ));
3189                        break 'find_source;
3190                    }
3191                }
3192            }
3193        }
3194
3195        if interior_or_upvar_span.is_none() {
3196            interior_or_upvar_span =
3197                coroutine_data.try_get_upvar_span(self, coroutine_did, ty_matches);
3198        }
3199
3200        if interior_or_upvar_span.is_none() && !coroutine_did.is_local() {
3201            interior_or_upvar_span = Some(CoroutineInteriorOrUpvar::Interior(span, None));
3202        }
3203
3204        debug!(?interior_or_upvar_span);
3205        if let Some(interior_or_upvar_span) = interior_or_upvar_span {
3206            let is_async = self.tcx.coroutine_is_async(coroutine_did);
3207            self.note_obligation_cause_for_async_await(
3208                err,
3209                interior_or_upvar_span,
3210                is_async,
3211                outer_coroutine,
3212                trait_ref,
3213                target_ty,
3214                obligation,
3215                next_code,
3216            );
3217            true
3218        } else {
3219            false
3220        }
3221    }
3222
3223    /// Unconditionally adds the diagnostic note described in
3224    /// `maybe_note_obligation_cause_for_async_await`'s documentation comment.
3225    #[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("note_obligation_cause_for_async_await",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(3225u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::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,
                        &{ meta.fields().value_set(&[]) })
                } 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: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let source_map = self.tcx.sess.source_map();
            let (await_or_yield, an_await_or_yield) =
                if is_async {
                    ("await", "an await")
                } else { ("yield", "a yield") };
            let future_or_coroutine =
                if is_async { "future" } else { "coroutine" };
            let trait_explanation =
                if let Some(name @ (sym::Send | sym::Sync)) =
                        self.tcx.get_diagnostic_name(trait_pred.def_id()) {
                    let (trait_name, trait_verb) =
                        if name == sym::Send {
                            ("`Send`", "sent")
                        } else { ("`Sync`", "shared") };
                    err.code = None;
                    err.primary_message(::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0} cannot be {1} between threads safely",
                                        future_or_coroutine, trait_verb))
                            }));
                    let original_span = err.span.primary_span().unwrap();
                    let mut span = MultiSpan::from_span(original_span);
                    let message =
                        outer_coroutine.and_then(|coroutine_did|
                                    {
                                        Some(match self.tcx.coroutine_kind(coroutine_did).unwrap() {
                                                CoroutineKind::Coroutine(_) =>
                                                    ::alloc::__export::must_use({
                                                            ::alloc::fmt::format(format_args!("coroutine is not {0}",
                                                                    trait_name))
                                                        }),
                                                CoroutineKind::Desugared(CoroutineDesugaring::Async,
                                                    CoroutineSource::Fn) =>
                                                    self.tcx.parent(coroutine_did).as_local().map(|parent_did|
                                                                        self.tcx.local_def_id_to_hir_id(parent_did)).and_then(|parent_hir_id|
                                                                    self.tcx.hir_opt_name(parent_hir_id)).map(|name|
                                                                {
                                                                    ::alloc::__export::must_use({
                                                                            ::alloc::fmt::format(format_args!("future returned by `{0}` is not {1}",
                                                                                    name, trait_name))
                                                                        })
                                                                })?,
                                                CoroutineKind::Desugared(CoroutineDesugaring::Async,
                                                    CoroutineSource::Block) => {
                                                    ::alloc::__export::must_use({
                                                            ::alloc::fmt::format(format_args!("future created by async block is not {0}",
                                                                    trait_name))
                                                        })
                                                }
                                                CoroutineKind::Desugared(CoroutineDesugaring::Async,
                                                    CoroutineSource::Closure) => {
                                                    ::alloc::__export::must_use({
                                                            ::alloc::fmt::format(format_args!("future created by async closure is not {0}",
                                                                    trait_name))
                                                        })
                                                }
                                                CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen,
                                                    CoroutineSource::Fn) =>
                                                    self.tcx.parent(coroutine_did).as_local().map(|parent_did|
                                                                        self.tcx.local_def_id_to_hir_id(parent_did)).and_then(|parent_hir_id|
                                                                    self.tcx.hir_opt_name(parent_hir_id)).map(|name|
                                                                {
                                                                    ::alloc::__export::must_use({
                                                                            ::alloc::fmt::format(format_args!("async iterator returned by `{0}` is not {1}",
                                                                                    name, trait_name))
                                                                        })
                                                                })?,
                                                CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen,
                                                    CoroutineSource::Block) => {
                                                    ::alloc::__export::must_use({
                                                            ::alloc::fmt::format(format_args!("async iterator created by async gen block is not {0}",
                                                                    trait_name))
                                                        })
                                                }
                                                CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen,
                                                    CoroutineSource::Closure) => {
                                                    ::alloc::__export::must_use({
                                                            ::alloc::fmt::format(format_args!("async iterator created by async gen closure is not {0}",
                                                                    trait_name))
                                                        })
                                                }
                                                CoroutineKind::Desugared(CoroutineDesugaring::Gen,
                                                    CoroutineSource::Fn) => {
                                                    self.tcx.parent(coroutine_did).as_local().map(|parent_did|
                                                                        self.tcx.local_def_id_to_hir_id(parent_did)).and_then(|parent_hir_id|
                                                                    self.tcx.hir_opt_name(parent_hir_id)).map(|name|
                                                                {
                                                                    ::alloc::__export::must_use({
                                                                            ::alloc::fmt::format(format_args!("iterator returned by `{0}` is not {1}",
                                                                                    name, trait_name))
                                                                        })
                                                                })?
                                                }
                                                CoroutineKind::Desugared(CoroutineDesugaring::Gen,
                                                    CoroutineSource::Block) => {
                                                    ::alloc::__export::must_use({
                                                            ::alloc::fmt::format(format_args!("iterator created by gen block is not {0}",
                                                                    trait_name))
                                                        })
                                                }
                                                CoroutineKind::Desugared(CoroutineDesugaring::Gen,
                                                    CoroutineSource::Closure) => {
                                                    ::alloc::__export::must_use({
                                                            ::alloc::fmt::format(format_args!("iterator created by gen closure is not {0}",
                                                                    trait_name))
                                                        })
                                                }
                                            })
                                    }).unwrap_or_else(||
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("{0} is not {1}",
                                                future_or_coroutine, trait_name))
                                    }));
                    span.push_span_label(original_span, message);
                    err.span(span);
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("is not {0}", trait_name))
                        })
                } else {
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("does not implement `{0}`",
                                    trait_pred.print_modifiers_and_trait_path()))
                        })
                };
            let mut explain_yield =
                |interior_span: Span, yield_span: Span|
                    {
                        let mut span = MultiSpan::from_span(yield_span);
                        let snippet =
                            match source_map.span_to_snippet(interior_span) {
                                Ok(snippet) if !snippet.contains('\n') =>
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("`{0}`", snippet))
                                        }),
                                _ => "the value".to_string(),
                            };
                        span.push_span_label(yield_span,
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("{0} occurs here, with {1} maybe used later",
                                            await_or_yield, snippet))
                                }));
                        span.push_span_label(interior_span,
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("has type `{0}` which {1}",
                                            target_ty, trait_explanation))
                                }));
                        err.span_note(span,
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("{0} {1} as this value is used across {2}",
                                            future_or_coroutine, trait_explanation, an_await_or_yield))
                                }));
                    };
            match interior_or_upvar_span {
                CoroutineInteriorOrUpvar::Interior(interior_span,
                    interior_extra_info) => {
                    if let Some((yield_span, from_awaited_ty)) =
                            interior_extra_info {
                        if let Some(await_span) = from_awaited_ty {
                            let mut span = MultiSpan::from_span(await_span);
                            span.push_span_label(await_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("await occurs here on type `{0}`, which {1}",
                                                target_ty, trait_explanation))
                                    }));
                            err.span_note(span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("future {0} as it awaits another future which {0}",
                                                trait_explanation))
                                    }));
                        } else { explain_yield(interior_span, yield_span); }
                    }
                }
                CoroutineInteriorOrUpvar::Upvar(upvar_span) => {
                    let non_send =
                        match target_ty.kind() {
                            ty::Ref(_, ref_ty, mutability) =>
                                match self.evaluate_obligation(obligation) {
                                    Ok(eval) if !eval.may_apply() =>
                                        Some((ref_ty, mutability.is_mut())),
                                    _ => None,
                                },
                            _ => None,
                        };
                    let (span_label, span_note) =
                        match non_send {
                            Some((ref_ty, is_mut)) => {
                                let ref_ty_trait = if is_mut { "Send" } else { "Sync" };
                                let ref_kind = if is_mut { "&mut" } else { "&" };
                                (::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("has type `{0}` which {1}, because `{2}` is not `{3}`",
                                                    target_ty, trait_explanation, ref_ty, ref_ty_trait))
                                        }),
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("captured value {0} because `{1}` references cannot be sent unless their referent is `{2}`",
                                                    trait_explanation, ref_kind, ref_ty_trait))
                                        }))
                            }
                            None =>
                                (::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("has type `{0}` which {1}",
                                                    target_ty, trait_explanation))
                                        }),
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("captured value {0}",
                                                    trait_explanation))
                                        })),
                        };
                    let mut span = MultiSpan::from_span(upvar_span);
                    span.push_span_label(upvar_span, span_label);
                    err.span_note(span, span_note);
                }
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:3448",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(3448u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["next_code"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&next_code)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            self.note_obligation_cause_code(obligation.cause.body_id, err,
                obligation.predicate, obligation.param_env,
                next_code.unwrap(), &mut Vec::new(), &mut Default::default());
        }
    }
}#[instrument(level = "debug", skip_all)]
3226    fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
3227        &self,
3228        err: &mut Diag<'_, G>,
3229        interior_or_upvar_span: CoroutineInteriorOrUpvar,
3230        is_async: bool,
3231        outer_coroutine: Option<DefId>,
3232        trait_pred: ty::TraitPredicate<'tcx>,
3233        target_ty: Ty<'tcx>,
3234        obligation: &PredicateObligation<'tcx>,
3235        next_code: Option<&ObligationCauseCode<'tcx>>,
3236    ) {
3237        let source_map = self.tcx.sess.source_map();
3238
3239        let (await_or_yield, an_await_or_yield) =
3240            if is_async { ("await", "an await") } else { ("yield", "a yield") };
3241        let future_or_coroutine = if is_async { "future" } else { "coroutine" };
3242
3243        // Special case the primary error message when send or sync is the trait that was
3244        // not implemented.
3245        let trait_explanation = if let Some(name @ (sym::Send | sym::Sync)) =
3246            self.tcx.get_diagnostic_name(trait_pred.def_id())
3247        {
3248            let (trait_name, trait_verb) =
3249                if name == sym::Send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
3250
3251            err.code = None;
3252            err.primary_message(format!(
3253                "{future_or_coroutine} cannot be {trait_verb} between threads safely"
3254            ));
3255
3256            let original_span = err.span.primary_span().unwrap();
3257            let mut span = MultiSpan::from_span(original_span);
3258
3259            let message = outer_coroutine
3260                .and_then(|coroutine_did| {
3261                    Some(match self.tcx.coroutine_kind(coroutine_did).unwrap() {
3262                        CoroutineKind::Coroutine(_) => format!("coroutine is not {trait_name}"),
3263                        CoroutineKind::Desugared(
3264                            CoroutineDesugaring::Async,
3265                            CoroutineSource::Fn,
3266                        ) => self
3267                            .tcx
3268                            .parent(coroutine_did)
3269                            .as_local()
3270                            .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did))
3271                            .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id))
3272                            .map(|name| {
3273                                format!("future returned by `{name}` is not {trait_name}")
3274                            })?,
3275                        CoroutineKind::Desugared(
3276                            CoroutineDesugaring::Async,
3277                            CoroutineSource::Block,
3278                        ) => {
3279                            format!("future created by async block is not {trait_name}")
3280                        }
3281                        CoroutineKind::Desugared(
3282                            CoroutineDesugaring::Async,
3283                            CoroutineSource::Closure,
3284                        ) => {
3285                            format!("future created by async closure is not {trait_name}")
3286                        }
3287                        CoroutineKind::Desugared(
3288                            CoroutineDesugaring::AsyncGen,
3289                            CoroutineSource::Fn,
3290                        ) => self
3291                            .tcx
3292                            .parent(coroutine_did)
3293                            .as_local()
3294                            .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did))
3295                            .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id))
3296                            .map(|name| {
3297                                format!("async iterator returned by `{name}` is not {trait_name}")
3298                            })?,
3299                        CoroutineKind::Desugared(
3300                            CoroutineDesugaring::AsyncGen,
3301                            CoroutineSource::Block,
3302                        ) => {
3303                            format!("async iterator created by async gen block is not {trait_name}")
3304                        }
3305                        CoroutineKind::Desugared(
3306                            CoroutineDesugaring::AsyncGen,
3307                            CoroutineSource::Closure,
3308                        ) => {
3309                            format!(
3310                                "async iterator created by async gen closure is not {trait_name}"
3311                            )
3312                        }
3313                        CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Fn) => {
3314                            self.tcx
3315                                .parent(coroutine_did)
3316                                .as_local()
3317                                .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did))
3318                                .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id))
3319                                .map(|name| {
3320                                    format!("iterator returned by `{name}` is not {trait_name}")
3321                                })?
3322                        }
3323                        CoroutineKind::Desugared(
3324                            CoroutineDesugaring::Gen,
3325                            CoroutineSource::Block,
3326                        ) => {
3327                            format!("iterator created by gen block is not {trait_name}")
3328                        }
3329                        CoroutineKind::Desugared(
3330                            CoroutineDesugaring::Gen,
3331                            CoroutineSource::Closure,
3332                        ) => {
3333                            format!("iterator created by gen closure is not {trait_name}")
3334                        }
3335                    })
3336                })
3337                .unwrap_or_else(|| format!("{future_or_coroutine} is not {trait_name}"));
3338
3339            span.push_span_label(original_span, message);
3340            err.span(span);
3341
3342            format!("is not {trait_name}")
3343        } else {
3344            format!("does not implement `{}`", trait_pred.print_modifiers_and_trait_path())
3345        };
3346
3347        let mut explain_yield = |interior_span: Span, yield_span: Span| {
3348            let mut span = MultiSpan::from_span(yield_span);
3349            let snippet = match source_map.span_to_snippet(interior_span) {
3350                // #70935: If snippet contains newlines, display "the value" instead
3351                // so that we do not emit complex diagnostics.
3352                Ok(snippet) if !snippet.contains('\n') => format!("`{snippet}`"),
3353                _ => "the value".to_string(),
3354            };
3355            // note: future is not `Send` as this value is used across an await
3356            //   --> $DIR/issue-70935-complex-spans.rs:13:9
3357            //    |
3358            // LL |            baz(|| async {
3359            //    |  ______________-
3360            //    | |
3361            //    | |
3362            // LL | |              foo(tx.clone());
3363            // LL | |          }).await;
3364            //    | |          - ^^^^^^ await occurs here, with value maybe used later
3365            //    | |__________|
3366            //    |            has type `closure` which is not `Send`
3367            // note: value is later dropped here
3368            // LL | |          }).await;
3369            //    | |                  ^
3370            //
3371            span.push_span_label(
3372                yield_span,
3373                format!("{await_or_yield} occurs here, with {snippet} maybe used later"),
3374            );
3375            span.push_span_label(
3376                interior_span,
3377                format!("has type `{target_ty}` which {trait_explanation}"),
3378            );
3379            err.span_note(
3380                span,
3381                format!("{future_or_coroutine} {trait_explanation} as this value is used across {an_await_or_yield}"),
3382            );
3383        };
3384        match interior_or_upvar_span {
3385            CoroutineInteriorOrUpvar::Interior(interior_span, interior_extra_info) => {
3386                if let Some((yield_span, from_awaited_ty)) = interior_extra_info {
3387                    if let Some(await_span) = from_awaited_ty {
3388                        // The type causing this obligation is one being awaited at await_span.
3389                        let mut span = MultiSpan::from_span(await_span);
3390                        span.push_span_label(
3391                            await_span,
3392                            format!(
3393                                "await occurs here on type `{target_ty}`, which {trait_explanation}"
3394                            ),
3395                        );
3396                        err.span_note(
3397                            span,
3398                            format!(
3399                                "future {trait_explanation} as it awaits another future which {trait_explanation}"
3400                            ),
3401                        );
3402                    } else {
3403                        // Look at the last interior type to get a span for the `.await`.
3404                        explain_yield(interior_span, yield_span);
3405                    }
3406                }
3407            }
3408            CoroutineInteriorOrUpvar::Upvar(upvar_span) => {
3409                // `Some((ref_ty, is_mut))` if `target_ty` is `&T` or `&mut T` and fails to impl `Send`
3410                let non_send = match target_ty.kind() {
3411                    ty::Ref(_, ref_ty, mutability) => match self.evaluate_obligation(obligation) {
3412                        Ok(eval) if !eval.may_apply() => Some((ref_ty, mutability.is_mut())),
3413                        _ => None,
3414                    },
3415                    _ => None,
3416                };
3417
3418                let (span_label, span_note) = match non_send {
3419                    // if `target_ty` is `&T` or `&mut T` and fails to impl `Send`,
3420                    // include suggestions to make `T: Sync` so that `&T: Send`,
3421                    // or to make `T: Send` so that `&mut T: Send`
3422                    Some((ref_ty, is_mut)) => {
3423                        let ref_ty_trait = if is_mut { "Send" } else { "Sync" };
3424                        let ref_kind = if is_mut { "&mut" } else { "&" };
3425                        (
3426                            format!(
3427                                "has type `{target_ty}` which {trait_explanation}, because `{ref_ty}` is not `{ref_ty_trait}`"
3428                            ),
3429                            format!(
3430                                "captured value {trait_explanation} because `{ref_kind}` references cannot be sent unless their referent is `{ref_ty_trait}`"
3431                            ),
3432                        )
3433                    }
3434                    None => (
3435                        format!("has type `{target_ty}` which {trait_explanation}"),
3436                        format!("captured value {trait_explanation}"),
3437                    ),
3438                };
3439
3440                let mut span = MultiSpan::from_span(upvar_span);
3441                span.push_span_label(upvar_span, span_label);
3442                err.span_note(span, span_note);
3443            }
3444        }
3445
3446        // Add a note for the item obligation that remains - normally a note pointing to the
3447        // bound that introduced the obligation (e.g. `T: Send`).
3448        debug!(?next_code);
3449        self.note_obligation_cause_code(
3450            obligation.cause.body_id,
3451            err,
3452            obligation.predicate,
3453            obligation.param_env,
3454            next_code.unwrap(),
3455            &mut Vec::new(),
3456            &mut Default::default(),
3457        );
3458    }
3459
3460    pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
3461        &self,
3462        body_id: LocalDefId,
3463        err: &mut Diag<'_, G>,
3464        predicate: T,
3465        param_env: ty::ParamEnv<'tcx>,
3466        cause_code: &ObligationCauseCode<'tcx>,
3467        obligated_types: &mut Vec<Ty<'tcx>>,
3468        seen_requirements: &mut FxHashSet<DefId>,
3469    ) where
3470        T: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
3471    {
3472        let tcx = self.tcx;
3473        let predicate = predicate.upcast(tcx);
3474        let suggest_remove_deref = |err: &mut Diag<'_, G>, expr: &hir::Expr<'_>| {
3475            if let Some(pred) = predicate.as_trait_clause()
3476                && tcx.is_lang_item(pred.def_id(), LangItem::Sized)
3477                && let hir::ExprKind::Unary(hir::UnOp::Deref, inner) = expr.kind
3478            {
3479                err.span_suggestion_verbose(
3480                    expr.span.until(inner.span),
3481                    "references are always `Sized`, even if they point to unsized data; consider \
3482                     not dereferencing the expression",
3483                    String::new(),
3484                    Applicability::MaybeIncorrect,
3485                );
3486            }
3487        };
3488        match *cause_code {
3489            ObligationCauseCode::ExprAssignable
3490            | ObligationCauseCode::MatchExpressionArm { .. }
3491            | ObligationCauseCode::Pattern { .. }
3492            | ObligationCauseCode::IfExpression { .. }
3493            | ObligationCauseCode::IfExpressionWithNoElse
3494            | ObligationCauseCode::MainFunctionType
3495            | ObligationCauseCode::LangFunctionType(_)
3496            | ObligationCauseCode::IntrinsicType
3497            | ObligationCauseCode::MethodReceiver
3498            | ObligationCauseCode::ReturnNoExpression
3499            | ObligationCauseCode::Misc
3500            | ObligationCauseCode::WellFormed(..)
3501            | ObligationCauseCode::MatchImpl(..)
3502            | ObligationCauseCode::ReturnValue(_)
3503            | ObligationCauseCode::BlockTailExpression(..)
3504            | ObligationCauseCode::AwaitableExpr(_)
3505            | ObligationCauseCode::ForLoopIterator
3506            | ObligationCauseCode::QuestionMark
3507            | ObligationCauseCode::CheckAssociatedTypeBounds { .. }
3508            | ObligationCauseCode::LetElse
3509            | ObligationCauseCode::UnOp { .. }
3510            | ObligationCauseCode::AscribeUserTypeProvePredicate(..)
3511            | ObligationCauseCode::AlwaysApplicableImpl
3512            | ObligationCauseCode::ConstParam(_)
3513            | ObligationCauseCode::ReferenceOutlivesReferent(..)
3514            | ObligationCauseCode::ObjectTypeBound(..) => {}
3515            ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, .. } => {
3516                if let hir::Node::Expr(lhs) = tcx.hir_node(lhs_hir_id)
3517                    && let hir::Node::Expr(rhs) = tcx.hir_node(rhs_hir_id)
3518                    && tcx.sess.source_map().lookup_char_pos(lhs.span.lo()).line
3519                        != tcx.sess.source_map().lookup_char_pos(rhs.span.hi()).line
3520                {
3521                    err.span_label(lhs.span, "");
3522                    err.span_label(rhs.span, "");
3523                }
3524            }
3525            ObligationCauseCode::RustCall => {
3526                if let Some(pred) = predicate.as_trait_clause()
3527                    && tcx.is_lang_item(pred.def_id(), LangItem::Sized)
3528                {
3529                    err.note("argument required to be sized due to `extern \"rust-call\"` ABI");
3530                }
3531            }
3532            ObligationCauseCode::SliceOrArrayElem => {
3533                err.note("slice and array elements must have `Sized` type");
3534            }
3535            ObligationCauseCode::ArrayLen(array_ty) => {
3536                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the length of array `{0}` must be type `usize`",
                array_ty))
    })format!("the length of array `{array_ty}` must be type `usize`"));
3537            }
3538            ObligationCauseCode::TupleElem => {
3539                err.note("only the last element of a tuple may have a dynamically sized type");
3540            }
3541            ObligationCauseCode::DynCompatible(span) => {
3542                err.multipart_suggestion(
3543                    "you might have meant to use `Self` to refer to the implementing type",
3544                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span, "Self".into())]))vec![(span, "Self".into())],
3545                    Applicability::MachineApplicable,
3546                );
3547            }
3548            ObligationCauseCode::WhereClause(item_def_id, span)
3549            | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)
3550            | ObligationCauseCode::HostEffectInExpr(item_def_id, span, ..)
3551                if !span.is_dummy() =>
3552            {
3553                if let ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, pos) = &cause_code {
3554                    if let Node::Expr(expr) = tcx.parent_hir_node(*hir_id)
3555                        && let hir::ExprKind::Call(_, args) = expr.kind
3556                        && let Some(expr) = args.get(*pos)
3557                    {
3558                        suggest_remove_deref(err, &expr);
3559                    } else if let Node::Expr(expr) = self.tcx.hir_node(*hir_id)
3560                        && let hir::ExprKind::MethodCall(_, _, args, _) = expr.kind
3561                        && let Some(expr) = args.get(*pos)
3562                    {
3563                        suggest_remove_deref(err, &expr);
3564                    }
3565                }
3566                let item_name = tcx.def_path_str(item_def_id);
3567                let short_item_name = { let _guard = ForceTrimmedGuard::new(); tcx.def_path_str(item_def_id) }with_forced_trimmed_paths!(tcx.def_path_str(item_def_id));
3568                let mut multispan = MultiSpan::from(span);
3569                let sm = tcx.sess.source_map();
3570                if let Some(ident) = tcx.opt_item_ident(item_def_id) {
3571                    let same_line =
3572                        match (sm.lookup_line(ident.span.hi()), sm.lookup_line(span.lo())) {
3573                            (Ok(l), Ok(r)) => l.line == r.line,
3574                            _ => true,
3575                        };
3576                    if ident.span.is_visible(sm) && !ident.span.overlaps(span) && !same_line {
3577                        multispan.push_span_label(
3578                            ident.span,
3579                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required by a bound in this {0}",
                tcx.def_kind(item_def_id).descr(item_def_id)))
    })format!(
3580                                "required by a bound in this {}",
3581                                tcx.def_kind(item_def_id).descr(item_def_id)
3582                            ),
3583                        );
3584                    }
3585                }
3586                let mut a = "a";
3587                let mut this = "this bound";
3588                let mut note = None;
3589                let mut help = None;
3590                if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() {
3591                    match clause {
3592                        ty::ClauseKind::Trait(trait_pred) => {
3593                            let def_id = trait_pred.def_id();
3594                            let visible_item = if let Some(local) = def_id.as_local() {
3595                                let ty = trait_pred.self_ty();
3596                                // when `TraitA: TraitB` and `S` only impl TraitA,
3597                                // we check if `TraitB` can be reachable from `S`
3598                                // to determine whether to note `TraitA` is sealed trait.
3599                                if let ty::Adt(adt, _) = ty.kind() {
3600                                    let visibilities = &tcx.resolutions(()).effective_visibilities;
3601                                    visibilities.effective_vis(local).is_none_or(|v| {
3602                                        v.at_level(Level::Reexported)
3603                                            .is_accessible_from(adt.did(), tcx)
3604                                    })
3605                                } else {
3606                                    // FIXME(xizheyin): if the type is not ADT, we should not suggest it
3607                                    true
3608                                }
3609                            } else {
3610                                // Check for foreign traits being reachable.
3611                                tcx.visible_parent_map(()).get(&def_id).is_some()
3612                            };
3613                            if tcx.is_lang_item(def_id, LangItem::Sized) {
3614                                // Check if this is an implicit bound, even in foreign crates.
3615                                if tcx
3616                                    .generics_of(item_def_id)
3617                                    .own_params
3618                                    .iter()
3619                                    .any(|param| tcx.def_span(param.def_id) == span)
3620                                {
3621                                    a = "an implicit `Sized`";
3622                                    this =
3623                                        "the implicit `Sized` requirement on this type parameter";
3624                                }
3625                                if let Some(hir::Node::TraitItem(hir::TraitItem {
3626                                    generics,
3627                                    kind: hir::TraitItemKind::Type(bounds, None),
3628                                    ..
3629                                })) = tcx.hir_get_if_local(item_def_id)
3630                                    // Do not suggest relaxing if there is an explicit `Sized` obligation.
3631                                    && !bounds.iter()
3632                                        .filter_map(|bound| bound.trait_ref())
3633                                        .any(|tr| tr.trait_def_id().is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Sized)))
3634                                {
3635                                    let (span, separator) = if let [.., last] = bounds {
3636                                        (last.span().shrink_to_hi(), " +")
3637                                    } else {
3638                                        (generics.span.shrink_to_hi(), ":")
3639                                    };
3640                                    err.span_suggestion_verbose(
3641                                        span,
3642                                        "consider relaxing the implicit `Sized` restriction",
3643                                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} ?Sized", separator))
    })format!("{separator} ?Sized"),
3644                                        Applicability::MachineApplicable,
3645                                    );
3646                                }
3647                            }
3648                            if let DefKind::Trait = tcx.def_kind(item_def_id)
3649                                && !visible_item
3650                            {
3651                                note = Some(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{1}` is a \"sealed trait\", because to implement it you also need to implement `{0}`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it",
                {
                    let _guard = NoTrimmedGuard::new();
                    tcx.def_path_str(def_id)
                }, short_item_name))
    })format!(
3652                                    "`{short_item_name}` is a \"sealed trait\", because to implement it \
3653                                    you also need to implement `{}`, which is not accessible; this is \
3654                                    usually done to force you to use one of the provided types that \
3655                                    already implement it",
3656                                    with_no_trimmed_paths!(tcx.def_path_str(def_id)),
3657                                ));
3658                                let mut types = tcx
3659                                    .all_impls(def_id)
3660                                    .map(|t| {
3661                                        {
    let _guard = NoTrimmedGuard::new();
    ::alloc::__export::must_use({
            ::alloc::fmt::format(format_args!("  {0}",
                    tcx.type_of(t).instantiate_identity().skip_norm_wip()))
        })
}with_no_trimmed_paths!(format!(
3662                                            "  {}",
3663                                            tcx.type_of(t).instantiate_identity().skip_norm_wip(),
3664                                        ))
3665                                    })
3666                                    .collect::<Vec<_>>();
3667                                if !types.is_empty() {
3668                                    let len = types.len();
3669                                    let post = if len > 9 {
3670                                        types.truncate(8);
3671                                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("\nand {0} others", len - 8))
    })format!("\nand {} others", len - 8)
3672                                    } else {
3673                                        String::new()
3674                                    };
3675                                    help = Some(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the following type{0} implement{1} the trait:\n{2}{3}",
                if len == 1 { "" } else { "s" },
                if len == 1 { "s" } else { "" }, types.join("\n"), post))
    })format!(
3676                                        "the following type{} implement{} the trait:\n{}{post}",
3677                                        pluralize!(len),
3678                                        if len == 1 { "s" } else { "" },
3679                                        types.join("\n"),
3680                                    ));
3681                                }
3682                            }
3683                        }
3684                        ty::ClauseKind::ConstArgHasType(..) => {
3685                            let descr =
3686                                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required by a const generic parameter in `{0}`",
                item_name))
    })format!("required by a const generic parameter in `{item_name}`");
3687                            if span.is_visible(sm) {
3688                                let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required by this const generic parameter in `{0}`",
                short_item_name))
    })format!(
3689                                    "required by this const generic parameter in `{short_item_name}`"
3690                                );
3691                                multispan.push_span_label(span, msg);
3692                                err.span_note(multispan, descr);
3693                            } else {
3694                                err.span_note(tcx.def_span(item_def_id), descr);
3695                            }
3696                            return;
3697                        }
3698                        _ => (),
3699                    }
3700                }
3701
3702                // If this is from a format string literal desugaring,
3703                // we've already said "required by this formatting parameter"
3704                let is_in_fmt_lit = if let Some(s) = err.span.primary_span() {
3705                    #[allow(non_exhaustive_omitted_patterns)] match s.desugaring_kind() {
    Some(DesugaringKind::FormatLiteral { .. }) => true,
    _ => false,
}matches!(s.desugaring_kind(), Some(DesugaringKind::FormatLiteral { .. }))
3706                } else {
3707                    false
3708                };
3709                if !is_in_fmt_lit {
3710                    let descr = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required by {0} bound in `{1}`", a,
                item_name))
    })format!("required by {a} bound in `{item_name}`");
3711                    if span.is_visible(sm) {
3712                        let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required by {0} in `{1}`", this,
                short_item_name))
    })format!("required by {this} in `{short_item_name}`");
3713                        multispan.push_span_label(span, msg);
3714                        err.span_note(multispan, descr);
3715                    } else {
3716                        err.span_note(tcx.def_span(item_def_id), descr);
3717                    }
3718                }
3719                if let Some(note) = note {
3720                    err.note(note);
3721                }
3722                if let Some(help) = help {
3723                    err.help(help);
3724                }
3725            }
3726            ObligationCauseCode::WhereClause(..)
3727            | ObligationCauseCode::WhereClauseInExpr(..)
3728            | ObligationCauseCode::HostEffectInExpr(..) => {
3729                // We hold the `DefId` of the item introducing the obligation, but displaying it
3730                // doesn't add user usable information. It always point at an associated item.
3731            }
3732            ObligationCauseCode::OpaqueTypeBound(span, definition_def_id) => {
3733                err.span_note(span, "required by a bound in an opaque type");
3734                if let Some(definition_def_id) = definition_def_id
3735                    // If there are any stalled coroutine obligations, then this
3736                    // error may be due to that, and not because the body has more
3737                    // where-clauses.
3738                    && self.tcx.typeck(definition_def_id).coroutine_stalled_predicates.is_empty()
3739                {
3740                    // FIXME(compiler-errors): We could probably point to something
3741                    // specific here if we tried hard enough...
3742                    err.span_note(
3743                        tcx.def_span(definition_def_id),
3744                        "this definition site has more where clauses than the opaque type",
3745                    );
3746                }
3747            }
3748            ObligationCauseCode::Coercion { source, target } => {
3749                let source =
3750                    tcx.short_string(self.resolve_vars_if_possible(source), err.long_ty_path());
3751                let target =
3752                    tcx.short_string(self.resolve_vars_if_possible(target), err.long_ty_path());
3753                err.note({
    let _guard = ForceTrimmedGuard::new();
    ::alloc::__export::must_use({
            ::alloc::fmt::format(format_args!("required for the cast from `{0}` to `{1}`",
                    source, target))
        })
}with_forced_trimmed_paths!(format!(
3754                    "required for the cast from `{source}` to `{target}`",
3755                )));
3756            }
3757            ObligationCauseCode::RepeatElementCopy { is_constable, elt_span } => {
3758                err.note(
3759                    "the `Copy` trait is required because this value will be copied for each element of the array",
3760                );
3761                let sm = tcx.sess.source_map();
3762                if #[allow(non_exhaustive_omitted_patterns)] match is_constable {
    IsConstable::Fn | IsConstable::Ctor => true,
    _ => false,
}matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
3763                    && let Ok(_) = sm.span_to_snippet(elt_span)
3764                {
3765                    err.multipart_suggestion(
3766                        "create an inline `const` block",
3767                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(elt_span.shrink_to_lo(), "const { ".to_string()),
                (elt_span.shrink_to_hi(), " }".to_string())]))vec![
3768                            (elt_span.shrink_to_lo(), "const { ".to_string()),
3769                            (elt_span.shrink_to_hi(), " }".to_string()),
3770                        ],
3771                        Applicability::MachineApplicable,
3772                    );
3773                } else {
3774                    // FIXME: we may suggest array::repeat instead
3775                    err.help("consider using `core::array::from_fn` to initialize the array");
3776                    err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html for more information");
3777                }
3778            }
3779            ObligationCauseCode::VariableType(hir_id) => {
3780                if let Some(typeck_results) = &self.typeck_results
3781                    && let Some(ty) = typeck_results.node_type_opt(hir_id)
3782                    && let ty::Error(_) = ty.kind()
3783                {
3784                    err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` isn\'t satisfied, but the type of this pattern is `{{type error}}`",
                predicate))
    })format!(
3785                        "`{predicate}` isn't satisfied, but the type of this pattern is \
3786                         `{{type error}}`",
3787                    ));
3788                    err.downgrade_to_delayed_bug();
3789                }
3790                let mut local = true;
3791                match tcx.parent_hir_node(hir_id) {
3792                    Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) => {
3793                        err.span_suggestion_verbose(
3794                            ty.span.shrink_to_lo(),
3795                            "consider borrowing here",
3796                            "&",
3797                            Applicability::MachineApplicable,
3798                        );
3799                    }
3800                    Node::LetStmt(hir::LetStmt {
3801                        init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
3802                        ..
3803                    }) => {
3804                        // When encountering an assignment of an unsized trait, like
3805                        // `let x = ""[..];`, provide a suggestion to borrow the initializer in
3806                        // order to use have a slice instead.
3807                        err.span_suggestion_verbose(
3808                            span.shrink_to_lo(),
3809                            "consider borrowing here",
3810                            "&",
3811                            Applicability::MachineApplicable,
3812                        );
3813                    }
3814                    Node::LetStmt(hir::LetStmt { init: Some(expr), .. }) => {
3815                        // When encountering an assignment of an unsized trait, like `let x = *"";`,
3816                        // we check if the RHS is a deref operation, to suggest removing it.
3817                        suggest_remove_deref(err, &expr);
3818                    }
3819                    Node::Param(param) => {
3820                        err.span_suggestion_verbose(
3821                            param.ty_span.shrink_to_lo(),
3822                            "function arguments must have a statically known size, borrowed types \
3823                            always have a known size",
3824                            "&",
3825                            Applicability::MachineApplicable,
3826                        );
3827                        local = false;
3828                    }
3829                    _ => {}
3830                }
3831                if local {
3832                    err.note("all local variables must have a statically known size");
3833                }
3834            }
3835            ObligationCauseCode::SizedArgumentType(hir_id) => {
3836                let mut ty = None;
3837                let borrowed_msg = "function arguments must have a statically known size, borrowed \
3838                                    types always have a known size";
3839                if let Some(hir_id) = hir_id
3840                    && let hir::Node::Param(param) = self.tcx.hir_node(hir_id)
3841                    && let Some(decl) = self.tcx.parent_hir_node(hir_id).fn_decl()
3842                    && let Some(t) = decl.inputs.iter().find(|t| param.ty_span.contains(t.span))
3843                {
3844                    // We use `contains` because the type might be surrounded by parentheses,
3845                    // which makes `ty_span` and `t.span` disagree with each other, but one
3846                    // fully contains the other: `foo: (dyn Foo + Bar)`
3847                    //                                 ^-------------^
3848                    //                                 ||
3849                    //                                 |t.span
3850                    //                                 param._ty_span
3851                    ty = Some(t);
3852                } else if let Some(hir_id) = hir_id
3853                    && let hir::Node::Ty(t) = self.tcx.hir_node(hir_id)
3854                {
3855                    ty = Some(t);
3856                }
3857                if let Some(ty) = ty {
3858                    match ty.kind {
3859                        hir::TyKind::TraitObject(traits, _) => {
3860                            let (span, kw) = match traits {
3861                                [first, ..] if first.span.lo() == ty.span.lo() => {
3862                                    // Missing `dyn` in front of trait object.
3863                                    (ty.span.shrink_to_lo(), "dyn ")
3864                                }
3865                                [first, ..] => (ty.span.until(first.span), ""),
3866                                [] => ::rustc_middle::util::bug::span_bug_fmt(ty.span,
    format_args!("trait object with no traits: {0:?}", ty))span_bug!(ty.span, "trait object with no traits: {ty:?}"),
3867                            };
3868                            let needs_parens = traits.len() != 1;
3869                            // Don't recommend impl Trait as a closure argument
3870                            if let Some(hir_id) = hir_id
3871                                && #[allow(non_exhaustive_omitted_patterns)] match self.tcx.parent_hir_node(hir_id)
    {
    hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { .. }, .. }) => true,
    _ => false,
}matches!(
3872                                    self.tcx.parent_hir_node(hir_id),
3873                                    hir::Node::Item(hir::Item {
3874                                        kind: hir::ItemKind::Fn { .. },
3875                                        ..
3876                                    })
3877                                )
3878                            {
3879                                err.span_suggestion_verbose(
3880                                    span,
3881                                    "you can use `impl Trait` as the argument type",
3882                                    "impl ",
3883                                    Applicability::MaybeIncorrect,
3884                                );
3885                            }
3886                            let sugg = if !needs_parens {
3887                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("&{0}", kw))
                        }))]))vec![(span.shrink_to_lo(), format!("&{kw}"))]
3888                            } else {
3889                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("&({0}", kw))
                        })), (ty.span.shrink_to_hi(), ")".to_string())]))vec![
3890                                    (span.shrink_to_lo(), format!("&({kw}")),
3891                                    (ty.span.shrink_to_hi(), ")".to_string()),
3892                                ]
3893                            };
3894                            err.multipart_suggestion(
3895                                borrowed_msg,
3896                                sugg,
3897                                Applicability::MachineApplicable,
3898                            );
3899                        }
3900                        hir::TyKind::Slice(_ty) => {
3901                            err.span_suggestion_verbose(
3902                                ty.span.shrink_to_lo(),
3903                                "function arguments must have a statically known size, borrowed \
3904                                 slices always have a known size",
3905                                "&",
3906                                Applicability::MachineApplicable,
3907                            );
3908                        }
3909                        hir::TyKind::Path(_) => {
3910                            err.span_suggestion_verbose(
3911                                ty.span.shrink_to_lo(),
3912                                borrowed_msg,
3913                                "&",
3914                                Applicability::MachineApplicable,
3915                            );
3916                        }
3917                        _ => {}
3918                    }
3919                } else {
3920                    err.note("all function arguments must have a statically known size");
3921                }
3922                if tcx.sess.opts.unstable_features.is_nightly_build()
3923                    && !tcx.features().unsized_fn_params()
3924                {
3925                    err.help("unsized fn params are gated as an unstable feature");
3926                }
3927            }
3928            ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType => {
3929                err.note("the return type of a function must have a statically known size");
3930            }
3931            ObligationCauseCode::SizedYieldType => {
3932                err.note("the yield type of a coroutine must have a statically known size");
3933            }
3934            ObligationCauseCode::AssignmentLhsSized => {
3935                err.note("the left-hand-side of an assignment must have a statically known size");
3936            }
3937            ObligationCauseCode::TupleInitializerSized => {
3938                err.note("tuples must have a statically known size to be initialized");
3939            }
3940            ObligationCauseCode::StructInitializerSized => {
3941                err.note("structs must have a statically known size to be initialized");
3942            }
3943            ObligationCauseCode::FieldSized { adt_kind: ref item, last, span } => {
3944                match *item {
3945                    AdtKind::Struct => {
3946                        if last {
3947                            err.note(
3948                                "the last field of a packed struct may only have a \
3949                                dynamically sized type if it does not need drop to be run",
3950                            );
3951                        } else {
3952                            err.note(
3953                                "only the last field of a struct may have a dynamically sized type",
3954                            );
3955                        }
3956                    }
3957                    AdtKind::Union => {
3958                        err.note("no field of a union may have a dynamically sized type");
3959                    }
3960                    AdtKind::Enum => {
3961                        err.note("no field of an enum variant may have a dynamically sized type");
3962                    }
3963                }
3964                err.help("change the field's type to have a statically known size");
3965                err.span_suggestion_verbose(
3966                    span.shrink_to_lo(),
3967                    "borrowed types always have a statically known size",
3968                    "&",
3969                    Applicability::MachineApplicable,
3970                );
3971                err.multipart_suggestion(
3972                    "the `Box` type always has a statically known size and allocates its contents \
3973                     in the heap",
3974                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(), "Box<".to_string()),
                (span.shrink_to_hi(), ">".to_string())]))vec![
3975                        (span.shrink_to_lo(), "Box<".to_string()),
3976                        (span.shrink_to_hi(), ">".to_string()),
3977                    ],
3978                    Applicability::MachineApplicable,
3979                );
3980            }
3981            ObligationCauseCode::SizedConstOrStatic => {
3982                err.note("statics and constants must have a statically known size");
3983            }
3984            ObligationCauseCode::InlineAsmSized => {
3985                err.note("all inline asm arguments must have a statically known size");
3986            }
3987            ObligationCauseCode::SizedClosureCapture(closure_def_id) => {
3988                err.note(
3989                    "all values captured by value by a closure must have a statically known size",
3990                );
3991                let hir::ExprKind::Closure(closure) =
3992                    tcx.hir_node_by_def_id(closure_def_id).expect_expr().kind
3993                else {
3994                    ::rustc_middle::util::bug::bug_fmt(format_args!("expected closure in SizedClosureCapture obligation"));bug!("expected closure in SizedClosureCapture obligation");
3995                };
3996                if let hir::CaptureBy::Value { .. } = closure.capture_clause
3997                    && let Some(span) = closure.fn_arg_span
3998                {
3999                    err.span_label(span, "this closure captures all values by move");
4000                }
4001            }
4002            ObligationCauseCode::SizedCoroutineInterior(coroutine_def_id) => {
4003                let what = match tcx.coroutine_kind(coroutine_def_id) {
4004                    None
4005                    | Some(hir::CoroutineKind::Coroutine(_))
4006                    | Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => {
4007                        "yield"
4008                    }
4009                    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
4010                        "await"
4011                    }
4012                    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => {
4013                        "yield`/`await"
4014                    }
4015                };
4016                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("all values live across `{0}` must have a statically known size",
                what))
    })format!(
4017                    "all values live across `{what}` must have a statically known size"
4018                ));
4019            }
4020            ObligationCauseCode::SharedStatic => {
4021                err.note("shared static variables must have a type that implements `Sync`");
4022            }
4023            ObligationCauseCode::BuiltinDerived(ref data) => {
4024                let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
4025                let ty = parent_trait_ref.skip_binder().self_ty();
4026                if parent_trait_ref.references_error() {
4027                    // NOTE(eddyb) this was `.cancel()`, but `err`
4028                    // is borrowed, so we can't fully defuse it.
4029                    err.downgrade_to_delayed_bug();
4030                    return;
4031                }
4032
4033                // If the obligation for a tuple is set directly by a Coroutine or Closure,
4034                // then the tuple must be the one containing capture types.
4035                let is_upvar_tys_infer_tuple = if !#[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Tuple(..) => true,
    _ => false,
}matches!(ty.kind(), ty::Tuple(..)) {
4036                    false
4037                } else if let ObligationCauseCode::BuiltinDerived(data) = &*data.parent_code {
4038                    let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
4039                    let nested_ty = parent_trait_ref.skip_binder().self_ty();
4040                    #[allow(non_exhaustive_omitted_patterns)] match nested_ty.kind() {
    ty::Coroutine(..) => true,
    _ => false,
}matches!(nested_ty.kind(), ty::Coroutine(..))
4041                        || #[allow(non_exhaustive_omitted_patterns)] match nested_ty.kind() {
    ty::Closure(..) => true,
    _ => false,
}matches!(nested_ty.kind(), ty::Closure(..))
4042                } else {
4043                    false
4044                };
4045
4046                let is_builtin_async_fn_trait =
4047                    tcx.async_fn_trait_kind_from_def_id(data.parent_trait_pred.def_id()).is_some();
4048
4049                if !is_upvar_tys_infer_tuple && !is_builtin_async_fn_trait {
4050                    let mut msg = || {
4051                        let ty_str = tcx.short_string(ty, err.long_ty_path());
4052                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required because it appears within the type `{0}`",
                ty_str))
    })format!("required because it appears within the type `{ty_str}`")
4053                    };
4054                    match *ty.kind() {
4055                        ty::Adt(def, _) => {
4056                            let msg = msg();
4057                            match tcx.opt_item_ident(def.did()) {
4058                                Some(ident) => {
4059                                    err.span_note(ident.span, msg);
4060                                }
4061                                None => {
4062                                    err.note(msg);
4063                                }
4064                            }
4065                        }
4066                        ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => {
4067                            // If the previous type is async fn, this is the future generated by the body of an async function.
4068                            // Avoid printing it twice (it was already printed in the `ty::Coroutine` arm below).
4069                            let is_future = tcx.ty_is_opaque_future(ty);
4070                            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:4070",
                        "rustc_trait_selection::error_reporting::traits::suggestions",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                        ::tracing_core::__macro_support::Option::Some(4070u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                        ::tracing_core::field::FieldSet::new(&["message",
                                        "obligated_types", "is_future"],
                            ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("note_obligation_cause_code: check for async fn")
                                            as &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&obligated_types)
                                            as &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&is_future)
                                            as &dyn Value))])
            });
    } else { ; }
};debug!(
4071                                ?obligated_types,
4072                                ?is_future,
4073                                "note_obligation_cause_code: check for async fn"
4074                            );
4075                            if is_future
4076                                && obligated_types.last().is_some_and(|ty| match ty.kind() {
4077                                    ty::Coroutine(last_def_id, ..) => {
4078                                        tcx.coroutine_is_async(*last_def_id)
4079                                    }
4080                                    _ => false,
4081                                })
4082                            {
4083                                // See comment above; skip printing twice.
4084                            } else {
4085                                let msg = msg();
4086                                err.span_note(tcx.def_span(def_id), msg);
4087                            }
4088                        }
4089                        ty::Coroutine(def_id, _) => {
4090                            let sp = tcx.def_span(def_id);
4091
4092                            // Special-case this to say "async block" instead of `[static coroutine]`.
4093                            let kind = tcx.coroutine_kind(def_id).unwrap();
4094                            err.span_note(
4095                                sp,
4096                                {
    let _guard = ForceTrimmedGuard::new();
    ::alloc::__export::must_use({
            ::alloc::fmt::format(format_args!("required because it\'s used within this {0:#}",
                    kind))
        })
}with_forced_trimmed_paths!(format!(
4097                                    "required because it's used within this {kind:#}",
4098                                )),
4099                            );
4100                        }
4101                        ty::CoroutineWitness(..) => {
4102                            // Skip printing coroutine-witnesses, since we'll drill into
4103                            // the bad field in another derived obligation cause.
4104                        }
4105                        ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _) => {
4106                            err.span_note(
4107                                tcx.def_span(def_id),
4108                                "required because it's used within this closure",
4109                            );
4110                        }
4111                        ty::Str => {
4112                            err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes");
4113                        }
4114                        _ => {
4115                            let msg = msg();
4116                            err.note(msg);
4117                        }
4118                    };
4119                }
4120
4121                obligated_types.push(ty);
4122
4123                let parent_predicate = parent_trait_ref;
4124                if !self.is_recursive_obligation(obligated_types, &data.parent_code) {
4125                    // #74711: avoid a stack overflow
4126                    ensure_sufficient_stack(|| {
4127                        self.note_obligation_cause_code(
4128                            body_id,
4129                            err,
4130                            parent_predicate,
4131                            param_env,
4132                            &data.parent_code,
4133                            obligated_types,
4134                            seen_requirements,
4135                        )
4136                    });
4137                } else {
4138                    ensure_sufficient_stack(|| {
4139                        self.note_obligation_cause_code(
4140                            body_id,
4141                            err,
4142                            parent_predicate,
4143                            param_env,
4144                            cause_code.peel_derives(),
4145                            obligated_types,
4146                            seen_requirements,
4147                        )
4148                    });
4149                }
4150            }
4151            ObligationCauseCode::ImplDerived(ref data) => {
4152                let mut parent_trait_pred =
4153                    self.resolve_vars_if_possible(data.derived.parent_trait_pred);
4154                let parent_def_id = parent_trait_pred.def_id();
4155                if tcx.is_diagnostic_item(sym::FromResidual, parent_def_id)
4156                    && !tcx.features().enabled(sym::try_trait_v2)
4157                {
4158                    // If `#![feature(try_trait_v2)]` is not enabled, then there's no point on
4159                    // talking about `FromResidual<Result<A, B>>`, as the end user has nothing they
4160                    // can do about it. As far as they are concerned, `?` is compiler magic.
4161                    return;
4162                }
4163                if tcx.is_diagnostic_item(sym::PinDerefMutHelper, parent_def_id) {
4164                    let parent_predicate =
4165                        self.resolve_vars_if_possible(data.derived.parent_trait_pred);
4166
4167                    // Skip PinDerefMutHelper in suggestions, but still show downstream suggestions.
4168                    ensure_sufficient_stack(|| {
4169                        self.note_obligation_cause_code(
4170                            body_id,
4171                            err,
4172                            parent_predicate,
4173                            param_env,
4174                            &data.derived.parent_code,
4175                            obligated_types,
4176                            seen_requirements,
4177                        )
4178                    });
4179                    return;
4180                }
4181                let self_ty_str =
4182                    tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
4183                let trait_name = tcx.short_string(
4184                    parent_trait_pred.print_modifiers_and_trait_path(),
4185                    err.long_ty_path(),
4186                );
4187                let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required for `{0}` to implement `{1}`",
                self_ty_str, trait_name))
    })format!("required for `{self_ty_str}` to implement `{trait_name}`");
4188                let mut is_auto_trait = false;
4189                match tcx.hir_get_if_local(data.impl_or_alias_def_id) {
4190                    Some(Node::Item(hir::Item {
4191                        kind: hir::ItemKind::Trait { is_auto, ident, .. },
4192                        ..
4193                    })) => {
4194                        // FIXME: we should do something else so that it works even on crate foreign
4195                        // auto traits.
4196                        is_auto_trait = #[allow(non_exhaustive_omitted_patterns)] match is_auto {
    hir::IsAuto::Yes => true,
    _ => false,
}matches!(is_auto, hir::IsAuto::Yes);
4197                        err.span_note(ident.span, msg);
4198                    }
4199                    Some(Node::Item(hir::Item {
4200                        kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, generics, .. }),
4201                        ..
4202                    })) => {
4203                        let mut spans = Vec::with_capacity(2);
4204                        if let Some(of_trait) = of_trait
4205                            && !of_trait.trait_ref.path.span.in_derive_expansion()
4206                        {
4207                            spans.push(of_trait.trait_ref.path.span);
4208                        }
4209                        spans.push(self_ty.span);
4210                        let mut spans: MultiSpan = spans.into();
4211                        let mut derived = false;
4212                        if #[allow(non_exhaustive_omitted_patterns)] match self_ty.span.ctxt().outer_expn_data().kind
    {
    ExpnKind::Macro(MacroKind::Derive, _) => true,
    _ => false,
}matches!(
4213                            self_ty.span.ctxt().outer_expn_data().kind,
4214                            ExpnKind::Macro(MacroKind::Derive, _)
4215                        ) || #[allow(non_exhaustive_omitted_patterns)] match of_trait.map(|t|
            t.trait_ref.path.span.ctxt().outer_expn_data().kind) {
    Some(ExpnKind::Macro(MacroKind::Derive, _)) => true,
    _ => false,
}matches!(
4216                            of_trait.map(|t| t.trait_ref.path.span.ctxt().outer_expn_data().kind),
4217                            Some(ExpnKind::Macro(MacroKind::Derive, _))
4218                        ) {
4219                            derived = true;
4220                            spans.push_span_label(
4221                                data.span,
4222                                if data.span.in_derive_expansion() {
4223                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("type parameter would need to implement `{0}`",
                trait_name))
    })format!("type parameter would need to implement `{trait_name}`")
4224                                } else {
4225                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsatisfied trait bound"))
    })format!("unsatisfied trait bound")
4226                                },
4227                            );
4228                        } else if !data.span.is_dummy() && !data.span.overlaps(self_ty.span) {
4229                            // `Sized` may be an explicit or implicit trait bound. If it is
4230                            // implicit, mention it as such.
4231                            if let Some(pred) = predicate.as_trait_clause()
4232                                && self.tcx.is_lang_item(pred.def_id(), LangItem::Sized)
4233                                && self
4234                                    .tcx
4235                                    .generics_of(data.impl_or_alias_def_id)
4236                                    .own_params
4237                                    .iter()
4238                                    .any(|param| self.tcx.def_span(param.def_id) == data.span)
4239                            {
4240                                spans.push_span_label(
4241                                    data.span,
4242                                    "unsatisfied trait bound implicitly introduced here",
4243                                );
4244                            } else {
4245                                spans.push_span_label(
4246                                    data.span,
4247                                    "unsatisfied trait bound introduced here",
4248                                );
4249                            }
4250                        }
4251                        err.span_note(spans, msg);
4252                        if derived && trait_name != "Copy" {
4253                            err.help(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider manually implementing `{0}` to avoid undesired bounds",
                trait_name))
    })format!(
4254                                "consider manually implementing `{trait_name}` to avoid undesired \
4255                                 bounds",
4256                            ));
4257                        }
4258                        point_at_assoc_type_restriction(
4259                            tcx,
4260                            err,
4261                            &self_ty_str,
4262                            &trait_name,
4263                            predicate,
4264                            &generics,
4265                            &data,
4266                        );
4267                    }
4268                    _ => {
4269                        err.note(msg);
4270                    }
4271                };
4272
4273                let mut parent_predicate = parent_trait_pred;
4274                let mut data = &data.derived;
4275                let mut count = 0;
4276                seen_requirements.insert(parent_def_id);
4277                if is_auto_trait {
4278                    // We don't want to point at the ADT saying "required because it appears within
4279                    // the type `X`", like we would otherwise do in test `supertrait-auto-trait.rs`.
4280                    while let ObligationCauseCode::BuiltinDerived(derived) = &*data.parent_code {
4281                        let child_trait_ref =
4282                            self.resolve_vars_if_possible(derived.parent_trait_pred);
4283                        let child_def_id = child_trait_ref.def_id();
4284                        if seen_requirements.insert(child_def_id) {
4285                            break;
4286                        }
4287                        data = derived;
4288                        parent_predicate = child_trait_ref.upcast(tcx);
4289                        parent_trait_pred = child_trait_ref;
4290                    }
4291                }
4292                while let ObligationCauseCode::ImplDerived(child) = &*data.parent_code {
4293                    // Skip redundant recursive obligation notes. See `ui/issue-20413.rs`.
4294                    let child_trait_pred =
4295                        self.resolve_vars_if_possible(child.derived.parent_trait_pred);
4296                    let child_def_id = child_trait_pred.def_id();
4297                    if seen_requirements.insert(child_def_id) {
4298                        break;
4299                    }
4300                    count += 1;
4301                    data = &child.derived;
4302                    parent_predicate = child_trait_pred.upcast(tcx);
4303                    parent_trait_pred = child_trait_pred;
4304                }
4305                if count > 0 {
4306                    err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} redundant requirement{1} hidden",
                count, if count == 1 { "" } else { "s" }))
    })format!(
4307                        "{} redundant requirement{} hidden",
4308                        count,
4309                        pluralize!(count)
4310                    ));
4311                    let self_ty = tcx.short_string(
4312                        parent_trait_pred.skip_binder().self_ty(),
4313                        err.long_ty_path(),
4314                    );
4315                    let trait_path = tcx.short_string(
4316                        parent_trait_pred.print_modifiers_and_trait_path(),
4317                        err.long_ty_path(),
4318                    );
4319                    err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required for `{0}` to implement `{1}`",
                self_ty, trait_path))
    })format!("required for `{self_ty}` to implement `{trait_path}`"));
4320                }
4321                // #74711: avoid a stack overflow
4322                ensure_sufficient_stack(|| {
4323                    self.note_obligation_cause_code(
4324                        body_id,
4325                        err,
4326                        parent_predicate,
4327                        param_env,
4328                        &data.parent_code,
4329                        obligated_types,
4330                        seen_requirements,
4331                    )
4332                });
4333            }
4334            ObligationCauseCode::ImplDerivedHost(ref data) => {
4335                let self_ty = tcx.short_string(
4336                    self.resolve_vars_if_possible(data.derived.parent_host_pred.self_ty()),
4337                    err.long_ty_path(),
4338                );
4339                let trait_path = tcx.short_string(
4340                    data.derived
4341                        .parent_host_pred
4342                        .map_bound(|pred| pred.trait_ref)
4343                        .print_only_trait_path(),
4344                    err.long_ty_path(),
4345                );
4346                let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required for `{1}` to implement `{0} {2}`",
                data.derived.parent_host_pred.skip_binder().constness,
                self_ty, trait_path))
    })format!(
4347                    "required for `{self_ty}` to implement `{} {trait_path}`",
4348                    data.derived.parent_host_pred.skip_binder().constness,
4349                );
4350                match tcx.hir_get_if_local(data.impl_def_id) {
4351                    Some(Node::Item(hir::Item {
4352                        kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
4353                        ..
4354                    })) => {
4355                        let mut spans = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [self_ty.span]))vec![self_ty.span];
4356                        spans.extend(of_trait.map(|t| t.trait_ref.path.span));
4357                        let mut spans: MultiSpan = spans.into();
4358                        spans.push_span_label(data.span, "unsatisfied trait bound introduced here");
4359                        err.span_note(spans, msg);
4360                    }
4361                    _ => {
4362                        err.note(msg);
4363                    }
4364                }
4365                ensure_sufficient_stack(|| {
4366                    self.note_obligation_cause_code(
4367                        body_id,
4368                        err,
4369                        data.derived.parent_host_pred,
4370                        param_env,
4371                        &data.derived.parent_code,
4372                        obligated_types,
4373                        seen_requirements,
4374                    )
4375                });
4376            }
4377            ObligationCauseCode::BuiltinDerivedHost(ref data) => {
4378                ensure_sufficient_stack(|| {
4379                    self.note_obligation_cause_code(
4380                        body_id,
4381                        err,
4382                        data.parent_host_pred,
4383                        param_env,
4384                        &data.parent_code,
4385                        obligated_types,
4386                        seen_requirements,
4387                    )
4388                });
4389            }
4390            ObligationCauseCode::WellFormedDerived(ref data) => {
4391                let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
4392                let parent_predicate = parent_trait_ref;
4393                // #74711: avoid a stack overflow
4394                ensure_sufficient_stack(|| {
4395                    self.note_obligation_cause_code(
4396                        body_id,
4397                        err,
4398                        parent_predicate,
4399                        param_env,
4400                        &data.parent_code,
4401                        obligated_types,
4402                        seen_requirements,
4403                    )
4404                });
4405            }
4406            ObligationCauseCode::TypeAlias(ref nested, span, def_id) => {
4407                // #74711: avoid a stack overflow
4408                ensure_sufficient_stack(|| {
4409                    self.note_obligation_cause_code(
4410                        body_id,
4411                        err,
4412                        predicate,
4413                        param_env,
4414                        nested,
4415                        obligated_types,
4416                        seen_requirements,
4417                    )
4418                });
4419                let mut multispan = MultiSpan::from(span);
4420                multispan.push_span_label(span, "required by this bound");
4421                err.span_note(
4422                    multispan,
4423                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("required by a bound on the type alias `{0}`",
                tcx.item_name(def_id)))
    })format!("required by a bound on the type alias `{}`", tcx.item_name(def_id)),
4424                );
4425            }
4426            ObligationCauseCode::FunctionArg {
4427                arg_hir_id, call_hir_id, ref parent_code, ..
4428            } => {
4429                self.note_function_argument_obligation(
4430                    body_id,
4431                    err,
4432                    arg_hir_id,
4433                    parent_code,
4434                    param_env,
4435                    predicate,
4436                    call_hir_id,
4437                );
4438                ensure_sufficient_stack(|| {
4439                    self.note_obligation_cause_code(
4440                        body_id,
4441                        err,
4442                        predicate,
4443                        param_env,
4444                        parent_code,
4445                        obligated_types,
4446                        seen_requirements,
4447                    )
4448                });
4449            }
4450            // Suppress `compare_type_predicate_entailment` errors for RPITITs, since they
4451            // should be implied by the parent method.
4452            ObligationCauseCode::CompareImplItem { trait_item_def_id, .. }
4453                if tcx.is_impl_trait_in_trait(trait_item_def_id) => {}
4454            ObligationCauseCode::CompareImplItem { trait_item_def_id, kind, .. } => {
4455                let item_name = tcx.item_name(trait_item_def_id);
4456                let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the requirement `{0}` appears on the `impl`\'s {1} `{2}` but not on the corresponding trait\'s {1}",
                predicate, kind, item_name))
    })format!(
4457                    "the requirement `{predicate}` appears on the `impl`'s {kind} \
4458                     `{item_name}` but not on the corresponding trait's {kind}",
4459                );
4460                let sp = tcx
4461                    .opt_item_ident(trait_item_def_id)
4462                    .map(|i| i.span)
4463                    .unwrap_or_else(|| tcx.def_span(trait_item_def_id));
4464                let mut assoc_span: MultiSpan = sp.into();
4465                assoc_span.push_span_label(
4466                    sp,
4467                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this trait\'s {0} doesn\'t have the requirement `{1}`",
                kind, predicate))
    })format!("this trait's {kind} doesn't have the requirement `{predicate}`"),
4468                );
4469                if let Some(ident) = tcx
4470                    .opt_associated_item(trait_item_def_id)
4471                    .and_then(|i| tcx.opt_item_ident(i.container_id(tcx)))
4472                {
4473                    assoc_span.push_span_label(ident.span, "in this trait");
4474                }
4475                err.span_note(assoc_span, msg);
4476            }
4477            ObligationCauseCode::TrivialBound => {
4478                tcx.disabled_nightly_features(err, [(String::new(), sym::trivial_bounds)]);
4479            }
4480            ObligationCauseCode::OpaqueReturnType(expr_info) => {
4481                let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
4482                    let expr_ty = tcx.short_string(expr_ty, err.long_ty_path());
4483                    let expr = tcx.hir_expect_expr(hir_id);
4484                    (expr_ty, expr)
4485                } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id()
4486                    && let body = tcx.hir_body(body_id)
4487                    && let hir::ExprKind::Block(block, _) = body.value.kind
4488                    && let Some(expr) = block.expr
4489                    && let Some(expr_ty) = self
4490                        .typeck_results
4491                        .as_ref()
4492                        .and_then(|typeck| typeck.node_type_opt(expr.hir_id))
4493                    && let Some(pred) = predicate.as_clause()
4494                    && let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
4495                    && self.can_eq(param_env, pred.self_ty(), expr_ty)
4496                {
4497                    let expr_ty = tcx.short_string(expr_ty, err.long_ty_path());
4498                    (expr_ty, expr)
4499                } else {
4500                    return;
4501                };
4502                err.span_label(
4503                    expr.span,
4504                    {
    let _guard = ForceTrimmedGuard::new();
    ::alloc::__export::must_use({
            ::alloc::fmt::format(format_args!("return type was inferred to be `{0}` here",
                    expr_ty))
        })
}with_forced_trimmed_paths!(format!(
4505                        "return type was inferred to be `{expr_ty}` here",
4506                    )),
4507                );
4508                suggest_remove_deref(err, &expr);
4509            }
4510            ObligationCauseCode::UnsizedNonPlaceExpr(span) => {
4511                err.span_note(
4512                    span,
4513                    "unsized values must be place expressions and cannot be put in temporaries",
4514                );
4515            }
4516            ObligationCauseCode::CompareEii { .. } => {
4517                {
    ::core::panicking::panic_fmt(format_args!("trait bounds on EII not yet supported "));
}panic!("trait bounds on EII not yet supported ")
4518            }
4519        }
4520    }
4521
4522    #[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("suggest_await_before_try",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(4522u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["obligation",
                                                    "trait_pred", "span", "trait_pred.self_ty"],
                                        ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_pred)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&span)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&debug(&trait_pred.self_ty())
                                                            as &dyn 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: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let future_trait =
                self.tcx.require_lang_item(LangItem::Future, span);
            let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
            let impls_future =
                self.type_implements_trait(future_trait,
                    [self.tcx.instantiate_bound_regions_with_erased(self_ty)],
                    obligation.param_env);
            if !impls_future.must_apply_modulo_regions() { return; }
            let item_def_id =
                self.tcx.associated_item_def_ids(future_trait)[0];
            let projection_ty =
                trait_pred.map_bound(|trait_pred|
                        {
                            Ty::new_projection(self.tcx, ty::IsRigid::No, item_def_id,
                                [trait_pred.self_ty()])
                        });
            let InferOk { value: projection_ty, .. } =
                self.at(&obligation.cause,
                        obligation.param_env).normalize(Unnormalized::new_wip(projection_ty));
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:4559",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(4559u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["normalized_projection_type"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&self.resolve_vars_if_possible(projection_ty))
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let try_obligation =
                self.mk_trait_obligation_with_new_self_ty(obligation.param_env,
                    trait_pred.map_bound(|trait_pred|
                            (trait_pred, projection_ty.skip_binder())));
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:4566",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(4566u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["try_trait_obligation"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&try_obligation)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            if self.predicate_may_hold(&try_obligation) &&
                        let Ok(snippet) =
                            self.tcx.sess.source_map().span_to_snippet(span) &&
                    snippet.ends_with('?') {
                match self.tcx.coroutine_kind(obligation.cause.body_id) {
                    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async,
                        _)) => {
                        err.span_suggestion_verbose(span.with_hi(span.hi() -
                                        BytePos(1)).shrink_to_hi(),
                            "consider `await`ing on the `Future`", ".await",
                            Applicability::MaybeIncorrect);
                    }
                    _ => {
                        let mut span: MultiSpan =
                            span.with_lo(span.hi() - BytePos(1)).into();
                        span.push_span_label(self.tcx.def_span(obligation.cause.body_id),
                            "this is not `async`");
                        err.span_note(span,
                            "this implements `Future` and its output type supports \
                        `?`, but the future cannot be awaited in a synchronous function");
                    }
                }
            }
        }
    }
}#[instrument(
4523        level = "debug", skip(self, err), fields(trait_pred.self_ty = ?trait_pred.self_ty())
4524    )]
4525    pub(super) fn suggest_await_before_try(
4526        &self,
4527        err: &mut Diag<'_>,
4528        obligation: &PredicateObligation<'tcx>,
4529        trait_pred: ty::PolyTraitPredicate<'tcx>,
4530        span: Span,
4531    ) {
4532        let future_trait = self.tcx.require_lang_item(LangItem::Future, span);
4533
4534        let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
4535        let impls_future = self.type_implements_trait(
4536            future_trait,
4537            [self.tcx.instantiate_bound_regions_with_erased(self_ty)],
4538            obligation.param_env,
4539        );
4540        if !impls_future.must_apply_modulo_regions() {
4541            return;
4542        }
4543
4544        let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
4545        // `<T as Future>::Output`
4546        let projection_ty = trait_pred.map_bound(|trait_pred| {
4547            Ty::new_projection(
4548                self.tcx,
4549                ty::IsRigid::No,
4550                item_def_id,
4551                // Future::Output has no args
4552                [trait_pred.self_ty()],
4553            )
4554        });
4555        let InferOk { value: projection_ty, .. } = self
4556            .at(&obligation.cause, obligation.param_env)
4557            .normalize(Unnormalized::new_wip(projection_ty));
4558
4559        debug!(
4560            normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty)
4561        );
4562        let try_obligation = self.mk_trait_obligation_with_new_self_ty(
4563            obligation.param_env,
4564            trait_pred.map_bound(|trait_pred| (trait_pred, projection_ty.skip_binder())),
4565        );
4566        debug!(try_trait_obligation = ?try_obligation);
4567        if self.predicate_may_hold(&try_obligation)
4568            && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
4569            && snippet.ends_with('?')
4570        {
4571            match self.tcx.coroutine_kind(obligation.cause.body_id) {
4572                Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
4573                    err.span_suggestion_verbose(
4574                        span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(),
4575                        "consider `await`ing on the `Future`",
4576                        ".await",
4577                        Applicability::MaybeIncorrect,
4578                    );
4579                }
4580                _ => {
4581                    let mut span: MultiSpan = span.with_lo(span.hi() - BytePos(1)).into();
4582                    span.push_span_label(
4583                        self.tcx.def_span(obligation.cause.body_id),
4584                        "this is not `async`",
4585                    );
4586                    err.span_note(
4587                        span,
4588                        "this implements `Future` and its output type supports \
4589                        `?`, but the future cannot be awaited in a synchronous function",
4590                    );
4591                }
4592            }
4593        }
4594    }
4595
4596    pub(super) fn suggest_floating_point_literal(
4597        &self,
4598        obligation: &PredicateObligation<'tcx>,
4599        err: &mut Diag<'_>,
4600        trait_pred: ty::PolyTraitPredicate<'tcx>,
4601    ) {
4602        let rhs_span = match obligation.cause.code() {
4603            ObligationCauseCode::BinOp { rhs_span, rhs_is_lit, .. } if *rhs_is_lit => rhs_span,
4604            _ => return,
4605        };
4606        if let ty::Float(_) = trait_pred.skip_binder().self_ty().kind()
4607            && let ty::Infer(InferTy::IntVar(_)) =
4608                trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
4609        {
4610            err.span_suggestion_verbose(
4611                rhs_span.shrink_to_hi(),
4612                "consider using a floating-point literal by writing it with `.0`",
4613                ".0",
4614                Applicability::MaybeIncorrect,
4615            );
4616        }
4617    }
4618
4619    pub fn can_suggest_derive(
4620        &self,
4621        obligation: &PredicateObligation<'tcx>,
4622        trait_pred: ty::PolyTraitPredicate<'tcx>,
4623    ) -> bool {
4624        if trait_pred.polarity() == ty::PredicatePolarity::Negative {
4625            return false;
4626        }
4627        let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
4628            return false;
4629        };
4630        let (adt, args) = match trait_pred.skip_binder().self_ty().kind() {
4631            ty::Adt(adt, args) if adt.did().is_local() => (adt, args),
4632            _ => return false,
4633        };
4634        let is_derivable_trait = match diagnostic_name {
4635            sym::Copy | sym::Clone => true,
4636            _ if adt.is_union() => false,
4637            sym::PartialEq | sym::PartialOrd => {
4638                let rhs_ty = trait_pred.skip_binder().trait_ref.args.type_at(1);
4639                trait_pred.skip_binder().self_ty() == rhs_ty
4640            }
4641            sym::Eq | sym::Ord | sym::Hash | sym::Debug | sym::Default => true,
4642            _ => false,
4643        };
4644        is_derivable_trait &&
4645            // Ensure all fields impl the trait.
4646            adt.all_fields().all(|field| {
4647                let field_ty = ty::GenericArg::from(field.ty(self.tcx, args).skip_norm_wip());
4648                let trait_args = match diagnostic_name {
4649                    sym::PartialEq | sym::PartialOrd => {
4650                        Some(field_ty)
4651                    }
4652                    _ => None,
4653                };
4654                let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
4655                    trait_ref: ty::TraitRef::new(self.tcx,
4656                        trait_pred.def_id(),
4657                        [field_ty].into_iter().chain(trait_args),
4658                    ),
4659                    ..*tr
4660                });
4661                let field_obl = Obligation::new(
4662                    self.tcx,
4663                    obligation.cause.clone(),
4664                    obligation.param_env,
4665                    trait_pred,
4666                );
4667                self.predicate_must_hold_modulo_regions(&field_obl)
4668            })
4669    }
4670
4671    pub fn suggest_derive(
4672        &self,
4673        obligation: &PredicateObligation<'tcx>,
4674        err: &mut Diag<'_>,
4675        trait_pred: ty::PolyTraitPredicate<'tcx>,
4676    ) {
4677        let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
4678            return;
4679        };
4680        let adt = match trait_pred.skip_binder().self_ty().kind() {
4681            ty::Adt(adt, _) if adt.did().is_local() => adt,
4682            _ => return,
4683        };
4684        if self.can_suggest_derive(obligation, trait_pred) {
4685            err.span_suggestion_verbose(
4686                self.tcx.def_span(adt.did()).shrink_to_lo(),
4687                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider annotating `{0}` with `#[derive({1})]`",
                trait_pred.skip_binder().self_ty(), diagnostic_name))
    })format!(
4688                    "consider annotating `{}` with `#[derive({})]`",
4689                    trait_pred.skip_binder().self_ty(),
4690                    diagnostic_name,
4691                ),
4692                // FIXME(const_trait_impl) derive_const as suggestion?
4693                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("#[derive({0})]\n",
                diagnostic_name))
    })format!("#[derive({diagnostic_name})]\n"),
4694                Applicability::MaybeIncorrect,
4695            );
4696        }
4697    }
4698
4699    pub(super) fn suggest_dereferencing_index(
4700        &self,
4701        obligation: &PredicateObligation<'tcx>,
4702        err: &mut Diag<'_>,
4703        trait_pred: ty::PolyTraitPredicate<'tcx>,
4704    ) {
4705        if let ObligationCauseCode::ImplDerived(_) = obligation.cause.code()
4706            && self
4707                .tcx
4708                .is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id)
4709            && let ty::Slice(_) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
4710            && let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind()
4711            && let ty::Uint(ty::UintTy::Usize) = inner_ty.kind()
4712        {
4713            err.span_suggestion_verbose(
4714                obligation.cause.span.shrink_to_lo(),
4715                "dereference this index",
4716                '*',
4717                Applicability::MachineApplicable,
4718            );
4719        }
4720    }
4721
4722    fn note_function_argument_obligation<G: EmissionGuarantee>(
4723        &self,
4724        body_id: LocalDefId,
4725        err: &mut Diag<'_, G>,
4726        arg_hir_id: HirId,
4727        parent_code: &ObligationCauseCode<'tcx>,
4728        param_env: ty::ParamEnv<'tcx>,
4729        failed_pred: ty::Predicate<'tcx>,
4730        call_hir_id: HirId,
4731    ) {
4732        let tcx = self.tcx;
4733        if let Node::Expr(expr) = tcx.hir_node(arg_hir_id)
4734            && let Some(typeck_results) = &self.typeck_results
4735        {
4736            if let hir::Expr { kind: hir::ExprKind::MethodCall(_, rcvr, _, _), .. } = expr
4737                && let Some(ty) = typeck_results.node_type_opt(rcvr.hir_id)
4738                && let Some(failed_pred) = failed_pred.as_trait_clause()
4739                && let pred = failed_pred.map_bound(|pred| pred.with_replaced_self_ty(tcx, ty))
4740                && self.predicate_must_hold_modulo_regions(&Obligation::misc(
4741                    tcx, expr.span, body_id, param_env, pred,
4742                ))
4743                && expr.span.hi() != rcvr.span.hi()
4744            {
4745                let should_sugg = match tcx.hir_node(call_hir_id) {
4746                    Node::Expr(hir::Expr {
4747                        kind: hir::ExprKind::MethodCall(_, call_receiver, _, _),
4748                        ..
4749                    }) if let Some((DefKind::AssocFn, did)) =
4750                        typeck_results.type_dependent_def(call_hir_id)
4751                        && call_receiver.hir_id == arg_hir_id =>
4752                    {
4753                        // Avoid suggesting removing a method call if the argument is the receiver of the parent call and
4754                        // removing the receiver would make the method inaccessible. i.e. `x.a().b()`, suggesting removing
4755                        // `.a()` could change the type and make `.b()` unavailable.
4756                        if tcx.inherent_impl_of_assoc(did).is_some() {
4757                            // if we're calling an inherent impl method, just try to make sure that the receiver type stays the same.
4758                            Some(ty) == typeck_results.node_type_opt(arg_hir_id)
4759                        } else {
4760                            // we're calling a trait method, so we just check removing the method call still satisfies the trait.
4761                            let trait_id = tcx
4762                                .trait_of_assoc(did)
4763                                .unwrap_or_else(|| tcx.impl_trait_id(tcx.parent(did)));
4764                            let args = typeck_results.node_args(call_hir_id);
4765                            let tr = ty::TraitRef::from_assoc(tcx, trait_id, args)
4766                                .with_replaced_self_ty(tcx, ty);
4767                            self.type_implements_trait(tr.def_id, tr.args, param_env)
4768                                .must_apply_modulo_regions()
4769                        }
4770                    }
4771                    _ => true,
4772                };
4773
4774                if should_sugg {
4775                    err.span_suggestion_verbose(
4776                        expr.span.with_lo(rcvr.span.hi()),
4777                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider removing this method call, as the receiver has type `{0}` and `{1}` trivially holds",
                ty, pred))
    })format!(
4778                            "consider removing this method call, as the receiver has type `{ty}` and \
4779                            `{pred}` trivially holds",
4780                        ),
4781                        "",
4782                        Applicability::MaybeIncorrect,
4783                    );
4784                }
4785            }
4786            if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
4787                let inner_expr = expr.peel_blocks();
4788                let ty = typeck_results
4789                    .expr_ty_adjusted_opt(inner_expr)
4790                    .unwrap_or(Ty::new_misc_error(tcx));
4791                let span = inner_expr.span;
4792                if Some(span) != err.span.primary_span()
4793                    && !span.in_external_macro(tcx.sess.source_map())
4794                {
4795                    err.span_label(
4796                        span,
4797                        if ty.references_error() {
4798                            String::new()
4799                        } else {
4800                            let ty = { let _guard = ForceTrimmedGuard::new(); self.ty_to_string(ty) }with_forced_trimmed_paths!(self.ty_to_string(ty));
4801                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this tail expression is of type `{0}`",
                ty))
    })format!("this tail expression is of type `{ty}`")
4802                        },
4803                    );
4804                    if let ty::PredicateKind::Clause(clause) = failed_pred.kind().skip_binder()
4805                        && let ty::ClauseKind::Trait(pred) = clause
4806                        && tcx.fn_trait_kind_from_def_id(pred.def_id()).is_some()
4807                    {
4808                        if let [stmt, ..] = block.stmts
4809                            && let hir::StmtKind::Semi(value) = stmt.kind
4810                            && let hir::ExprKind::Closure(hir::Closure {
4811                                body, fn_decl_span, ..
4812                            }) = value.kind
4813                            && let body = tcx.hir_body(*body)
4814                            && !#[allow(non_exhaustive_omitted_patterns)] match body.value.kind {
    hir::ExprKind::Block(..) => true,
    _ => false,
}matches!(body.value.kind, hir::ExprKind::Block(..))
4815                        {
4816                            // Check if the failed predicate was an expectation of a closure type
4817                            // and if there might have been a `{ |args|` typo instead of `|args| {`.
4818                            err.multipart_suggestion(
4819                                "you might have meant to open the closure body instead of placing \
4820                                 a closure within a block",
4821                                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(expr.span.with_hi(value.span.lo()), String::new()),
                (fn_decl_span.shrink_to_hi(), " {".to_string())]))vec![
4822                                    (expr.span.with_hi(value.span.lo()), String::new()),
4823                                    (fn_decl_span.shrink_to_hi(), " {".to_string()),
4824                                ],
4825                                Applicability::MaybeIncorrect,
4826                            );
4827                        } else {
4828                            // Maybe the bare block was meant to be a closure.
4829                            err.span_suggestion_verbose(
4830                                expr.span.shrink_to_lo(),
4831                                "you might have meant to create the closure instead of a block",
4832                                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("|{0}| ",
                (0..pred.trait_ref.args.len() -
                                        1).map(|_| "_").collect::<Vec<_>>().join(", ")))
    })format!(
4833                                    "|{}| ",
4834                                    (0..pred.trait_ref.args.len() - 1)
4835                                        .map(|_| "_")
4836                                        .collect::<Vec<_>>()
4837                                        .join(", ")
4838                                ),
4839                                Applicability::MaybeIncorrect,
4840                            );
4841                        }
4842                    }
4843                }
4844            }
4845
4846            // FIXME: visit the ty to see if there's any closure involved, and if there is,
4847            // check whether its evaluated return type is the same as the one corresponding
4848            // to an associated type (as seen from `trait_pred`) in the predicate. Like in
4849            // trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
4850            let mut type_diffs = ::alloc::vec::Vec::new()vec![];
4851            if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = *parent_code
4852                && let Some(node_args) = typeck_results.node_args_opt(call_hir_id)
4853                && let where_clauses =
4854                    self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args)
4855                && let Some(where_pred) = where_clauses.predicates.get(idx)
4856            {
4857                let where_pred = where_pred.as_ref().skip_norm_wip();
4858                if let Some(where_pred) = where_pred.as_trait_clause()
4859                    && let Some(failed_pred) = failed_pred.as_trait_clause()
4860                    && where_pred.def_id() == failed_pred.def_id()
4861                {
4862                    self.enter_forall(where_pred, |where_pred| {
4863                        let failed_pred = self.instantiate_binder_with_fresh_vars(
4864                            expr.span,
4865                            BoundRegionConversionTime::FnCall,
4866                            failed_pred,
4867                        );
4868
4869                        let zipped =
4870                            iter::zip(where_pred.trait_ref.args, failed_pred.trait_ref.args);
4871                        for (expected, actual) in zipped {
4872                            self.probe(|_| {
4873                                match self
4874                                    .at(&ObligationCause::misc(expr.span, body_id), param_env)
4875                                    // Doesn't actually matter if we define opaque types here, this is just used for
4876                                    // diagnostics, and the result is never kept around.
4877                                    .eq(DefineOpaqueTypes::Yes, expected, actual)
4878                                {
4879                                    Ok(_) => (), // We ignore nested obligations here for now.
4880                                    Err(err) => type_diffs.push(err),
4881                                }
4882                            })
4883                        }
4884                    })
4885                } else if let Some(where_pred) = where_pred.as_projection_clause()
4886                    && let Some(failed_pred) = failed_pred.as_projection_clause()
4887                    && let Some(found) = failed_pred.skip_binder().term.as_type()
4888                {
4889                    type_diffs = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [TypeError::Sorts(ty::error::ExpectedFound {
                        expected: where_pred.skip_binder().projection_term.expect_ty().to_ty(self.tcx,
                            ty::IsRigid::No),
                        found,
                    })]))vec![TypeError::Sorts(ty::error::ExpectedFound {
4890                        expected: where_pred
4891                            .skip_binder()
4892                            .projection_term
4893                            .expect_ty()
4894                            .to_ty(self.tcx, ty::IsRigid::No),
4895                        found,
4896                    })];
4897                }
4898            }
4899            if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
4900                && let hir::Path { res: Res::Local(hir_id), .. } = path
4901                && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
4902                && let hir::Node::LetStmt(local) = self.tcx.parent_hir_node(binding.hir_id)
4903                && let Some(binding_expr) = local.init
4904            {
4905                // If the expression we're calling on is a binding, we want to point at the
4906                // `let` when talking about the type. Otherwise we'll point at every part
4907                // of the method chain with the type.
4908                self.point_at_chain(binding_expr, typeck_results, type_diffs, param_env, err);
4909            } else {
4910                self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
4911            }
4912        }
4913        let call_node = tcx.hir_node(call_hir_id);
4914        if let Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(path, rcvr, ..), .. }) =
4915            call_node
4916        {
4917            if Some(rcvr.span) == err.span.primary_span() {
4918                err.replace_span_with(path.ident.span, true);
4919            }
4920        }
4921
4922        if let Node::Expr(expr) = call_node {
4923            if let hir::ExprKind::Call(hir::Expr { span, .. }, _)
4924            | hir::ExprKind::MethodCall(
4925                hir::PathSegment { ident: Ident { span, .. }, .. },
4926                ..,
4927            ) = expr.kind
4928            {
4929                if Some(*span) != err.span.primary_span() {
4930                    let msg = if span.is_desugaring(DesugaringKind::FormatLiteral { source: true })
4931                    {
4932                        "required by this formatting parameter"
4933                    } else if span.is_desugaring(DesugaringKind::FormatLiteral { source: false }) {
4934                        "required by a formatting parameter in this expression"
4935                    } else {
4936                        "required by a bound introduced by this call"
4937                    };
4938                    err.span_label(*span, msg);
4939                }
4940            }
4941
4942            if let hir::ExprKind::MethodCall(_, expr, ..) = expr.kind {
4943                self.suggest_option_method_if_applicable(failed_pred, param_env, err, expr);
4944            }
4945        }
4946    }
4947
4948    fn suggest_option_method_if_applicable<G: EmissionGuarantee>(
4949        &self,
4950        failed_pred: ty::Predicate<'tcx>,
4951        param_env: ty::ParamEnv<'tcx>,
4952        err: &mut Diag<'_, G>,
4953        expr: &hir::Expr<'_>,
4954    ) {
4955        let tcx = self.tcx;
4956        let infcx = self.infcx;
4957        let Some(typeck_results) = self.typeck_results.as_ref() else { return };
4958
4959        // Make sure we're dealing with the `Option` type.
4960        let Some(option_ty_adt) = typeck_results.expr_ty_adjusted(expr).ty_adt_def() else {
4961            return;
4962        };
4963        if !tcx.is_diagnostic_item(sym::Option, option_ty_adt.did()) {
4964            return;
4965        }
4966
4967        // Given the predicate `fn(&T): FnOnce<(U,)>`, extract `fn(&T)` and `(U,)`,
4968        // then suggest `Option::as_deref(_mut)` if `U` can deref to `T`
4969        if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, .. }))
4970            = failed_pred.kind().skip_binder()
4971            && tcx.is_fn_trait(trait_ref.def_id)
4972            && let [self_ty, found_ty] = trait_ref.args.as_slice()
4973            && let Some(fn_ty) = self_ty.as_type().filter(|ty| ty.is_fn())
4974            && let fn_sig @ ty::FnSig {
4975                ..
4976            } = fn_ty.fn_sig(tcx).skip_binder()
4977            // FIXME(splat): this might need to change if the Fn* traits start using/supporting splat
4978            && fn_sig.abi() == ExternAbi::Rust
4979            && !fn_sig.c_variadic()
4980            && fn_sig.safety() == hir::Safety::Safe
4981
4982            // Extract first param of fn sig with peeled refs, e.g. `fn(&T)` -> `T`
4983            && let Some(&ty::Ref(_, target_ty, needs_mut)) = fn_sig.inputs().first().map(|t| t.kind())
4984            && !target_ty.has_escaping_bound_vars()
4985
4986            // Extract first tuple element out of fn trait, e.g. `FnOnce<(U,)>` -> `U`
4987            && let Some(ty::Tuple(tys)) = found_ty.as_type().map(Ty::kind)
4988            && let &[found_ty] = tys.as_slice()
4989            && !found_ty.has_escaping_bound_vars()
4990
4991            // Extract `<U as Deref>::Target` assoc type and check that it is `T`
4992            && let Some(deref_target_did) = tcx.lang_items().deref_target()
4993            && let projection = Ty::new_projection_from_args(tcx,ty::IsRigid::No, deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)]))
4994            && let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(projection))
4995            && obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation))
4996            && infcx.can_eq(param_env, deref_target, target_ty)
4997        {
4998            let help = if let hir::Mutability::Mut = needs_mut
4999                && let Some(deref_mut_did) = tcx.lang_items().deref_mut_trait()
5000                && infcx
5001                    .type_implements_trait(deref_mut_did, iter::once(found_ty), param_env)
5002                    .must_apply_modulo_regions()
5003            {
5004                Some(("call `Option::as_deref_mut()` first", ".as_deref_mut()"))
5005            } else if let hir::Mutability::Not = needs_mut {
5006                Some(("call `Option::as_deref()` first", ".as_deref()"))
5007            } else {
5008                None
5009            };
5010
5011            if let Some((msg, sugg)) = help {
5012                err.span_suggestion_with_style(
5013                    expr.span.shrink_to_hi(),
5014                    msg,
5015                    sugg,
5016                    Applicability::MaybeIncorrect,
5017                    SuggestionStyle::ShowAlways,
5018                );
5019            }
5020        }
5021    }
5022
5023    fn look_for_iterator_item_mistakes<G: EmissionGuarantee>(
5024        &self,
5025        assocs_in_this_method: &[Option<(Span, (DefId, Ty<'tcx>))>],
5026        typeck_results: &TypeckResults<'tcx>,
5027        type_diffs: &[TypeError<'tcx>],
5028        param_env: ty::ParamEnv<'tcx>,
5029        path_segment: &hir::PathSegment<'_>,
5030        args: &[hir::Expr<'_>],
5031        prev_ty: Ty<'_>,
5032        err: &mut Diag<'_, G>,
5033    ) {
5034        let tcx = self.tcx;
5035        // Special case for iterator chains, we look at potential failures of `Iterator::Item`
5036        // not being `: Clone` and `Iterator::map` calls with spurious trailing `;`.
5037        for entry in assocs_in_this_method {
5038            let Some((_span, (def_id, ty))) = entry else {
5039                continue;
5040            };
5041            for diff in type_diffs {
5042                let TypeError::Sorts(expected_found) = diff else {
5043                    continue;
5044                };
5045                if tcx.is_diagnostic_item(sym::IntoIteratorItem, *def_id)
5046                    && path_segment.ident.name == sym::iter
5047                    && self.can_eq(
5048                        param_env,
5049                        Ty::new_ref(
5050                            tcx,
5051                            tcx.lifetimes.re_erased,
5052                            expected_found.found,
5053                            ty::Mutability::Not,
5054                        ),
5055                        *ty,
5056                    )
5057                    && let [] = args
5058                {
5059                    // Used `.iter()` when `.into_iter()` was likely meant.
5060                    err.span_suggestion_verbose(
5061                        path_segment.ident.span,
5062                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider consuming the `{0}` to construct the `Iterator`",
                prev_ty))
    })format!("consider consuming the `{prev_ty}` to construct the `Iterator`"),
5063                        "into_iter".to_string(),
5064                        Applicability::MachineApplicable,
5065                    );
5066                }
5067                if tcx.is_diagnostic_item(sym::IntoIteratorItem, *def_id)
5068                    && path_segment.ident.name == sym::into_iter
5069                    && self.can_eq(
5070                        param_env,
5071                        expected_found.found,
5072                        Ty::new_ref(tcx, tcx.lifetimes.re_erased, *ty, ty::Mutability::Not),
5073                    )
5074                    && let [] = args
5075                {
5076                    // Used `.into_iter()` when `.iter()` was likely meant.
5077                    err.span_suggestion_verbose(
5078                        path_segment.ident.span,
5079                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider not consuming the `{0}` to construct the `Iterator`",
                prev_ty))
    })format!(
5080                            "consider not consuming the `{prev_ty}` to construct the `Iterator`"
5081                        ),
5082                        "iter".to_string(),
5083                        Applicability::MachineApplicable,
5084                    );
5085                }
5086                if tcx.is_diagnostic_item(sym::IteratorItem, *def_id)
5087                    && path_segment.ident.name == sym::map
5088                    && self.can_eq(param_env, expected_found.found, *ty)
5089                    && let [arg] = args
5090                    && let hir::ExprKind::Closure(closure) = arg.kind
5091                {
5092                    let body = tcx.hir_body(closure.body);
5093                    if let hir::ExprKind::Block(block, None) = body.value.kind
5094                        && let None = block.expr
5095                        && let [.., stmt] = block.stmts
5096                        && let hir::StmtKind::Semi(expr) = stmt.kind
5097                        // FIXME: actually check the expected vs found types, but right now
5098                        // the expected is a projection that we need to resolve.
5099                        // && let Some(tail_ty) = typeck_results.expr_ty_opt(expr)
5100                        && expected_found.found.is_unit()
5101                        // FIXME: this happens with macro calls. Need to figure out why the stmt
5102                        // `println!();` doesn't include the `;` in its `Span`. (#133845)
5103                        // We filter these out to avoid ICEs with debug assertions on caused by
5104                        // empty suggestions.
5105                        && expr.span.hi() != stmt.span.hi()
5106                    {
5107                        err.span_suggestion_verbose(
5108                            expr.span.shrink_to_hi().with_hi(stmt.span.hi()),
5109                            "consider removing this semicolon",
5110                            String::new(),
5111                            Applicability::MachineApplicable,
5112                        );
5113                    }
5114                    let expr = if let hir::ExprKind::Block(block, None) = body.value.kind
5115                        && let Some(expr) = block.expr
5116                    {
5117                        expr
5118                    } else {
5119                        body.value
5120                    };
5121                    if let hir::ExprKind::MethodCall(path_segment, rcvr, [], span) = expr.kind
5122                        && path_segment.ident.name == sym::clone
5123                        && let Some(expr_ty) = typeck_results.expr_ty_opt(expr)
5124                        && let Some(rcvr_ty) = typeck_results.expr_ty_opt(rcvr)
5125                        && self.can_eq(param_env, expr_ty, rcvr_ty)
5126                        && let ty::Ref(_, ty, _) = expr_ty.kind()
5127                    {
5128                        err.span_label(
5129                            span,
5130                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this method call is cloning the reference `{0}`, not `{1}` which doesn\'t implement `Clone`",
                expr_ty, ty))
    })format!(
5131                                "this method call is cloning the reference `{expr_ty}`, not \
5132                                 `{ty}` which doesn't implement `Clone`",
5133                            ),
5134                        );
5135                        let ty::Param(..) = ty.kind() else {
5136                            continue;
5137                        };
5138                        let node =
5139                            tcx.hir_node_by_def_id(tcx.hir_get_parent_item(expr.hir_id).def_id);
5140
5141                        let pred = ty::Binder::dummy(ty::TraitPredicate {
5142                            trait_ref: ty::TraitRef::new(
5143                                tcx,
5144                                tcx.require_lang_item(LangItem::Clone, span),
5145                                [*ty],
5146                            ),
5147                            polarity: ty::PredicatePolarity::Positive,
5148                        });
5149                        let Some(generics) = node.generics() else {
5150                            continue;
5151                        };
5152                        let Some(body_id) = node.body_id() else {
5153                            continue;
5154                        };
5155                        suggest_restriction(
5156                            tcx,
5157                            tcx.hir_body_owner_def_id(body_id),
5158                            generics,
5159                            &::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("type parameter `{0}`", ty))
    })format!("type parameter `{ty}`"),
5160                            err,
5161                            node.fn_sig(),
5162                            None,
5163                            pred,
5164                            None,
5165                        );
5166                    }
5167                }
5168            }
5169        }
5170    }
5171
5172    fn point_at_chain<G: EmissionGuarantee>(
5173        &self,
5174        expr: &hir::Expr<'_>,
5175        typeck_results: &TypeckResults<'tcx>,
5176        type_diffs: Vec<TypeError<'tcx>>,
5177        param_env: ty::ParamEnv<'tcx>,
5178        err: &mut Diag<'_, G>,
5179    ) {
5180        let mut primary_spans = ::alloc::vec::Vec::new()vec![];
5181        let mut span_labels = ::alloc::vec::Vec::new()vec![];
5182
5183        let tcx = self.tcx;
5184
5185        let mut print_root_expr = true;
5186        let mut assocs = ::alloc::vec::Vec::new()vec![];
5187        let mut expr = expr;
5188        let mut prev_ty = self.resolve_vars_if_possible(
5189            typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)),
5190        );
5191        while let hir::ExprKind::MethodCall(path_segment, rcvr_expr, args, span) = expr.kind {
5192            // Point at every method call in the chain with the resulting type.
5193            // vec![1, 2, 3].iter().map(mapper).sum<i32>()
5194            //               ^^^^^^ ^^^^^^^^^^^
5195            expr = rcvr_expr;
5196            let assocs_in_this_method =
5197                self.probe_assoc_types_at_expr(&type_diffs, span, prev_ty, expr.hir_id, param_env);
5198            prev_ty = self.resolve_vars_if_possible(
5199                typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)),
5200            );
5201            self.look_for_iterator_item_mistakes(
5202                &assocs_in_this_method,
5203                typeck_results,
5204                &type_diffs,
5205                param_env,
5206                path_segment,
5207                args,
5208                prev_ty,
5209                err,
5210            );
5211            assocs.push(assocs_in_this_method);
5212
5213            if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
5214                && let hir::Path { res: Res::Local(hir_id), .. } = path
5215                && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
5216            {
5217                let parent = self.tcx.parent_hir_node(binding.hir_id);
5218                // We've reached the root of the method call chain...
5219                if let hir::Node::LetStmt(local) = parent
5220                    && let Some(binding_expr) = local.init
5221                {
5222                    // ...and it is a binding. Get the binding creation and continue the chain.
5223                    expr = binding_expr;
5224                }
5225                if let hir::Node::Param(param) = parent {
5226                    // ...and it is an fn argument.
5227                    let prev_ty = self.resolve_vars_if_possible(
5228                        typeck_results
5229                            .node_type_opt(param.hir_id)
5230                            .unwrap_or(Ty::new_misc_error(tcx)),
5231                    );
5232                    let assocs_in_this_method = self.probe_assoc_types_at_expr(
5233                        &type_diffs,
5234                        param.ty_span,
5235                        prev_ty,
5236                        param.hir_id,
5237                        param_env,
5238                    );
5239                    if assocs_in_this_method.iter().any(|a| a.is_some()) {
5240                        assocs.push(assocs_in_this_method);
5241                        print_root_expr = false;
5242                    }
5243                    break;
5244                }
5245            }
5246        }
5247        // We want the type before deref coercions, otherwise we talk about `&[_]`
5248        // instead of `Vec<_>`.
5249        if let Some(ty) = typeck_results.expr_ty_opt(expr)
5250            && print_root_expr
5251        {
5252            let ty = { let _guard = ForceTrimmedGuard::new(); self.ty_to_string(ty) }with_forced_trimmed_paths!(self.ty_to_string(ty));
5253            // Point at the root expression
5254            // vec![1, 2, 3].iter().map(mapper).sum<i32>()
5255            // ^^^^^^^^^^^^^
5256            span_labels.push((expr.span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this expression has type `{0}`",
                ty))
    })format!("this expression has type `{ty}`")));
5257        };
5258        // Only show this if it is not a "trivial" expression (not a method
5259        // chain) and there are associated types to talk about.
5260        let mut assocs = assocs.into_iter().peekable();
5261        while let Some(assocs_in_method) = assocs.next() {
5262            let Some(prev_assoc_in_method) = assocs.peek() else {
5263                for entry in assocs_in_method {
5264                    let Some((span, (assoc, ty))) = entry else {
5265                        continue;
5266                    };
5267                    if primary_spans.is_empty()
5268                        || type_diffs.iter().any(|diff| {
5269                            let TypeError::Sorts(expected_found) = diff else {
5270                                return false;
5271                            };
5272                            self.can_eq(param_env, expected_found.found, ty)
5273                        })
5274                    {
5275                        // FIXME: this doesn't quite work for `Iterator::collect`
5276                        // because we have `Vec<i32>` and `()`, but we'd want `i32`
5277                        // to point at the `.into_iter()` call, but as long as we
5278                        // still point at the other method calls that might have
5279                        // introduced the issue, this is fine for now.
5280                        primary_spans.push(span);
5281                    }
5282                    span_labels.push((
5283                        span,
5284                        {
    let _guard = ForceTrimmedGuard::new();
    ::alloc::__export::must_use({
            ::alloc::fmt::format(format_args!("`{0}` is `{1}` here",
                    self.tcx.def_path_str(assoc), ty))
        })
}with_forced_trimmed_paths!(format!(
5285                            "`{}` is `{ty}` here",
5286                            self.tcx.def_path_str(assoc),
5287                        )),
5288                    ));
5289                }
5290                break;
5291            };
5292            for (entry, prev_entry) in
5293                assocs_in_method.into_iter().zip(prev_assoc_in_method.into_iter())
5294            {
5295                match (entry, prev_entry) {
5296                    (Some((span, (assoc, ty))), Some((_, (_, prev_ty)))) => {
5297                        let ty_str = { let _guard = ForceTrimmedGuard::new(); self.ty_to_string(ty) }with_forced_trimmed_paths!(self.ty_to_string(ty));
5298
5299                        let assoc = { let _guard = ForceTrimmedGuard::new(); self.tcx.def_path_str(assoc) }with_forced_trimmed_paths!(self.tcx.def_path_str(assoc));
5300                        if !self.can_eq(param_env, ty, *prev_ty) {
5301                            if type_diffs.iter().any(|diff| {
5302                                let TypeError::Sorts(expected_found) = diff else {
5303                                    return false;
5304                                };
5305                                self.can_eq(param_env, expected_found.found, ty)
5306                            }) {
5307                                primary_spans.push(span);
5308                            }
5309                            span_labels
5310                                .push((span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` changed to `{1}` here",
                assoc, ty_str))
    })format!("`{assoc}` changed to `{ty_str}` here")));
5311                        } else {
5312                            span_labels.push((span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` remains `{1}` here", assoc,
                ty_str))
    })format!("`{assoc}` remains `{ty_str}` here")));
5313                        }
5314                    }
5315                    (Some((span, (assoc, ty))), None) => {
5316                        span_labels.push((
5317                            span,
5318                            {
    let _guard = ForceTrimmedGuard::new();
    ::alloc::__export::must_use({
            ::alloc::fmt::format(format_args!("`{0}` is `{1}` here",
                    self.tcx.def_path_str(assoc), self.ty_to_string(ty)))
        })
}with_forced_trimmed_paths!(format!(
5319                                "`{}` is `{}` here",
5320                                self.tcx.def_path_str(assoc),
5321                                self.ty_to_string(ty),
5322                            )),
5323                        ));
5324                    }
5325                    (None, Some(_)) | (None, None) => {}
5326                }
5327            }
5328        }
5329        if !primary_spans.is_empty() {
5330            let mut multi_span: MultiSpan = primary_spans.into();
5331            for (span, label) in span_labels {
5332                multi_span.push_span_label(span, label);
5333            }
5334            err.span_note(
5335                multi_span,
5336                "the method call chain might not have had the expected associated types",
5337            );
5338        }
5339    }
5340
5341    fn probe_assoc_types_at_expr(
5342        &self,
5343        type_diffs: &[TypeError<'tcx>],
5344        span: Span,
5345        prev_ty: Ty<'tcx>,
5346        body_id: HirId,
5347        param_env: ty::ParamEnv<'tcx>,
5348    ) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>> {
5349        let ocx = ObligationCtxt::new(self.infcx);
5350        let mut assocs_in_this_method = Vec::with_capacity(type_diffs.len());
5351        for diff in type_diffs {
5352            let TypeError::Sorts(expected_found) = diff else {
5353                continue;
5354            };
5355            let &ty::Alias(_, ty::AliasTy { kind: kind @ ty::Projection { def_id }, .. }) =
5356                expected_found.expected.kind()
5357            else {
5358                continue;
5359            };
5360
5361            // Make `Self` be equivalent to the type of the call chain
5362            // expression we're looking at now, so that we can tell what
5363            // for example `Iterator::Item` is at this point in the chain.
5364            let args = GenericArgs::for_item(self.tcx, def_id, |param, _| {
5365                if param.index == 0 {
5366                    if true {
    {
        match param.kind {
            ty::GenericParamDefKind::Type { .. } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "ty::GenericParamDefKind::Type { .. }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(param.kind, ty::GenericParamDefKind::Type { .. });
5367                    return prev_ty.into();
5368                }
5369                self.var_for_def(span, param)
5370            });
5371            // This will hold the resolved type of the associated type, if the
5372            // current expression implements the trait that associated type is
5373            // in. For example, this would be what `Iterator::Item` is here.
5374            let ty = self.infcx.next_ty_var(span);
5375            // This corresponds to `<ExprTy as Iterator>::Item = _`.
5376            let projection = ty::Binder::dummy(ty::PredicateKind::Clause(
5377                ty::ClauseKind::Projection(ty::ProjectionPredicate {
5378                    projection_term: ty::AliasTerm::new_from_args(self.tcx, kind.into(), args),
5379                    term: ty.into(),
5380                }),
5381            ));
5382            let body_def_id = self.tcx.hir_enclosing_body_owner(body_id);
5383            // Add `<ExprTy as Iterator>::Item = _` obligation.
5384            ocx.register_obligation(Obligation::misc(
5385                self.tcx,
5386                span,
5387                body_def_id,
5388                param_env,
5389                projection,
5390            ));
5391            if ocx.try_evaluate_obligations().is_empty()
5392                && let ty = self.resolve_vars_if_possible(ty)
5393                && !ty.is_ty_var()
5394            {
5395                assocs_in_this_method.push(Some((span, (def_id, ty))));
5396            } else {
5397                // `<ExprTy as Iterator>` didn't select, so likely we've
5398                // reached the end of the iterator chain, like the originating
5399                // `Vec<_>` or the `ty` couldn't be determined.
5400                // Keep the space consistent for later zipping.
5401                assocs_in_this_method.push(None);
5402            }
5403        }
5404        assocs_in_this_method
5405    }
5406
5407    /// If the type that failed selection is an array or a reference to an array,
5408    /// but the trait is implemented for slices, suggest that the user converts
5409    /// the array into a slice.
5410    pub(super) fn suggest_convert_to_slice(
5411        &self,
5412        err: &mut Diag<'_>,
5413        obligation: &PredicateObligation<'tcx>,
5414        trait_pred: ty::PolyTraitPredicate<'tcx>,
5415        candidate_impls: &[ImplCandidate<'tcx>],
5416        span: Span,
5417    ) {
5418        if span.in_external_macro(self.tcx.sess.source_map()) {
5419            return;
5420        }
5421        // We can only suggest the slice coercion for function and binary operation arguments,
5422        // since the suggestion would make no sense in turbofish or call
5423        let (ObligationCauseCode::BinOp { .. } | ObligationCauseCode::FunctionArg { .. }) =
5424            obligation.cause.code()
5425        else {
5426            return;
5427        };
5428
5429        // Three cases where we can make a suggestion:
5430        // 1. `[T; _]` (array of T)
5431        // 2. `&[T; _]` (reference to array of T)
5432        // 3. `&mut [T; _]` (mutable reference to array of T)
5433        let (element_ty, mut mutability) = match *trait_pred.skip_binder().self_ty().kind() {
5434            ty::Array(element_ty, _) => (element_ty, None),
5435
5436            ty::Ref(_, pointee_ty, mutability) => match *pointee_ty.kind() {
5437                ty::Array(element_ty, _) => (element_ty, Some(mutability)),
5438                _ => return,
5439            },
5440
5441            _ => return,
5442        };
5443
5444        // Go through all the candidate impls to see if any of them is for
5445        // slices of `element_ty` with `mutability`.
5446        let mut is_slice = |candidate: Ty<'tcx>| match *candidate.kind() {
5447            ty::RawPtr(t, m) | ty::Ref(_, t, m) => {
5448                if let ty::Slice(e) = *t.kind()
5449                    && e == element_ty
5450                    && m == mutability.unwrap_or(m)
5451                {
5452                    // Use the candidate's mutability going forward.
5453                    mutability = Some(m);
5454                    true
5455                } else {
5456                    false
5457                }
5458            }
5459            _ => false,
5460        };
5461
5462        // Grab the first candidate that matches, if any, and make a suggestion.
5463        if let Some(slice_ty) = candidate_impls
5464            .iter()
5465            .map(|trait_ref| trait_ref.trait_ref.self_ty())
5466            .find(|t| is_slice(*t))
5467        {
5468            let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("convert the array to a `{0}` slice instead",
                slice_ty))
    })format!("convert the array to a `{slice_ty}` slice instead");
5469
5470            if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
5471                let mut suggestions = ::alloc::vec::Vec::new()vec![];
5472                if snippet.starts_with('&') {
5473                } else if let Some(hir::Mutability::Mut) = mutability {
5474                    suggestions.push((span.shrink_to_lo(), "&mut ".into()));
5475                } else {
5476                    suggestions.push((span.shrink_to_lo(), "&".into()));
5477                }
5478                suggestions.push((span.shrink_to_hi(), "[..]".into()));
5479                err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
5480            } else {
5481                err.span_help(span, msg);
5482            }
5483        }
5484    }
5485
5486    /// If the type failed selection but the trait is implemented for `(T,)`, suggest that the user
5487    /// creates a unary tuple
5488    ///
5489    /// This is a common gotcha when using libraries that emulate variadic functions with traits for tuples.
5490    pub(super) fn suggest_tuple_wrapping(
5491        &self,
5492        err: &mut Diag<'_>,
5493        root_obligation: &PredicateObligation<'tcx>,
5494        obligation: &PredicateObligation<'tcx>,
5495    ) {
5496        let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code() else {
5497            return;
5498        };
5499
5500        let Some(root_pred) = root_obligation.predicate.as_trait_clause() else { return };
5501
5502        let trait_ref = root_pred.map_bound(|root_pred| {
5503            root_pred.trait_ref.with_replaced_self_ty(
5504                self.tcx,
5505                Ty::new_tup(self.tcx, &[root_pred.trait_ref.self_ty()]),
5506            )
5507        });
5508
5509        let obligation =
5510            Obligation::new(self.tcx, obligation.cause.clone(), obligation.param_env, trait_ref);
5511
5512        if self.predicate_must_hold_modulo_regions(&obligation) {
5513            let arg_span = self.tcx.hir_span(*arg_hir_id);
5514            err.multipart_suggestion(
5515                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("use a unary tuple instead"))
    })format!("use a unary tuple instead"),
5516                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(arg_span.shrink_to_lo(), "(".into()),
                (arg_span.shrink_to_hi(), ",)".into())]))vec![(arg_span.shrink_to_lo(), "(".into()), (arg_span.shrink_to_hi(), ",)".into())],
5517                Applicability::MaybeIncorrect,
5518            );
5519        }
5520    }
5521
5522    pub(super) fn suggest_shadowed_inherent_method(
5523        &self,
5524        err: &mut Diag<'_>,
5525        obligation: &PredicateObligation<'tcx>,
5526        trait_predicate: ty::PolyTraitPredicate<'tcx>,
5527    ) {
5528        let ObligationCauseCode::FunctionArg { call_hir_id, .. } = obligation.cause.code() else {
5529            return;
5530        };
5531        let Node::Expr(call) = self.tcx.hir_node(*call_hir_id) else { return };
5532        let hir::ExprKind::MethodCall(segment, rcvr, args, ..) = call.kind else { return };
5533        let Some(typeck) = &self.typeck_results else { return };
5534        let Some(rcvr_ty) = typeck.expr_ty_adjusted_opt(rcvr) else { return };
5535        let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
5536        let autoderef = (self.autoderef_steps)(rcvr_ty);
5537        for (ty, def_id) in autoderef.iter().filter_map(|(ty, obligations)| {
5538            if let ty::Adt(def, _) = ty.kind()
5539                && *ty != rcvr_ty.peel_refs()
5540                && obligations.iter().all(|obligation| self.predicate_may_hold(obligation))
5541            {
5542                Some((ty, def.did()))
5543            } else {
5544                None
5545            }
5546        }) {
5547            for impl_def_id in self.tcx.inherent_impls(def_id) {
5548                if *impl_def_id == trait_predicate.def_id() {
5549                    continue;
5550                }
5551                for m in self
5552                    .tcx
5553                    .provided_trait_methods(*impl_def_id)
5554                    .filter(|m| m.name() == segment.ident.name)
5555                {
5556                    let fn_sig = self.tcx.fn_sig(m.def_id);
5557                    if fn_sig.skip_binder().inputs().skip_binder().len() != args.len() + 1 {
5558                        continue;
5559                    }
5560                    let rcvr_ty = fn_sig.skip_binder().input(0).skip_binder();
5561                    let (mutability, _ty) = match rcvr_ty.kind() {
5562                        ty::Ref(_, ty, hir::Mutability::Mut) => ("&mut ", ty),
5563                        ty::Ref(_, ty, _) => ("&", ty),
5564                        _ => ("", &rcvr_ty),
5565                    };
5566                    let path = self.tcx.def_path_str(def_id);
5567                    err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("there\'s an inherent method on `{0}` of the same name, which can be auto-dereferenced from `{1}`",
                ty, rcvr_ty))
    })format!(
5568                        "there's an inherent method on `{ty}` of the same name, which can be \
5569                         auto-dereferenced from `{rcvr_ty}`"
5570                    ));
5571                    err.multipart_suggestion(
5572                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("to access the inherent method on `{0}`, use the fully-qualified path",
                ty))
    })format!(
5573                            "to access the inherent method on `{ty}`, use the fully-qualified path",
5574                        ),
5575                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(call.span.until(rcvr.span),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("{2}::{0}({1}", m.name(),
                                    mutability, path))
                        })),
                match &args {
                    [] =>
                        (rcvr.span.shrink_to_hi().with_hi(call.span.hi()),
                            ")".to_string()),
                    [first, ..] =>
                        (rcvr.span.between(first.span), ", ".to_string()),
                }]))vec![
5576                            (
5577                                call.span.until(rcvr.span),
5578                                format!("{path}::{}({}", m.name(), mutability),
5579                            ),
5580                            match &args {
5581                                [] => (
5582                                    rcvr.span.shrink_to_hi().with_hi(call.span.hi()),
5583                                    ")".to_string(),
5584                                ),
5585                                [first, ..] => (rcvr.span.between(first.span), ", ".to_string()),
5586                            },
5587                        ],
5588                        Applicability::MaybeIncorrect,
5589                    );
5590                }
5591            }
5592        }
5593    }
5594
5595    pub(super) fn explain_hrtb_projection(
5596        &self,
5597        diag: &mut Diag<'_>,
5598        pred: ty::PolyTraitPredicate<'tcx>,
5599        param_env: ty::ParamEnv<'tcx>,
5600        cause: &ObligationCause<'tcx>,
5601    ) {
5602        if pred.skip_binder().has_escaping_bound_vars() && pred.skip_binder().has_non_region_infer()
5603        {
5604            self.probe(|_| {
5605                let ocx = ObligationCtxt::new(self);
5606                self.enter_forall(pred, |pred| {
5607                    let pred = ocx.normalize(
5608                        &ObligationCause::dummy(),
5609                        param_env,
5610                        Unnormalized::new_wip(pred),
5611                    );
5612                    ocx.register_obligation(Obligation::new(
5613                        self.tcx,
5614                        ObligationCause::dummy(),
5615                        param_env,
5616                        pred,
5617                    ));
5618                });
5619                if !ocx.try_evaluate_obligations().is_empty() {
5620                    // encountered errors.
5621                    return;
5622                }
5623
5624                if let ObligationCauseCode::FunctionArg {
5625                    call_hir_id,
5626                    arg_hir_id,
5627                    parent_code: _,
5628                } = cause.code()
5629                {
5630                    let arg_span = self.tcx.hir_span(*arg_hir_id);
5631                    let mut sp: MultiSpan = arg_span.into();
5632
5633                    sp.push_span_label(
5634                        arg_span,
5635                        "the trait solver is unable to infer the \
5636                        generic types that should be inferred from this argument",
5637                    );
5638                    sp.push_span_label(
5639                        self.tcx.hir_span(*call_hir_id),
5640                        "add turbofish arguments to this call to \
5641                        specify the types manually, even if it's redundant",
5642                    );
5643                    diag.span_note(
5644                        sp,
5645                        "this is a known limitation of the trait solver that \
5646                        will be lifted in the future",
5647                    );
5648                } else {
5649                    let mut sp: MultiSpan = cause.span.into();
5650                    sp.push_span_label(
5651                        cause.span,
5652                        "try adding turbofish arguments to this expression to \
5653                        specify the types manually, even if it's redundant",
5654                    );
5655                    diag.span_note(
5656                        sp,
5657                        "this is a known limitation of the trait solver that \
5658                        will be lifted in the future",
5659                    );
5660                }
5661            });
5662        }
5663    }
5664
5665    pub(super) fn suggest_desugaring_async_fn_in_trait(
5666        &self,
5667        err: &mut Diag<'_>,
5668        trait_pred: ty::PolyTraitPredicate<'tcx>,
5669    ) {
5670        // Don't suggest if RTN is active -- we should prefer a where-clause bound instead.
5671        if self.tcx.features().return_type_notation() {
5672            return;
5673        }
5674
5675        let trait_def_id = trait_pred.def_id();
5676
5677        // Only suggest specifying auto traits
5678        if !self.tcx.trait_is_auto(trait_def_id) {
5679            return;
5680        }
5681
5682        // Look for an RPITIT
5683        let ty::Alias(_, alias_ty @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) =
5684            trait_pred.self_ty().skip_binder().kind()
5685        else {
5686            return;
5687        };
5688        let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
5689            self.tcx.opt_rpitit_info(*def_id)
5690        else {
5691            return;
5692        };
5693
5694        let auto_trait = self.tcx.def_path_str(trait_def_id);
5695        // ... which is a local function
5696        let Some(fn_def_id) = fn_def_id.as_local() else {
5697            // If it's not local, we can at least mention that the method is async, if it is.
5698            if self.tcx.asyncness(fn_def_id).is_async() {
5699                err.span_note(
5700                    self.tcx.def_span(fn_def_id),
5701                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}::{1}` is an `async fn` in trait, which does not automatically imply that its future is `{2}`",
                alias_ty.trait_ref(self.tcx), self.tcx.item_name(fn_def_id),
                auto_trait))
    })format!(
5702                        "`{}::{}` is an `async fn` in trait, which does not \
5703                    automatically imply that its future is `{auto_trait}`",
5704                        alias_ty.trait_ref(self.tcx),
5705                        self.tcx.item_name(fn_def_id)
5706                    ),
5707                );
5708            }
5709            return;
5710        };
5711        let hir::Node::TraitItem(item) = self.tcx.hir_node_by_def_id(fn_def_id) else {
5712            return;
5713        };
5714
5715        // ... whose signature is `async` (i.e. this is an AFIT)
5716        let (sig, body) = item.expect_fn();
5717        let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(opaq_def, ..), .. }) =
5718            sig.decl.output
5719        else {
5720            // This should never happen, but let's not ICE.
5721            return;
5722        };
5723
5724        // Check that this is *not* a nested `impl Future` RPIT in an async fn
5725        // (i.e. `async fn foo() -> impl Future`)
5726        if opaq_def.def_id.to_def_id() != opaque_def_id {
5727            return;
5728        }
5729
5730        let Some(sugg) = suggest_desugaring_async_fn_to_impl_future_in_trait(
5731            self.tcx,
5732            *sig,
5733            *body,
5734            opaque_def_id.expect_local(),
5735            &::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" + {0}", auto_trait))
    })format!(" + {auto_trait}"),
5736        ) else {
5737            return;
5738        };
5739
5740        let function_name = self.tcx.def_path_str(fn_def_id);
5741        err.multipart_suggestion(
5742            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` can be made part of the associated future\'s guarantees for all implementations of `{1}`",
                auto_trait, function_name))
    })format!(
5743                "`{auto_trait}` can be made part of the associated future's \
5744                guarantees for all implementations of `{function_name}`"
5745            ),
5746            sugg,
5747            Applicability::MachineApplicable,
5748        );
5749    }
5750
5751    pub fn ty_kind_suggestion(
5752        &self,
5753        param_env: ty::ParamEnv<'tcx>,
5754        ty: Ty<'tcx>,
5755    ) -> Option<String> {
5756        let tcx = self.infcx.tcx;
5757        let implements_default = |ty| {
5758            let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
5759                return false;
5760            };
5761            self.type_implements_trait(default_trait, [ty], param_env).must_apply_modulo_regions()
5762        };
5763
5764        Some(match *ty.kind() {
5765            ty::Never | ty::Error(_) => return None,
5766            ty::Bool => "false".to_string(),
5767            ty::Char => "\'x\'".to_string(),
5768            ty::Int(_) | ty::Uint(_) => "42".into(),
5769            ty::Float(_) => "3.14159".into(),
5770            ty::Slice(_) => "[]".to_string(),
5771            ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
5772                "vec![]".to_string()
5773            }
5774            ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => {
5775                "String::new()".to_string()
5776            }
5777            ty::Adt(def, args) if def.is_box() => {
5778                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Box::new({0})",
                self.ty_kind_suggestion(param_env, args[0].expect_ty())?))
    })format!("Box::new({})", self.ty_kind_suggestion(param_env, args[0].expect_ty())?)
5779            }
5780            ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => {
5781                "None".to_string()
5782            }
5783            ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => {
5784                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Ok({0})",
                self.ty_kind_suggestion(param_env, args[0].expect_ty())?))
    })format!("Ok({})", self.ty_kind_suggestion(param_env, args[0].expect_ty())?)
5785            }
5786            ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
5787            ty::Ref(_, ty, mutability) => {
5788                if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) {
5789                    "\"\"".to_string()
5790                } else {
5791                    let ty = self.ty_kind_suggestion(param_env, ty)?;
5792                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("&{0}{1}", mutability.prefix_str(),
                ty))
    })format!("&{}{ty}", mutability.prefix_str())
5793                }
5794            }
5795            ty::Array(ty, len) if let Some(len) = len.try_to_target_usize(tcx) => {
5796                if len == 0 {
5797                    "[]".to_string()
5798                } else if self.type_is_copy_modulo_regions(param_env, ty) || len == 1 {
5799                    // Can only suggest `[ty; 0]` if sz == 1 or copy
5800                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("[{0}; {1}]",
                self.ty_kind_suggestion(param_env, ty)?, len))
    })format!("[{}; {}]", self.ty_kind_suggestion(param_env, ty)?, len)
5801                } else {
5802                    "/* value */".to_string()
5803                }
5804            }
5805            ty::Tuple(tys) => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("({0}{1})",
                tys.iter().map(|ty|
                                    self.ty_kind_suggestion(param_env,
                                        ty)).collect::<Option<Vec<String>>>()?.join(", "),
                if tys.len() == 1 { "," } else { "" }))
    })format!(
5806                "({}{})",
5807                tys.iter()
5808                    .map(|ty| self.ty_kind_suggestion(param_env, ty))
5809                    .collect::<Option<Vec<String>>>()?
5810                    .join(", "),
5811                if tys.len() == 1 { "," } else { "" }
5812            ),
5813            _ => "/* value */".to_string(),
5814        })
5815    }
5816
5817    // For E0277 when use `?` operator, suggest adding
5818    // a suitable return type in `FnSig`, and a default
5819    // return value at the end of the function's body.
5820    pub(super) fn suggest_add_result_as_return_type(
5821        &self,
5822        obligation: &PredicateObligation<'tcx>,
5823        err: &mut Diag<'_>,
5824        trait_pred: ty::PolyTraitPredicate<'tcx>,
5825    ) {
5826        if ObligationCauseCode::QuestionMark != *obligation.cause.code().peel_derives() {
5827            return;
5828        }
5829
5830        // Only suggest for local function and associated method,
5831        // because this suggest adding both return type in
5832        // the `FnSig` and a default return value in the body, so it
5833        // is not suitable for foreign function without a local body,
5834        // and neither for trait method which may be also implemented
5835        // in other place, so shouldn't change it's FnSig.
5836        fn choose_suggest_items<'tcx, 'hir>(
5837            tcx: TyCtxt<'tcx>,
5838            node: hir::Node<'hir>,
5839        ) -> Option<(&'hir hir::FnDecl<'hir>, hir::BodyId)> {
5840            match node {
5841                hir::Node::Item(item)
5842                    if let hir::ItemKind::Fn { sig, body: body_id, .. } = item.kind =>
5843                {
5844                    Some((sig.decl, body_id))
5845                }
5846                hir::Node::ImplItem(item)
5847                    if let hir::ImplItemKind::Fn(sig, body_id) = item.kind =>
5848                {
5849                    let parent = tcx.parent_hir_node(item.hir_id());
5850                    if let hir::Node::Item(item) = parent
5851                        && let hir::ItemKind::Impl(imp) = item.kind
5852                        && imp.of_trait.is_none()
5853                    {
5854                        return Some((sig.decl, body_id));
5855                    }
5856                    None
5857                }
5858                _ => None,
5859            }
5860        }
5861
5862        let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
5863        if let Some((fn_decl, body_id)) = choose_suggest_items(self.tcx, node)
5864            && let hir::FnRetTy::DefaultReturn(ret_span) = fn_decl.output
5865            && self.tcx.is_diagnostic_item(sym::FromResidual, trait_pred.def_id())
5866            && trait_pred.skip_binder().trait_ref.args.type_at(0).is_unit()
5867            && let ty::Adt(def, _) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
5868            && self.tcx.is_diagnostic_item(sym::Result, def.did())
5869        {
5870            let mut sugg_spans =
5871                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(ret_span,
                    " -> Result<(), Box<dyn std::error::Error>>".to_string())]))vec![(ret_span, " -> Result<(), Box<dyn std::error::Error>>".to_string())];
5872            let body = self.tcx.hir_body(body_id);
5873            if let hir::ExprKind::Block(b, _) = body.value.kind
5874                && b.expr.is_none()
5875            {
5876                // The span of '}' in the end of block.
5877                let span = self.tcx.sess.source_map().end_point(b.span);
5878                sugg_spans.push((
5879                    span.shrink_to_lo(),
5880                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}", "    Ok(())\n",
                self.tcx.sess.source_map().indentation_before(span).unwrap_or_default()))
    })format!(
5881                        "{}{}",
5882                        "    Ok(())\n",
5883                        self.tcx.sess.source_map().indentation_before(span).unwrap_or_default(),
5884                    ),
5885                ));
5886            }
5887            err.multipart_suggestion(
5888                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider adding return type"))
    })format!("consider adding return type"),
5889                sugg_spans,
5890                Applicability::MaybeIncorrect,
5891            );
5892        }
5893    }
5894
5895    #[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("suggest_unsized_bound_if_applicable",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(5895u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::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,
                        &{ meta.fields().value_set(&[]) })
                } 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: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) =
                obligation.predicate.kind().skip_binder() else { return; };
            let (ObligationCauseCode::WhereClause(item_def_id, span) |
                    ObligationCauseCode::WhereClauseInExpr(item_def_id, span,
                    ..)) =
                *obligation.cause.code().peel_derives() else { return; };
            if span.is_dummy() { return; }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:5915",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(5915u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["pred",
                                                    "item_def_id", "span"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&pred) as
                                                        &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&item_def_id)
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&span) as
                                                        &dyn Value))])
                        });
                } else { ; }
            };
            let (Some(node), true) =
                (self.tcx.hir_get_if_local(item_def_id),
                    self.tcx.is_lang_item(pred.def_id(),
                        LangItem::Sized)) else { return; };
            let Some(generics) = node.generics() else { return; };
            let sized_trait = self.tcx.lang_items().sized_trait();
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:5928",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(5928u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["generics.params"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&generics.params)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:5929",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(5929u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["generics.predicates"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&generics.predicates)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let Some(param) =
                generics.params.iter().find(|param|
                        param.span == span) else { return; };
            let explicitly_sized =
                generics.bounds_for_param(param.def_id).flat_map(|bp|
                            bp.bounds).any(|bound|
                        bound.trait_ref().and_then(|tr| tr.trait_def_id()) ==
                            sized_trait);
            if explicitly_sized { return; }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:5942",
                                    "rustc_trait_selection::error_reporting::traits::suggestions",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                                    ::tracing_core::__macro_support::Option::Some(5942u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                                    ::tracing_core::field::FieldSet::new(&["param"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&param) as
                                                        &dyn Value))])
                        });
                } else { ; }
            };
            match node {
                hir::Node::Item(item @ hir::Item {
                    kind: hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) |
                        hir::ItemKind::Union(..), .. }) => {
                    if self.suggest_indirection_for_unsized(err, item, param) {
                        return;
                    }
                }
                _ => {}
            };
            let (span, separator, open_paren_sp) =
                if let Some((s, open_paren_sp)) =
                        generics.bounds_span_for_suggestions(param.def_id) {
                    (s, " +", open_paren_sp)
                } else {
                    (param.name.ident().span.shrink_to_hi(), ":", None)
                };
            let mut suggs = ::alloc::vec::Vec::new();
            let suggestion =
                ::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0} ?Sized", separator))
                    });
            if let Some(open_paren_sp) = open_paren_sp {
                suggs.push((open_paren_sp, "(".to_string()));
                suggs.push((span,
                        ::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("){0}", suggestion))
                            })));
            } else { suggs.push((span, suggestion)); }
            err.multipart_suggestion("consider relaxing the implicit `Sized` restriction",
                suggs, Applicability::MachineApplicable);
        }
    }
}#[instrument(level = "debug", skip_all)]
5896    pub(super) fn suggest_unsized_bound_if_applicable(
5897        &self,
5898        err: &mut Diag<'_>,
5899        obligation: &PredicateObligation<'tcx>,
5900    ) {
5901        let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) =
5902            obligation.predicate.kind().skip_binder()
5903        else {
5904            return;
5905        };
5906        let (ObligationCauseCode::WhereClause(item_def_id, span)
5907        | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)) =
5908            *obligation.cause.code().peel_derives()
5909        else {
5910            return;
5911        };
5912        if span.is_dummy() {
5913            return;
5914        }
5915        debug!(?pred, ?item_def_id, ?span);
5916
5917        let (Some(node), true) = (
5918            self.tcx.hir_get_if_local(item_def_id),
5919            self.tcx.is_lang_item(pred.def_id(), LangItem::Sized),
5920        ) else {
5921            return;
5922        };
5923
5924        let Some(generics) = node.generics() else {
5925            return;
5926        };
5927        let sized_trait = self.tcx.lang_items().sized_trait();
5928        debug!(?generics.params);
5929        debug!(?generics.predicates);
5930        let Some(param) = generics.params.iter().find(|param| param.span == span) else {
5931            return;
5932        };
5933        // Check that none of the explicit trait bounds is `Sized`. Assume that an explicit
5934        // `Sized` bound is there intentionally and we don't need to suggest relaxing it.
5935        let explicitly_sized = generics
5936            .bounds_for_param(param.def_id)
5937            .flat_map(|bp| bp.bounds)
5938            .any(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) == sized_trait);
5939        if explicitly_sized {
5940            return;
5941        }
5942        debug!(?param);
5943        match node {
5944            hir::Node::Item(
5945                item @ hir::Item {
5946                    // Only suggest indirection for uses of type parameters in ADTs.
5947                    kind:
5948                        hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..),
5949                    ..
5950                },
5951            ) => {
5952                if self.suggest_indirection_for_unsized(err, item, param) {
5953                    return;
5954                }
5955            }
5956            _ => {}
5957        };
5958
5959        // Didn't add an indirection suggestion, so add a general suggestion to relax `Sized`.
5960        let (span, separator, open_paren_sp) =
5961            if let Some((s, open_paren_sp)) = generics.bounds_span_for_suggestions(param.def_id) {
5962                (s, " +", open_paren_sp)
5963            } else {
5964                (param.name.ident().span.shrink_to_hi(), ":", None)
5965            };
5966
5967        let mut suggs = vec![];
5968        let suggestion = format!("{separator} ?Sized");
5969
5970        if let Some(open_paren_sp) = open_paren_sp {
5971            suggs.push((open_paren_sp, "(".to_string()));
5972            suggs.push((span, format!("){suggestion}")));
5973        } else {
5974            suggs.push((span, suggestion));
5975        }
5976
5977        err.multipart_suggestion(
5978            "consider relaxing the implicit `Sized` restriction",
5979            suggs,
5980            Applicability::MachineApplicable,
5981        );
5982    }
5983
5984    fn suggest_indirection_for_unsized(
5985        &self,
5986        err: &mut Diag<'_>,
5987        item: &hir::Item<'tcx>,
5988        param: &hir::GenericParam<'tcx>,
5989    ) -> bool {
5990        // Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a
5991        // borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S<T: ?Sized>(T);`
5992        // is not. Look for invalid "bare" parameter uses, and suggest using indirection.
5993        let mut visitor = FindTypeParam { param: param.name.ident().name, .. };
5994        visitor.visit_item(item);
5995        if visitor.invalid_spans.is_empty() {
5996            return false;
5997        }
5998        let mut multispan: MultiSpan = param.span.into();
5999        multispan.push_span_label(
6000            param.span,
6001            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this could be changed to `{0}: ?Sized`...",
                param.name.ident()))
    })format!("this could be changed to `{}: ?Sized`...", param.name.ident()),
6002        );
6003        for sp in visitor.invalid_spans {
6004            multispan.push_span_label(
6005                sp,
6006                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("...if indirection were used here: `Box<{0}>`",
                param.name.ident()))
    })format!("...if indirection were used here: `Box<{}>`", param.name.ident()),
6007            );
6008        }
6009        err.span_help(
6010            multispan,
6011            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("you could relax the implicit `Sized` bound on `{0}` if it were used through indirection like `&{0}` or `Box<{0}>`",
                param.name.ident()))
    })format!(
6012                "you could relax the implicit `Sized` bound on `{T}` if it were \
6013                used through indirection like `&{T}` or `Box<{T}>`",
6014                T = param.name.ident(),
6015            ),
6016        );
6017        true
6018    }
6019    pub(crate) fn suggest_swapping_lhs_and_rhs<T>(
6020        &self,
6021        err: &mut Diag<'_>,
6022        predicate: T,
6023        param_env: ty::ParamEnv<'tcx>,
6024        cause_code: &ObligationCauseCode<'tcx>,
6025    ) where
6026        T: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
6027    {
6028        let tcx = self.tcx;
6029        let predicate = predicate.upcast(tcx);
6030        match *cause_code {
6031            ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, rhs_span, .. }
6032                if let Some(typeck_results) = &self.typeck_results
6033                    && let hir::Node::Expr(lhs) = tcx.hir_node(lhs_hir_id)
6034                    && let hir::Node::Expr(rhs) = tcx.hir_node(rhs_hir_id)
6035                    && let Some(lhs_ty) = typeck_results.expr_ty_opt(lhs)
6036                    && let Some(rhs_ty) = typeck_results.expr_ty_opt(rhs) =>
6037            {
6038                if let Some(pred) = predicate.as_trait_clause()
6039                    && tcx.is_lang_item(pred.def_id(), LangItem::PartialEq)
6040                    && self
6041                        .infcx
6042                        .type_implements_trait(pred.def_id(), [rhs_ty, lhs_ty], param_env)
6043                        .must_apply_modulo_regions()
6044                {
6045                    let lhs_span = tcx.hir_span(lhs_hir_id);
6046                    let sm = tcx.sess.source_map();
6047                    if let Ok(rhs_snippet) = sm.span_to_snippet(rhs_span)
6048                        && let Ok(lhs_snippet) = sm.span_to_snippet(lhs_span)
6049                    {
6050                        err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` implements `PartialEq<{1}>`",
                rhs_ty, lhs_ty))
    })format!("`{rhs_ty}` implements `PartialEq<{lhs_ty}>`"));
6051                        err.multipart_suggestion(
6052                            "consider swapping the equality",
6053                            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(lhs_span, rhs_snippet), (rhs_span, lhs_snippet)]))vec![(lhs_span, rhs_snippet), (rhs_span, lhs_snippet)],
6054                            Applicability::MaybeIncorrect,
6055                        );
6056                    }
6057                }
6058            }
6059            _ => {}
6060        }
6061    }
6062}
6063
6064/// Add a hint to add a missing borrow or remove an unnecessary one.
6065fn hint_missing_borrow<'tcx>(
6066    infcx: &InferCtxt<'tcx>,
6067    param_env: ty::ParamEnv<'tcx>,
6068    span: Span,
6069    found: Ty<'tcx>,
6070    expected: Ty<'tcx>,
6071    found_node: Node<'_>,
6072    err: &mut Diag<'_>,
6073) {
6074    if #[allow(non_exhaustive_omitted_patterns)] match found_node {
    Node::TraitItem(..) => true,
    _ => false,
}matches!(found_node, Node::TraitItem(..)) {
6075        return;
6076    }
6077
6078    let found_args = match found.kind() {
6079        ty::FnPtr(sig_tys, _) => infcx.enter_forall(*sig_tys, |sig_tys| sig_tys.inputs().iter()),
6080        kind => {
6081            ::rustc_middle::util::bug::span_bug_fmt(span,
    format_args!("found was converted to a FnPtr above but is now {0:?}",
        kind))span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
6082        }
6083    };
6084    let expected_args = match expected.kind() {
6085        ty::FnPtr(sig_tys, _) => infcx.enter_forall(*sig_tys, |sig_tys| sig_tys.inputs().iter()),
6086        kind => {
6087            ::rustc_middle::util::bug::span_bug_fmt(span,
    format_args!("expected was converted to a FnPtr above but is now {0:?}",
        kind))span_bug!(span, "expected was converted to a FnPtr above but is now {:?}", kind)
6088        }
6089    };
6090
6091    // This could be a variant constructor, for example.
6092    let Some(fn_decl) = found_node.fn_decl() else {
6093        return;
6094    };
6095
6096    let args = fn_decl.inputs.iter();
6097
6098    let mut to_borrow = Vec::new();
6099    let mut remove_borrow = Vec::new();
6100
6101    for ((found_arg, expected_arg), arg) in found_args.zip(expected_args).zip(args) {
6102        let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg);
6103        let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg);
6104
6105        if infcx.can_eq(param_env, found_ty, expected_ty) {
6106            // FIXME: This could handle more exotic cases like mutability mismatches too!
6107            if found_refs.len() < expected_refs.len()
6108                && found_refs[..] == expected_refs[expected_refs.len() - found_refs.len()..]
6109            {
6110                to_borrow.push((
6111                    arg.span.shrink_to_lo(),
6112                    expected_refs[..expected_refs.len() - found_refs.len()]
6113                        .iter()
6114                        .map(|mutbl| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("&{0}", mutbl.prefix_str()))
    })format!("&{}", mutbl.prefix_str()))
6115                        .collect::<Vec<_>>()
6116                        .join(""),
6117                ));
6118            } else if found_refs.len() > expected_refs.len() {
6119                let mut span = arg.span.shrink_to_lo();
6120                let mut left = found_refs.len() - expected_refs.len();
6121                let mut ty = arg;
6122                while let hir::TyKind::Ref(_, mut_ty) = &ty.kind
6123                    && left > 0
6124                {
6125                    span = span.with_hi(mut_ty.ty.span.lo());
6126                    ty = mut_ty.ty;
6127                    left -= 1;
6128                }
6129                if left == 0 {
6130                    remove_borrow.push((span, String::new()));
6131                }
6132            }
6133        }
6134    }
6135
6136    if !to_borrow.is_empty() {
6137        err.subdiagnostic(diagnostics::AdjustSignatureBorrow::Borrow { to_borrow });
6138    }
6139
6140    if !remove_borrow.is_empty() {
6141        err.subdiagnostic(diagnostics::AdjustSignatureBorrow::RemoveBorrow { remove_borrow });
6142    }
6143}
6144
6145/// Collect all the paths that reference `Self`.
6146/// Used to suggest replacing associated types with an explicit type in `where` clauses.
6147#[derive(#[automatically_derived]
impl<'v> ::core::fmt::Debug for SelfVisitor<'v> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "SelfVisitor",
            "paths", &self.paths, "name", &&self.name)
    }
}Debug)]
6148pub struct SelfVisitor<'v> {
6149    pub paths: Vec<&'v hir::Ty<'v>> = Vec::new(),
6150    pub name: Option<Symbol>,
6151}
6152
6153impl<'v> Visitor<'v> for SelfVisitor<'v> {
6154    fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
6155        if let hir::TyKind::Path(path) = ty.kind
6156            && let hir::QPath::TypeRelative(inner_ty, segment) = path
6157            && (Some(segment.ident.name) == self.name || self.name.is_none())
6158            && let hir::TyKind::Path(inner_path) = inner_ty.kind
6159            && let hir::QPath::Resolved(None, inner_path) = inner_path
6160            && let Res::SelfTyAlias { .. } = inner_path.res
6161        {
6162            self.paths.push(ty.as_unambig_ty());
6163        }
6164        hir::intravisit::walk_ty(self, ty);
6165    }
6166}
6167
6168/// Collect all the returned expressions within the input expression.
6169/// Used to point at the return spans when we want to suggest some change to them.
6170#[derive(#[automatically_derived]
impl<'v> ::core::default::Default for ReturnsVisitor<'v> {
    #[inline]
    fn default() -> ReturnsVisitor<'v> {
        ReturnsVisitor {
            returns: ::core::default::Default::default(),
            in_block_tail: ::core::default::Default::default(),
        }
    }
}Default)]
6171pub struct ReturnsVisitor<'v> {
6172    pub returns: Vec<&'v hir::Expr<'v>>,
6173    in_block_tail: bool,
6174}
6175
6176impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
6177    fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
6178        // Visit every expression to detect `return` paths, either through the function's tail
6179        // expression or `return` statements. We walk all nodes to find `return` statements, but
6180        // we only care about tail expressions when `in_block_tail` is `true`, which means that
6181        // they're in the return path of the function body.
6182        match ex.kind {
6183            hir::ExprKind::Ret(Some(ex)) => {
6184                self.returns.push(ex);
6185            }
6186            hir::ExprKind::Block(block, _) if self.in_block_tail => {
6187                self.in_block_tail = false;
6188                for stmt in block.stmts {
6189                    hir::intravisit::walk_stmt(self, stmt);
6190                }
6191                self.in_block_tail = true;
6192                if let Some(expr) = block.expr {
6193                    self.visit_expr(expr);
6194                }
6195            }
6196            hir::ExprKind::If(_, then, else_opt) if self.in_block_tail => {
6197                self.visit_expr(then);
6198                if let Some(el) = else_opt {
6199                    self.visit_expr(el);
6200                }
6201            }
6202            hir::ExprKind::Match(_, arms, _) if self.in_block_tail => {
6203                for arm in arms {
6204                    self.visit_expr(arm.body);
6205                }
6206            }
6207            // We need to walk to find `return`s in the entire body.
6208            _ if !self.in_block_tail => hir::intravisit::walk_expr(self, ex),
6209            _ => self.returns.push(ex),
6210        }
6211    }
6212
6213    fn visit_body(&mut self, body: &hir::Body<'v>) {
6214        if !!self.in_block_tail {
    ::core::panicking::panic("assertion failed: !self.in_block_tail")
};assert!(!self.in_block_tail);
6215        self.in_block_tail = true;
6216        hir::intravisit::walk_body(self, body);
6217    }
6218}
6219
6220/// Collect all the awaited expressions within the input expression.
6221#[derive(#[automatically_derived]
impl ::core::default::Default for AwaitsVisitor {
    #[inline]
    fn default() -> AwaitsVisitor {
        AwaitsVisitor { awaits: ::core::default::Default::default() }
    }
}Default)]
6222struct AwaitsVisitor {
6223    awaits: Vec<HirId>,
6224}
6225
6226impl<'v> Visitor<'v> for AwaitsVisitor {
6227    fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
6228        if let hir::ExprKind::Yield(_, hir::YieldSource::Await { expr: Some(id) }) = ex.kind {
6229            self.awaits.push(id)
6230        }
6231        hir::intravisit::walk_expr(self, ex)
6232    }
6233}
6234
6235/// Suggest a new type parameter name for diagnostic purposes.
6236///
6237/// `name` is the preferred name you'd like to suggest if it's not in use already.
6238pub trait NextTypeParamName {
6239    fn next_type_param_name(&self, name: Option<&str>) -> String;
6240}
6241
6242impl NextTypeParamName for &[hir::GenericParam<'_>] {
6243    fn next_type_param_name(&self, name: Option<&str>) -> String {
6244        // Type names are usually single letters in uppercase. So convert the first letter of input string to uppercase.
6245        let name = name.and_then(|n| n.chars().next()).map(|c| c.to_uppercase().to_string());
6246        let name = name.as_deref();
6247
6248        // This is the list of possible parameter names that we might suggest.
6249        let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"];
6250
6251        // Filter out used names based on `filter_fn`.
6252        let used_names: Vec<Symbol> = self
6253            .iter()
6254            .filter_map(|param| match param.name {
6255                hir::ParamName::Plain(ident) => Some(ident.name),
6256                _ => None,
6257            })
6258            .collect();
6259
6260        // Find a name from `possible_names` that is not in `used_names`.
6261        possible_names
6262            .iter()
6263            .find(|n| !used_names.contains(&Symbol::intern(n)))
6264            .unwrap_or(&"ParamName")
6265            .to_string()
6266    }
6267}
6268
6269/// Collect the spans that we see the generic param `param_did`
6270struct ReplaceImplTraitVisitor<'a> {
6271    ty_spans: &'a mut Vec<Span>,
6272    param_did: DefId,
6273}
6274
6275impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
6276    fn visit_ty(&mut self, t: &'hir hir::Ty<'hir, AmbigArg>) {
6277        if let hir::TyKind::Path(hir::QPath::Resolved(
6278            None,
6279            hir::Path { res: Res::Def(_, segment_did), .. },
6280        )) = t.kind
6281        {
6282            if self.param_did == *segment_did {
6283                // `fn foo(t: impl Trait)`
6284                //            ^^^^^^^^^^ get this to suggest `T` instead
6285
6286                // There might be more than one `impl Trait`.
6287                self.ty_spans.push(t.span);
6288                return;
6289            }
6290        }
6291
6292        hir::intravisit::walk_ty(self, t);
6293    }
6294}
6295
6296pub(super) fn get_explanation_based_on_obligation<'tcx>(
6297    tcx: TyCtxt<'tcx>,
6298    obligation: &PredicateObligation<'tcx>,
6299    trait_predicate: ty::PolyTraitPredicate<'tcx>,
6300    pre_message: String,
6301    long_ty_path: &mut Option<PathBuf>,
6302) -> String {
6303    if let ObligationCauseCode::MainFunctionType = obligation.cause.code() {
6304        "consider using `()`, or a `Result`".to_owned()
6305    } else {
6306        let ty_desc = match trait_predicate.self_ty().skip_binder().kind() {
6307            ty::FnDef(_, _) => Some("fn item"),
6308            ty::Closure(_, _) => Some("closure"),
6309            _ => None,
6310        };
6311
6312        let desc = match ty_desc {
6313            Some(desc) => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" {0}", desc))
    })format!(" {desc}"),
6314            None => String::new(),
6315        };
6316        if let ty::PredicatePolarity::Positive = trait_predicate.polarity() {
6317            // If the trait in question is unstable, mention that fact in the diagnostic.
6318            // But if we're building with `-Zforce-unstable-if-unmarked` then _any_ trait
6319            // not explicitly marked stable is considered unstable, so the extra text is
6320            // unhelpful noise. See <https://github.com/rust-lang/rust/issues/152692>.
6321            let mention_unstable = !tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
6322                && try { tcx.lookup_stability(trait_predicate.def_id())?.level.is_stable() }
6323                    == Some(false);
6324            let unstable = if mention_unstable { "nightly-only, unstable " } else { "" };
6325
6326            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{2}the {3}trait `{0}` is not implemented for{4} `{1}`",
                trait_predicate.print_modifiers_and_trait_path(),
                tcx.short_string(trait_predicate.self_ty().skip_binder(),
                    long_ty_path), pre_message, unstable, desc))
    })format!(
6327                "{pre_message}the {unstable}trait `{}` is not implemented for{desc} `{}`",
6328                trait_predicate.print_modifiers_and_trait_path(),
6329                tcx.short_string(trait_predicate.self_ty().skip_binder(), long_ty_path),
6330            )
6331        } else {
6332            // "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is
6333            // not implemented for `T`".
6334            // FIXME: add note explaining explicit negative trait bounds.
6335            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}the trait bound `{1}` is not satisfied",
                pre_message, trait_predicate))
    })format!("{pre_message}the trait bound `{trait_predicate}` is not satisfied")
6336        }
6337    }
6338}
6339
6340// Replace `param` with `replace_ty`
6341struct ReplaceImplTraitFolder<'tcx> {
6342    tcx: TyCtxt<'tcx>,
6343    param: &'tcx ty::GenericParamDef,
6344    replace_ty: Ty<'tcx>,
6345}
6346
6347impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceImplTraitFolder<'tcx> {
6348    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
6349        if let ty::Param(ty::ParamTy { index, .. }) = t.kind() {
6350            if self.param.index == *index {
6351                return self.replace_ty;
6352            }
6353        }
6354        t.super_fold_with(self)
6355    }
6356
6357    fn cx(&self) -> TyCtxt<'tcx> {
6358        self.tcx
6359    }
6360}
6361
6362pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
6363    tcx: TyCtxt<'tcx>,
6364    sig: hir::FnSig<'tcx>,
6365    body: hir::TraitFn<'tcx>,
6366    opaque_def_id: LocalDefId,
6367    add_bounds: &str,
6368) -> Option<Vec<(Span, String)>> {
6369    let hir::IsAsync::Async(async_span) = sig.header.asyncness else {
6370        return None;
6371    };
6372    let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span);
6373
6374    let future = tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
6375    let [hir::GenericBound::Trait(trait_ref)] = future.bounds else {
6376        // `async fn` should always lower to a single bound... but don't ICE.
6377        return None;
6378    };
6379    let Some(hir::PathSegment { args: Some(args), .. }) = trait_ref.trait_ref.path.segments.last()
6380    else {
6381        // desugaring to a single path segment for `Future<...>`.
6382        return None;
6383    };
6384    let Some(future_output_ty) = args.constraints.first().and_then(|constraint| constraint.ty())
6385    else {
6386        // Also should never happen.
6387        return None;
6388    };
6389
6390    let mut sugg = if future_output_ty.span.is_empty() {
6391        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(async_span, String::new()),
                (future_output_ty.span,
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(" -> impl std::future::Future<Output = ()>{0}",
                                    add_bounds))
                        }))]))vec![
6392            (async_span, String::new()),
6393            (
6394                future_output_ty.span,
6395                format!(" -> impl std::future::Future<Output = ()>{add_bounds}"),
6396            ),
6397        ]
6398    } else {
6399        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(future_output_ty.span.shrink_to_lo(),
                    "impl std::future::Future<Output = ".to_owned()),
                (future_output_ty.span.shrink_to_hi(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(">{0}", add_bounds))
                        })), (async_span, String::new())]))vec![
6400            (future_output_ty.span.shrink_to_lo(), "impl std::future::Future<Output = ".to_owned()),
6401            (future_output_ty.span.shrink_to_hi(), format!(">{add_bounds}")),
6402            (async_span, String::new()),
6403        ]
6404    };
6405
6406    // If there's a body, we also need to wrap it in `async {}`
6407    if let hir::TraitFn::Provided(body) = body {
6408        let body = tcx.hir_body(body);
6409        let body_span = body.value.span;
6410        let body_span_without_braces =
6411            body_span.with_lo(body_span.lo() + BytePos(1)).with_hi(body_span.hi() - BytePos(1));
6412        if body_span_without_braces.is_empty() {
6413            sugg.push((body_span_without_braces, " async {} ".to_owned()));
6414        } else {
6415            sugg.extend([
6416                (body_span_without_braces.shrink_to_lo(), "async {".to_owned()),
6417                (body_span_without_braces.shrink_to_hi(), "} ".to_owned()),
6418            ]);
6419        }
6420    }
6421
6422    Some(sugg)
6423}
6424
6425/// On `impl` evaluation cycles, look for `Self::AssocTy` restrictions in `where` clauses, explain
6426/// they are not allowed and if possible suggest alternatives.
6427fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
6428    tcx: TyCtxt<'_>,
6429    err: &mut Diag<'_, G>,
6430    self_ty_str: &str,
6431    trait_name: &str,
6432    predicate: ty::Predicate<'_>,
6433    generics: &hir::Generics<'_>,
6434    data: &ImplDerivedCause<'_>,
6435) {
6436    let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() else {
6437        return;
6438    };
6439    let ty::ClauseKind::Projection(proj) = clause else {
6440        return;
6441    };
6442    let Some(name) = tcx
6443        .opt_rpitit_info(proj.def_id())
6444        .and_then(|data| match data {
6445            ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => Some(tcx.item_name(fn_def_id)),
6446            ty::ImplTraitInTraitData::Impl { .. } => None,
6447        })
6448        .or_else(|| tcx.opt_item_name(proj.def_id()))
6449    else {
6450        return;
6451    };
6452    let mut predicates = generics.predicates.iter().peekable();
6453    let mut prev: Option<(&hir::WhereBoundPredicate<'_>, Span)> = None;
6454    while let Some(pred) = predicates.next() {
6455        let curr_span = pred.span;
6456        let hir::WherePredicateKind::BoundPredicate(pred) = pred.kind else {
6457            continue;
6458        };
6459        let mut bounds = pred.bounds.iter();
6460        while let Some(bound) = bounds.next() {
6461            let Some(trait_ref) = bound.trait_ref() else {
6462                continue;
6463            };
6464            if bound.span() != data.span {
6465                continue;
6466            }
6467            if let hir::TyKind::Path(path) = pred.bounded_ty.kind
6468                && let hir::QPath::TypeRelative(ty, segment) = path
6469                && segment.ident.name == name
6470                && let hir::TyKind::Path(inner_path) = ty.kind
6471                && let hir::QPath::Resolved(None, inner_path) = inner_path
6472                && let Res::SelfTyAlias { .. } = inner_path.res
6473            {
6474                // The following block is to determine the right span to delete for this bound
6475                // that will leave valid code after the suggestion is applied.
6476                let span = if pred.origin == hir::PredicateOrigin::WhereClause
6477                    && generics
6478                        .predicates
6479                        .iter()
6480                        .filter(|p| {
6481                            #[allow(non_exhaustive_omitted_patterns)] match p.kind {
    hir::WherePredicateKind::BoundPredicate(p) if
        hir::PredicateOrigin::WhereClause == p.origin => true,
    _ => false,
}matches!(
6482                                p.kind,
6483                                hir::WherePredicateKind::BoundPredicate(p)
6484                                if hir::PredicateOrigin::WhereClause == p.origin
6485                            )
6486                        })
6487                        .count()
6488                        == 1
6489                {
6490                    // There's only one `where` bound, that needs to be removed. Remove the whole
6491                    // `where` clause.
6492                    generics.where_clause_span
6493                } else if let Some(next_pred) = predicates.peek()
6494                    && let hir::WherePredicateKind::BoundPredicate(next) = next_pred.kind
6495                    && pred.origin == next.origin
6496                {
6497                    // There's another bound, include the comma for the current one.
6498                    curr_span.until(next_pred.span)
6499                } else if let Some((prev, prev_span)) = prev
6500                    && pred.origin == prev.origin
6501                {
6502                    // Last bound, try to remove the previous comma.
6503                    prev_span.shrink_to_hi().to(curr_span)
6504                } else if pred.origin == hir::PredicateOrigin::WhereClause {
6505                    curr_span.with_hi(generics.where_clause_span.hi())
6506                } else {
6507                    curr_span
6508                };
6509
6510                err.span_suggestion_verbose(
6511                    span,
6512                    "associated type for the current `impl` cannot be restricted in `where` \
6513                     clauses, remove this bound",
6514                    "",
6515                    Applicability::MaybeIncorrect,
6516                );
6517            }
6518            if let Some(new) =
6519                tcx.associated_items(data.impl_or_alias_def_id).find_by_ident_and_kind(
6520                    tcx,
6521                    Ident::with_dummy_span(name),
6522                    ty::AssocTag::Type,
6523                    data.impl_or_alias_def_id,
6524                )
6525            {
6526                // The associated type is specified in the `impl` we're
6527                // looking at. Point at it.
6528                let span = tcx.def_span(new.def_id);
6529                err.span_label(
6530                    span,
6531                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("associated type `<{0} as {1}>::{2}` is specified here",
                self_ty_str, trait_name, name))
    })format!(
6532                        "associated type `<{self_ty_str} as {trait_name}>::{name}` is specified \
6533                         here",
6534                    ),
6535                );
6536                // Search for the associated type `Self::{name}`, get
6537                // its type and suggest replacing the bound with it.
6538                let mut visitor = SelfVisitor { name: Some(name), .. };
6539                visitor.visit_trait_ref(trait_ref);
6540                for path in visitor.paths {
6541                    err.span_suggestion_verbose(
6542                        path.span,
6543                        "replace the associated type with the type specified in this `impl`",
6544                        tcx.type_of(new.def_id).skip_binder(),
6545                        Applicability::MachineApplicable,
6546                    );
6547                }
6548            } else {
6549                let mut visitor = SelfVisitor { name: None, .. };
6550                visitor.visit_trait_ref(trait_ref);
6551                let span: MultiSpan =
6552                    visitor.paths.iter().map(|p| p.span).collect::<Vec<Span>>().into();
6553                err.span_note(
6554                    span,
6555                    "associated types for the current `impl` cannot be restricted in `where` \
6556                     clauses",
6557                );
6558            }
6559        }
6560        prev = Some((pred, curr_span));
6561    }
6562}
6563
6564fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) {
6565    let mut refs = ::alloc::vec::Vec::new()vec![];
6566
6567    while let ty::Ref(_, new_ty, mutbl) = ty.kind() {
6568        ty = *new_ty;
6569        refs.push(*mutbl);
6570    }
6571
6572    (ty, refs)
6573}
6574
6575/// Look for type `param` in an ADT being used only through a reference to confirm that suggesting
6576/// `param: ?Sized` would be a valid constraint.
6577struct FindTypeParam {
6578    param: rustc_span::Symbol,
6579    invalid_spans: Vec<Span> = Vec::new(),
6580    nested: bool = false,
6581}
6582
6583impl<'v> Visitor<'v> for FindTypeParam {
6584    fn visit_where_predicate(&mut self, _: &'v hir::WherePredicate<'v>) {
6585        // Skip where-clauses, to avoid suggesting indirection for type parameters found there.
6586    }
6587
6588    fn visit_ty(&mut self, ty: &hir::Ty<'_, AmbigArg>) {
6589        // We collect the spans of all uses of the "bare" type param, like in `field: T` or
6590        // `field: (T, T)` where we could make `T: ?Sized` while skipping cases that are known to be
6591        // valid like `field: &'a T` or `field: *mut T` and cases that *might* have further `Sized`
6592        // obligations like `Box<T>` and `Vec<T>`, but we perform no extra analysis for those cases
6593        // and suggest `T: ?Sized` regardless of their obligations. This is fine because the errors
6594        // in that case should make what happened clear enough.
6595        match ty.kind {
6596            hir::TyKind::Ptr(_) | hir::TyKind::Ref(..) | hir::TyKind::TraitObject(..) => {}
6597            hir::TyKind::Path(hir::QPath::Resolved(None, path))
6598                if let [segment] = path.segments
6599                    && segment.ident.name == self.param =>
6600            {
6601                if !self.nested {
6602                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs:6602",
                        "rustc_trait_selection::error_reporting::traits::suggestions",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs"),
                        ::tracing_core::__macro_support::Option::Some(6602u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::traits::suggestions"),
                        ::tracing_core::field::FieldSet::new(&["message", "ty"],
                            ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("FindTypeParam::visit_ty")
                                            as &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&ty) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?ty, "FindTypeParam::visit_ty");
6603                    self.invalid_spans.push(ty.span);
6604                }
6605            }
6606            hir::TyKind::Path(_) => {
6607                let prev = self.nested;
6608                self.nested = true;
6609                hir::intravisit::walk_ty(self, ty);
6610                self.nested = prev;
6611            }
6612            _ => {
6613                hir::intravisit::walk_ty(self, ty);
6614            }
6615        }
6616    }
6617}
6618
6619/// Look for type parameters in predicates. We use this to identify whether a bound is suitable in
6620/// on a given item.
6621struct ParamFinder {
6622    params: Vec<Symbol> = Vec::new(),
6623}
6624
6625impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParamFinder {
6626    fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
6627        match t.kind() {
6628            ty::Param(p) => self.params.push(p.name),
6629            _ => {}
6630        }
6631        t.super_visit_with(self)
6632    }
6633}
6634
6635impl ParamFinder {
6636    /// Whether the `hir::Generics` of the current item can suggest the evaluated bound because its
6637    /// references to type parameters are present in the generics.
6638    fn can_suggest_bound(&self, generics: &hir::Generics<'_>) -> bool {
6639        if self.params.is_empty() {
6640            // There are no references to type parameters at all, so suggesting the bound
6641            // would be reasonable.
6642            return true;
6643        }
6644        generics.params.iter().any(|p| match p.name {
6645            hir::ParamName::Plain(p_name) => {
6646                // All of the parameters in the bound can be referenced in the current item.
6647                self.params.iter().any(|p| *p == p_name.name || *p == kw::SelfUpper)
6648            }
6649            _ => true,
6650        })
6651    }
6652}