Skip to main content

rustc_hir_analysis/hir_ty_lowering/
dyn_trait.rs

1use rustc_ast::TraitObjectSyntax;
2use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
3use rustc_errors::codes::*;
4use rustc_errors::{
5    Applicability, Diag, EmissionGuarantee, StashKey, Suggestions, struct_span_code_err,
6};
7use rustc_hir::def::{DefKind, Res};
8use rustc_hir::def_id::DefId;
9use rustc_hir::{self as hir, LangItem};
10use rustc_lint_defs::builtin::{BARE_TRAIT_OBJECTS, UNUSED_ASSOCIATED_TYPE_BOUNDS};
11use rustc_middle::ty::elaborate::ClauseWithSupertraitSpan;
12use rustc_middle::ty::{
13    self, BottomUpFolder, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
14    TypeVisitableExt, Upcast,
15};
16use rustc_span::edit_distance::find_best_match_for_name;
17use rustc_span::{ErrorGuaranteed, Span};
18use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
19use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
20use rustc_trait_selection::traits;
21use smallvec::{SmallVec, smallvec};
22use tracing::{debug, instrument};
23
24use super::HirTyLowerer;
25use crate::errors::DynTraitAssocItemBindingMentionsSelf;
26use crate::hir_ty_lowering::{
27    GenericArgCountMismatch, ImpliedBoundsContext, OverlappingAsssocItemConstraints,
28    PredicateFilter, RegionInferReason,
29};
30
31impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
32    /// Lower a trait object type from the HIR to our internal notion of a type.
33    x;#[instrument(level = "debug", skip_all, ret)]
34    pub(super) fn lower_trait_object_ty(
35        &self,
36        span: Span,
37        hir_id: hir::HirId,
38        hir_bounds: &[hir::PolyTraitRef<'tcx>],
39        lifetime: &hir::Lifetime,
40        syntax: TraitObjectSyntax,
41    ) -> Ty<'tcx> {
42        let tcx = self.tcx();
43        let dummy_self = tcx.types.trait_object_dummy_self;
44
45        match syntax {
46            TraitObjectSyntax::Dyn => {}
47            TraitObjectSyntax::None => {
48                match self.prohibit_or_lint_bare_trait_object_ty(span, hir_id, hir_bounds) {
49                    // Don't continue with type analysis if the `dyn` keyword is missing.
50                    // It generates confusing errors, especially if the user meant to use
51                    // another keyword like `impl`.
52                    Some(guar) => return Ty::new_error(tcx, guar),
53                    None => {}
54                }
55            }
56        }
57
58        let mut user_written_bounds = Vec::new();
59        let mut potential_assoc_items = Vec::new();
60        for poly_trait_ref in hir_bounds.iter() {
61            // FIXME(mgca): We actually leak `trait_object_dummy_self` if the type of any assoc
62            //              const mentions `Self` (in "Self projections" which we intentionally
63            //              allow). That's because we query feed the instantiated type to `type_of`.
64            //              That's really bad, dummy self should never escape lowering! It leads us
65            //              to accept less code we'd like to support and can lead to ICEs later.
66            let result = self.lower_poly_trait_ref(
67                poly_trait_ref,
68                dummy_self,
69                &mut user_written_bounds,
70                PredicateFilter::SelfOnly,
71                OverlappingAsssocItemConstraints::Forbidden,
72            );
73            if let Err(GenericArgCountMismatch { invalid_args, .. }) = result.correct {
74                potential_assoc_items.extend(invalid_args);
75            }
76        }
77
78        self.add_default_traits(
79            &mut user_written_bounds,
80            dummy_self,
81            &hir_bounds
82                .iter()
83                .map(|&trait_ref| hir::GenericBound::Trait(trait_ref))
84                .collect::<Vec<_>>(),
85            ImpliedBoundsContext::AssociatedTypeOrImplTrait,
86            span,
87        );
88
89        let (mut elaborated_trait_bounds, elaborated_projection_bounds) =
90            traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied());
91
92        // FIXME(sized-hierarchy): https://github.com/rust-lang/rust/pull/142712#issuecomment-3013231794
93        debug!(?user_written_bounds, ?elaborated_trait_bounds);
94        let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
95        // Don't strip out `MetaSized` when the user wrote it explicitly, only when it was
96        // elaborated
97        if user_written_bounds
98            .iter()
99            .all(|(clause, _)| clause.as_trait_clause().map(|p| p.def_id()) != Some(meta_sized_did))
100        {
101            elaborated_trait_bounds.retain(|(pred, _)| pred.def_id() != meta_sized_did);
102        }
103        debug!(?user_written_bounds, ?elaborated_trait_bounds);
104
105        let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = elaborated_trait_bounds
106            .into_iter()
107            .partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
108
109        // We don't support empty trait objects.
110        if regular_traits.is_empty() && auto_traits.is_empty() {
111            let guar =
112                self.report_trait_object_with_no_traits(span, user_written_bounds.iter().copied());
113            return Ty::new_error(tcx, guar);
114        }
115        // We don't support >1 principal
116        if regular_traits.len() > 1 {
117            let guar = self.report_trait_object_addition_traits(&regular_traits);
118            return Ty::new_error(tcx, guar);
119        }
120        // Don't create a dyn trait if we have errors in the principal.
121        if let Err(guar) = regular_traits.error_reported() {
122            return Ty::new_error(tcx, guar);
123        }
124
125        // Check that there are no gross dyn-compatibility violations;
126        // most importantly, that the supertraits don't contain `Self`,
127        // to avoid ICEs.
128        for (clause, span) in user_written_bounds {
129            if let Some(trait_pred) = clause.as_trait_clause() {
130                let violations = self.dyn_compatibility_violations(trait_pred.def_id());
131                if !violations.is_empty() {
132                    let reported = report_dyn_incompatibility(
133                        tcx,
134                        span,
135                        Some(hir_id),
136                        trait_pred.def_id(),
137                        &violations,
138                    )
139                    .emit();
140                    return Ty::new_error(tcx, reported);
141                }
142            }
143        }
144
145        // Map the projection bounds onto a key that makes it easy to remove redundant
146        // bounds that are constrained by supertraits of the principal trait.
147        //
148        // Also make sure we detect conflicting bounds from expanding trait aliases.
149        //
150        // FIXME(#150936): Since the elaborated projection bounds also include the user-written ones
151        //                 and we're separately rejecting duplicate+conflicting bindings for trait
152        //                 object types when lowering assoc item bindings, there are basic cases
153        //                 where we're emitting two distinct but very similar diagnostics.
154        let mut projection_bounds = FxIndexMap::default();
155        for (proj, proj_span) in elaborated_projection_bounds {
156            let item_def_id = proj.item_def_id();
157
158            let proj = proj.map_bound(|mut proj| {
159                let references_self = proj.term.walk().any(|arg| arg == dummy_self.into());
160                if references_self {
161                    let guar = self.dcx().emit_err(DynTraitAssocItemBindingMentionsSelf {
162                        span,
163                        kind: tcx.def_descr(item_def_id),
164                        binding: proj_span,
165                    });
166                    proj.term = replace_dummy_self_with_error(tcx, proj.term, guar);
167                }
168                proj
169            });
170
171            let key = (
172                item_def_id,
173                tcx.anonymize_bound_vars(
174                    proj.map_bound(|proj| proj.projection_term.trait_ref(tcx)),
175                ),
176            );
177            if let Some((old_proj, old_proj_span)) =
178                projection_bounds.insert(key, (proj, proj_span))
179                && tcx.anonymize_bound_vars(proj) != tcx.anonymize_bound_vars(old_proj)
180            {
181                let kind = tcx.def_descr(item_def_id);
182                let name = tcx.item_name(item_def_id);
183                self.dcx()
184                    .struct_span_err(span, format!("conflicting {kind} bindings for `{name}`"))
185                    .with_span_label(
186                        old_proj_span,
187                        format!("`{name}` is specified to be `{}` here", old_proj.term()),
188                    )
189                    .with_span_label(
190                        proj_span,
191                        format!("`{name}` is specified to be `{}` here", proj.term()),
192                    )
193                    .emit();
194            }
195        }
196
197        let principal_trait = regular_traits.into_iter().next();
198
199        // A stable ordering of associated types & consts from the principal trait and all its
200        // supertraits. We use this to ensure that different substitutions of a trait don't
201        // result in `dyn Trait` types with different projections lists, which can be unsound:
202        // <https://github.com/rust-lang/rust/pull/136458>.
203        // We achieve a stable ordering by walking over the unsubstituted principal trait ref.
204        let mut ordered_associated_items = vec![];
205
206        if let Some((principal_trait, ref spans)) = principal_trait {
207            let principal_trait = principal_trait.map_bound(|trait_pred| {
208                assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
209                trait_pred.trait_ref
210            });
211
212            for ClauseWithSupertraitSpan { clause, supertrait_span } in traits::elaborate(
213                tcx,
214                [ClauseWithSupertraitSpan::new(
215                    ty::TraitRef::identity(tcx, principal_trait.def_id()).upcast(tcx),
216                    *spans.last().unwrap(),
217                )],
218            )
219            .filter_only_self()
220            {
221                let clause = clause.instantiate_supertrait(tcx, principal_trait);
222                debug!("observing object predicate `{clause:?}`");
223
224                let bound_predicate = clause.kind();
225                match bound_predicate.skip_binder() {
226                    ty::ClauseKind::Trait(pred) => {
227                        // FIXME(negative_bounds): Handle this correctly...
228                        let trait_ref =
229                            tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
230                        ordered_associated_items.extend(
231                            tcx.associated_items(pred.trait_ref.def_id)
232                                .in_definition_order()
233                                // Only associated types & type consts can possibly be
234                                // constrained in a trait object type via a binding.
235                                .filter(|item| item.is_type() || item.is_type_const(tcx))
236                                // Traits with RPITITs are simply not dyn compatible (for now).
237                                .filter(|item| !item.is_impl_trait_in_trait())
238                                .map(|item| (item.def_id, trait_ref)),
239                        );
240                    }
241                    ty::ClauseKind::Projection(pred) => {
242                        let pred = bound_predicate.rebind(pred);
243                        // A `Self` within the original bound will be instantiated with a
244                        // `trait_object_dummy_self`, so check for that.
245                        let references_self =
246                            pred.skip_binder().term.walk().any(|arg| arg == dummy_self.into());
247
248                        // If the projection output contains `Self`, force the user to
249                        // elaborate it explicitly to avoid a lot of complexity.
250                        //
251                        // The "classically useful" case is the following:
252                        // ```
253                        //     trait MyTrait: FnMut() -> <Self as MyTrait>::MyOutput {
254                        //         type MyOutput;
255                        //     }
256                        // ```
257                        //
258                        // Here, the user could theoretically write `dyn MyTrait<MyOutput = X>`,
259                        // but actually supporting that would "expand" to an infinitely-long type
260                        // `fix $ τ → dyn MyTrait<MyOutput = X, Output = <τ as MyTrait>::MyOutput`.
261                        //
262                        // Instead, we force the user to write
263                        // `dyn MyTrait<MyOutput = X, Output = X>`, which is uglier but works. See
264                        // the discussion in #56288 for alternatives.
265                        if !references_self {
266                            let key = (
267                                pred.item_def_id(),
268                                tcx.anonymize_bound_vars(
269                                    pred.map_bound(|proj| proj.projection_term.trait_ref(tcx)),
270                                ),
271                            );
272                            if !projection_bounds.contains_key(&key) {
273                                projection_bounds.insert(key, (pred, supertrait_span));
274                            }
275                        }
276
277                        self.check_elaborated_projection_mentions_input_lifetimes(
278                            pred,
279                            *spans.first().unwrap(),
280                            supertrait_span,
281                        );
282                    }
283                    _ => (),
284                }
285            }
286        }
287
288        // Flag assoc item bindings that didn't really need to be specified.
289        for &(projection_bound, span) in projection_bounds.values() {
290            let def_id = projection_bound.item_def_id();
291            if tcx.generics_require_sized_self(def_id) {
292                // FIXME(mgca): Ideally we would generalize the name of this lint to sth. like
293                // `unused_associated_item_bindings` since this can now also trigger on *const*
294                // projections / assoc *const* bindings.
295                tcx.emit_node_span_lint(
296                    UNUSED_ASSOCIATED_TYPE_BOUNDS,
297                    hir_id,
298                    span,
299                    crate::errors::UnusedAssociatedTypeBounds { span },
300                );
301            }
302        }
303
304        // The user has to constrain all associated types & consts via bindings unless the
305        // corresponding associated item has a `where Self: Sized` clause. This can be done
306        // in the `dyn Trait` directly, in the supertrait bounds or behind trait aliases.
307        //
308        // Collect all associated items that weren't specified and compute the list of
309        // projection bounds which we'll later turn into existential ones.
310        //
311        // We intentionally keep around projections whose associated item has a `Self: Sized`
312        // bound in order to be able to wfcheck the RHS, allow the RHS to constrain generic
313        // parameters and to imply bounds.
314        // See also <https://github.com/rust-lang/rust/pull/140684>.
315        let mut missing_assoc_items = FxIndexSet::default();
316        let projection_bounds: Vec<_> = ordered_associated_items
317            .into_iter()
318            .filter_map(|key @ (def_id, _)| {
319                if let Some(&assoc) = projection_bounds.get(&key) {
320                    return Some(assoc);
321                }
322                if !tcx.generics_require_sized_self(def_id) {
323                    missing_assoc_items.insert(key);
324                }
325                None
326            })
327            .collect();
328
329        // If there are any associated items whose value wasn't provided, bail out with an error.
330        if let Err(guar) = self.check_for_required_assoc_items(
331            principal_trait.as_ref().map_or(smallvec![], |(_, spans)| spans.clone()),
332            missing_assoc_items,
333            potential_assoc_items,
334            hir_bounds,
335        ) {
336            return Ty::new_error(tcx, guar);
337        }
338
339        // De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
340        // `dyn Trait + Send`.
341        // We remove duplicates by inserting into a `FxHashSet` to avoid re-ordering
342        // the bounds
343        let mut duplicates = FxHashSet::default();
344        auto_traits.retain(|(trait_pred, _)| duplicates.insert(trait_pred.def_id()));
345
346        debug!(?principal_trait);
347        debug!(?auto_traits);
348
349        // Erase the `dummy_self` (`trait_object_dummy_self`) used above.
350        let principal_trait_ref = principal_trait.map(|(trait_pred, spans)| {
351            trait_pred.map_bound(|trait_pred| {
352                let trait_ref = trait_pred.trait_ref;
353                assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
354                assert_eq!(trait_ref.self_ty(), dummy_self);
355
356                let span = *spans.first().unwrap();
357
358                // Verify that `dummy_self` did not leak inside generic parameter defaults. This
359                // could not be done at path creation, since we need to see through trait aliases.
360                let mut missing_generic_params = Vec::new();
361                let generics = tcx.generics_of(trait_ref.def_id);
362                let args: Vec<_> = trait_ref
363                    .args
364                    .iter()
365                    .enumerate()
366                    // Skip `Self`
367                    .skip(1)
368                    .map(|(index, arg)| {
369                        if arg.walk().any(|arg| arg == dummy_self.into()) {
370                            let param = &generics.own_params[index];
371                            missing_generic_params.push((param.name, param.kind.clone()));
372                            param.to_error(tcx)
373                        } else {
374                            arg
375                        }
376                    })
377                    .collect();
378
379                let empty_generic_args = hir_bounds.iter().any(|hir_bound| {
380                    hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
381                        && hir_bound.span.contains(span)
382                });
383                self.report_missing_generic_params(
384                    missing_generic_params,
385                    trait_ref.def_id,
386                    span,
387                    empty_generic_args,
388                );
389
390                ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new(
391                    tcx,
392                    trait_ref.def_id,
393                    args,
394                ))
395            })
396        });
397
398        let existential_projections = projection_bounds.into_iter().map(|(bound, _)| {
399            bound.map_bound(|mut b| {
400                assert_eq!(b.projection_term.self_ty(), dummy_self);
401
402                // Like for trait refs, verify that `dummy_self` did not leak inside default type
403                // parameters.
404                let references_self = b.projection_term.args.iter().skip(1).any(|arg| {
405                    if arg.walk().any(|arg| arg == dummy_self.into()) {
406                        return true;
407                    }
408                    false
409                });
410                if references_self {
411                    let guar = tcx
412                        .dcx()
413                        .span_delayed_bug(span, "trait object projection bounds reference `Self`");
414                    b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar);
415                }
416
417                ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(
418                    tcx, b,
419                ))
420            })
421        });
422
423        let mut auto_trait_predicates: Vec<_> = auto_traits
424            .into_iter()
425            .map(|(trait_pred, _)| {
426                assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive);
427                assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self);
428
429                ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id()))
430            })
431            .collect();
432        auto_trait_predicates.dedup();
433
434        // N.b. principal, projections, auto traits
435        // FIXME: This is actually wrong with multiple principals in regards to symbol mangling
436        let mut v = principal_trait_ref
437            .into_iter()
438            .chain(existential_projections)
439            .chain(auto_trait_predicates)
440            .collect::<SmallVec<[_; 8]>>();
441        v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
442        let existential_predicates = tcx.mk_poly_existential_predicates(&v);
443
444        // Use explicitly-specified region bound, unless the bound is missing.
445        let region_bound = if !lifetime.is_elided() {
446            self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
447        } else {
448            self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
449                // Curiously, we prefer object lifetime default for `+ '_`...
450                if tcx.named_bound_var(lifetime.hir_id).is_some() {
451                    self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
452                } else {
453                    let reason =
454                        if let hir::LifetimeKind::ImplicitObjectLifetimeDefault = lifetime.kind {
455                            RegionInferReason::ObjectLifetimeDefault(span.shrink_to_hi())
456                        } else {
457                            RegionInferReason::ExplicitObjectLifetime
458                        };
459                    self.re_infer(span, reason)
460                }
461            })
462        };
463        debug!(?region_bound);
464
465        Ty::new_dynamic(tcx, existential_predicates, region_bound)
466    }
467
468    /// Check that elaborating the principal of a trait ref doesn't lead to projections
469    /// that are unconstrained. This can happen because an otherwise unconstrained
470    /// *type variable* can be substituted with a type that has late-bound regions. See
471    /// `elaborated-predicates-unconstrained-late-bound.rs` for a test.
472    fn check_elaborated_projection_mentions_input_lifetimes(
473        &self,
474        pred: ty::PolyProjectionPredicate<'tcx>,
475        span: Span,
476        supertrait_span: Span,
477    ) {
478        let tcx = self.tcx();
479
480        // Find any late-bound regions declared in `ty` that are not
481        // declared in the trait-ref or assoc_item. These are not well-formed.
482        //
483        // Example:
484        //
485        //     for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
486        //     for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
487        let late_bound_in_projection_term =
488            tcx.collect_constrained_late_bound_regions(pred.map_bound(|pred| pred.projection_term));
489        let late_bound_in_term =
490            tcx.collect_referenced_late_bound_regions(pred.map_bound(|pred| pred.term));
491        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:491",
                        "rustc_hir_analysis::hir_ty_lowering::dyn_trait",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
                        ::tracing_core::__macro_support::Option::Some(491u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
                        ::tracing_core::field::FieldSet::new(&["late_bound_in_projection_term"],
                            ::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(&late_bound_in_projection_term)
                                            as &dyn Value))])
            });
    } else { ; }
};debug!(?late_bound_in_projection_term);
492        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:492",
                        "rustc_hir_analysis::hir_ty_lowering::dyn_trait",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
                        ::tracing_core::__macro_support::Option::Some(492u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
                        ::tracing_core::field::FieldSet::new(&["late_bound_in_term"],
                            ::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(&late_bound_in_term)
                                            as &dyn Value))])
            });
    } else { ; }
};debug!(?late_bound_in_term);
493
494        // FIXME: point at the type params that don't have appropriate lifetimes:
495        // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
496        //                         ----  ----     ^^^^^^^
497        // NOTE(mgca): This error should be impossible to trigger with assoc const bindings.
498        self.validate_late_bound_regions(
499            late_bound_in_projection_term,
500            late_bound_in_term,
501            |br_name| {
502                let item_name = tcx.item_name(pred.item_def_id());
503                {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("binding for associated type `{0}` references {1}, which does not appear in the trait input types",
                            item_name, br_name))
                })).with_code(E0582)
}struct_span_code_err!(
504                    self.dcx(),
505                    span,
506                    E0582,
507                    "binding for associated type `{}` references {}, \
508                             which does not appear in the trait input types",
509                    item_name,
510                    br_name
511                )
512                .with_span_label(supertrait_span, "due to this supertrait")
513            },
514        );
515    }
516
517    /// Prohibit or lint against *bare* trait object types depending on the edition.
518    ///
519    /// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
520    /// In edition 2021 and onward we emit a hard error for them.
521    fn prohibit_or_lint_bare_trait_object_ty(
522        &self,
523        span: Span,
524        hir_id: hir::HirId,
525        hir_bounds: &[hir::PolyTraitRef<'tcx>],
526    ) -> Option<ErrorGuaranteed> {
527        let tcx = self.tcx();
528        let [poly_trait_ref, ..] = hir_bounds else { return None };
529
530        let in_path = match tcx.parent_hir_node(hir_id) {
531            hir::Node::Ty(hir::Ty {
532                kind: hir::TyKind::Path(hir::QPath::TypeRelative(qself, _)),
533                ..
534            })
535            | hir::Node::Expr(hir::Expr {
536                kind: hir::ExprKind::Path(hir::QPath::TypeRelative(qself, _)),
537                ..
538            })
539            | hir::Node::PatExpr(hir::PatExpr {
540                kind: hir::PatExprKind::Path(hir::QPath::TypeRelative(qself, _)),
541                ..
542            }) if qself.hir_id == hir_id => true,
543            _ => false,
544        };
545        let needs_bracket = in_path
546            && !tcx
547                .sess
548                .source_map()
549                .span_to_prev_source(span)
550                .ok()
551                .is_some_and(|s| s.trim_end().ends_with('<'));
552
553        let is_global = poly_trait_ref.trait_ref.path.is_global();
554
555        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!("{0}dyn {1}",
                                    if needs_bracket { "<" } else { "" },
                                    if is_global { "(" } else { "" }))
                        }))]))vec![(
556            span.shrink_to_lo(),
557            format!(
558                "{}dyn {}",
559                if needs_bracket { "<" } else { "" },
560                if is_global { "(" } else { "" },
561            ),
562        )];
563
564        if is_global || needs_bracket {
565            sugg.push((
566                span.shrink_to_hi(),
567                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}",
                if is_global { ")" } else { "" },
                if needs_bracket { ">" } else { "" }))
    })format!(
568                    "{}{}",
569                    if is_global { ")" } else { "" },
570                    if needs_bracket { ">" } else { "" },
571                ),
572            ));
573        }
574
575        if span.edition().at_least_rust_2021() {
576            let mut diag = {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("{0}",
                            "expected a type, found a trait"))
                })).with_code(E0782)
}rustc_errors::struct_span_code_err!(
577                self.dcx(),
578                span,
579                E0782,
580                "{}",
581                "expected a type, found a trait"
582            );
583            if span.can_be_used_for_suggestions()
584                && poly_trait_ref.trait_ref.trait_def_id().is_some()
585                && !self.maybe_suggest_impl_trait(span, hir_id, hir_bounds, &mut diag)
586                && !self.maybe_suggest_dyn_trait(hir_id, span, sugg, &mut diag)
587            {
588                self.maybe_suggest_add_generic_impl_trait(span, hir_id, &mut diag);
589            }
590            // Check if the impl trait that we are considering is an impl of a local trait.
591            self.maybe_suggest_blanket_trait_impl(span, hir_id, &mut diag);
592            self.maybe_suggest_assoc_ty_bound(hir_id, &mut diag);
593            self.maybe_suggest_typoed_method(
594                hir_id,
595                poly_trait_ref.trait_ref.trait_def_id(),
596                &mut diag,
597            );
598            // In case there is an associated type with the same name
599            // Add the suggestion to this error
600            if let Some(mut sugg) =
601                self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion)
602                && let Suggestions::Enabled(ref mut s1) = diag.suggestions
603                && let Suggestions::Enabled(ref mut s2) = sugg.suggestions
604            {
605                s1.append(s2);
606                sugg.cancel();
607            }
608            Some(diag.emit())
609        } else {
610            tcx.node_span_lint(BARE_TRAIT_OBJECTS, hir_id, span, |lint| {
611                lint.primary_message("trait objects without an explicit `dyn` are deprecated");
612                if span.can_be_used_for_suggestions() {
613                    lint.multipart_suggestion(
614                        "if this is a dyn-compatible trait, use `dyn`",
615                        sugg,
616                        Applicability::MachineApplicable,
617                    );
618                }
619                self.maybe_suggest_blanket_trait_impl(span, hir_id, lint);
620            });
621            None
622        }
623    }
624
625    /// For a struct or enum with an invalid bare trait object field, suggest turning
626    /// it into a generic type bound.
627    fn maybe_suggest_add_generic_impl_trait(
628        &self,
629        span: Span,
630        hir_id: hir::HirId,
631        diag: &mut Diag<'_>,
632    ) -> bool {
633        let tcx = self.tcx();
634
635        let parent_hir_id = tcx.parent_hir_id(hir_id);
636        let parent_item = tcx.hir_get_parent_item(hir_id).def_id;
637
638        let generics = match tcx.hir_node_by_def_id(parent_item) {
639            hir::Node::Item(hir::Item {
640                kind: hir::ItemKind::Struct(_, generics, variant),
641                ..
642            }) => {
643                if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) {
644                    return false;
645                }
646                generics
647            }
648            hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(_, generics, def), .. }) => {
649                if !def
650                    .variants
651                    .iter()
652                    .flat_map(|variant| variant.data.fields().iter())
653                    .any(|field| field.hir_id == parent_hir_id)
654                {
655                    return false;
656                }
657                generics
658            }
659            _ => return false,
660        };
661
662        let Ok(rendered_ty) = tcx.sess.source_map().span_to_snippet(span) else {
663            return false;
664        };
665
666        let param = "TUV"
667            .chars()
668            .map(|c| c.to_string())
669            .chain((0..).map(|i| ::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("P{0}", i)) })format!("P{i}")))
670            .find(|s| !generics.params.iter().any(|param| param.name.ident().as_str() == s))
671            .expect("we definitely can find at least one param name to generate");
672        let mut sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span, param.to_string())]))vec![(span, param.to_string())];
673        if let Some(insertion_span) = generics.span_for_param_suggestion() {
674            sugg.push((insertion_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(", {1}: {0}", rendered_ty, param))
    })format!(", {param}: {}", rendered_ty)));
675        } else {
676            sugg.push((generics.where_clause_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{1}: {0}>", rendered_ty, param))
    })format!("<{param}: {}>", rendered_ty)));
677        }
678        diag.multipart_suggestion(
679            "you might be missing a type parameter",
680            sugg,
681            Applicability::MachineApplicable,
682        );
683        true
684    }
685
686    /// Make sure that we are in the condition to suggest the blanket implementation.
687    fn maybe_suggest_blanket_trait_impl<G: EmissionGuarantee>(
688        &self,
689        span: Span,
690        hir_id: hir::HirId,
691        diag: &mut Diag<'_, G>,
692    ) {
693        let tcx = self.tcx();
694        let parent_id = tcx.hir_get_parent_item(hir_id).def_id;
695        if let hir::Node::Item(hir::Item {
696            kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, of_trait, generics, .. }),
697            ..
698        }) = tcx.hir_node_by_def_id(parent_id)
699            && hir_id == impl_self_ty.hir_id
700        {
701            let Some(of_trait) = of_trait else {
702                diag.span_suggestion_verbose(
703                    impl_self_ty.span.shrink_to_hi(),
704                    "you might have intended to implement this trait for a given type",
705                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" for /* Type */"))
    })format!(" for /* Type */"),
706                    Applicability::HasPlaceholders,
707                );
708                return;
709            };
710            if !of_trait.trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
711                return;
712            }
713            let of_trait_span = of_trait.trait_ref.path.span;
714            // make sure that we are not calling unwrap to abort during the compilation
715            let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else {
716                return;
717            };
718
719            let Ok(impl_trait_name) = self.tcx().sess.source_map().span_to_snippet(span) else {
720                return;
721            };
722            let sugg = self.add_generic_param_suggestion(generics, span, &impl_trait_name);
723            diag.multipart_suggestion(
724                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("alternatively use a blanket implementation to implement `{0}` for all types that also implement `{1}`",
                of_trait_name, impl_trait_name))
    })format!(
725                    "alternatively use a blanket implementation to implement `{of_trait_name}` for \
726                     all types that also implement `{impl_trait_name}`"
727                ),
728                sugg,
729                Applicability::MaybeIncorrect,
730            );
731        }
732    }
733
734    /// Try our best to approximate when adding `dyn` would be helpful for a bare
735    /// trait object.
736    ///
737    /// Right now, this is if the type is either directly nested in another ty,
738    /// or if it's in the tail field within a struct. This approximates what the
739    /// user would've gotten on edition 2015, except for the case where we have
740    /// an *obvious* knock-on `Sized` error.
741    fn maybe_suggest_dyn_trait(
742        &self,
743        hir_id: hir::HirId,
744        span: Span,
745        sugg: Vec<(Span, String)>,
746        diag: &mut Diag<'_>,
747    ) -> bool {
748        let tcx = self.tcx();
749        if span.in_derive_expansion() {
750            return false;
751        }
752
753        // Look at the direct HIR parent, since we care about the relationship between
754        // the type and the thing that directly encloses it.
755        match tcx.parent_hir_node(hir_id) {
756            // These are all generally ok. Namely, when a trait object is nested
757            // into another expression or ty, it's either very certain that they
758            // missed the ty (e.g. `&Trait`) or it's not really possible to tell
759            // what their intention is, so let's not give confusing suggestions and
760            // just mention `dyn`. The user can make up their mind what to do here.
761            hir::Node::Ty(_)
762            | hir::Node::Expr(_)
763            | hir::Node::PatExpr(_)
764            | hir::Node::PathSegment(_)
765            | hir::Node::AssocItemConstraint(_)
766            | hir::Node::TraitRef(_)
767            | hir::Node::Item(_)
768            | hir::Node::WherePredicate(_) => {}
769
770            hir::Node::Field(field) => {
771                // Enums can't have unsized fields, fields can only have an unsized tail field.
772                if let hir::Node::Item(hir::Item {
773                    kind: hir::ItemKind::Struct(_, _, variant), ..
774                }) = tcx.parent_hir_node(field.hir_id)
775                    && variant
776                        .fields()
777                        .last()
778                        .is_some_and(|tail_field| tail_field.hir_id == field.hir_id)
779                {
780                    // Ok
781                } else {
782                    return false;
783                }
784            }
785            _ => return false,
786        }
787
788        // FIXME: Only emit this suggestion if the trait is dyn-compatible.
789        diag.multipart_suggestion(
790            "you can add the `dyn` keyword if you want a trait object",
791            sugg,
792            Applicability::MachineApplicable,
793        );
794        true
795    }
796
797    fn add_generic_param_suggestion(
798        &self,
799        generics: &hir::Generics<'_>,
800        self_ty_span: Span,
801        impl_trait_name: &str,
802    ) -> Vec<(Span, String)> {
803        // check if the trait has generics, to make a correct suggestion
804        let param_name = generics.params.next_type_param_name(None);
805
806        let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
807            (span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(", {0}: {1}", param_name,
                impl_trait_name))
    })format!(", {param_name}: {impl_trait_name}"))
808        } else {
809            (generics.span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0}: {1}>", param_name,
                impl_trait_name))
    })format!("<{param_name}: {impl_trait_name}>"))
810        };
811        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(self_ty_span, param_name), add_generic_sugg]))vec![(self_ty_span, param_name), add_generic_sugg]
812    }
813
814    /// Make sure that we are in the condition to suggest `impl Trait`.
815    fn maybe_suggest_impl_trait(
816        &self,
817        span: Span,
818        hir_id: hir::HirId,
819        hir_bounds: &[hir::PolyTraitRef<'tcx>],
820        diag: &mut Diag<'_>,
821    ) -> bool {
822        let tcx = self.tcx();
823        let parent_id = tcx.hir_get_parent_item(hir_id).def_id;
824        // FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0<Ty = Trait1>`
825        //        and suggest `Trait0<Ty = impl Trait1>`.
826        // Functions are found in three different contexts.
827        // 1. Independent functions
828        // 2. Functions inside trait blocks
829        // 3. Functions inside impl blocks
830        let (sig, generics) = match tcx.hir_node_by_def_id(parent_id) {
831            hir::Node::Item(hir::Item {
832                kind: hir::ItemKind::Fn { sig, generics, .. }, ..
833            }) => (sig, generics),
834            hir::Node::TraitItem(hir::TraitItem {
835                kind: hir::TraitItemKind::Fn(sig, _),
836                generics,
837                ..
838            }) => (sig, generics),
839            hir::Node::ImplItem(hir::ImplItem {
840                kind: hir::ImplItemKind::Fn(sig, _),
841                generics,
842                ..
843            }) => (sig, generics),
844            _ => return false,
845        };
846        let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(span) else {
847            return false;
848        };
849        let impl_sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(), "impl ".to_string())]))vec![(span.shrink_to_lo(), "impl ".to_string())];
850        // Check if trait object is safe for suggesting dynamic dispatch.
851        let is_dyn_compatible = hir_bounds.iter().all(|bound| match bound.trait_ref.path.res {
852            Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
853            _ => false,
854        });
855
856        let borrowed = #[allow(non_exhaustive_omitted_patterns)] match tcx.parent_hir_node(hir_id) {
    hir::Node::Ty(hir::Ty { kind: hir::TyKind::Ref(..), .. }) => true,
    _ => false,
}matches!(
857            tcx.parent_hir_node(hir_id),
858            hir::Node::Ty(hir::Ty { kind: hir::TyKind::Ref(..), .. })
859        );
860
861        // Suggestions for function return type.
862        if let hir::FnRetTy::Return(ty) = sig.decl.output
863            && ty.peel_refs().hir_id == hir_id
864        {
865            let pre = if !is_dyn_compatible {
866                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` is dyn-incompatible, ",
                trait_name))
    })format!("`{trait_name}` is dyn-incompatible, ")
867            } else {
868                String::new()
869            };
870            let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}use `impl {1}` to return an opaque type, as long as you return a single underlying type",
                pre, trait_name))
    })format!(
871                "{pre}use `impl {trait_name}` to return an opaque type, as long as you return a \
872                 single underlying type",
873            );
874
875            diag.multipart_suggestion(msg, impl_sugg, Applicability::MachineApplicable);
876
877            // Suggest `Box<dyn Trait>` for return type
878            if is_dyn_compatible {
879                // If the return type is `&Trait`, we don't want
880                // the ampersand to be displayed in the `Box<dyn Trait>`
881                // suggestion.
882                let suggestion = if borrowed {
883                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(ty.span,
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("Box<dyn {0}>",
                                    trait_name))
                        }))]))vec![(ty.span, format!("Box<dyn {trait_name}>"))]
884                } else {
885                    ::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<dyn ".to_string()),
                (ty.span.shrink_to_hi(), ">".to_string())]))vec![
886                        (ty.span.shrink_to_lo(), "Box<dyn ".to_string()),
887                        (ty.span.shrink_to_hi(), ">".to_string()),
888                    ]
889                };
890
891                diag.multipart_suggestion(
892                    "alternatively, you can return an owned trait object",
893                    suggestion,
894                    Applicability::MachineApplicable,
895                );
896            }
897            return true;
898        }
899
900        // Suggestions for function parameters.
901        for ty in sig.decl.inputs {
902            if ty.peel_refs().hir_id != hir_id {
903                continue;
904            }
905            let sugg = self.add_generic_param_suggestion(generics, span, &trait_name);
906            diag.multipart_suggestion(
907                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("use a new generic type parameter, constrained by `{0}`",
                trait_name))
    })format!("use a new generic type parameter, constrained by `{trait_name}`"),
908                sugg,
909                Applicability::MachineApplicable,
910            );
911            diag.multipart_suggestion(
912                "you can also use an opaque type, but users won't be able to specify the type \
913                 parameter when calling the `fn`, having to rely exclusively on type inference",
914                impl_sugg,
915                Applicability::MachineApplicable,
916            );
917            if !is_dyn_compatible {
918                diag.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` is dyn-incompatible, otherwise a trait object could be used",
                trait_name))
    })format!(
919                    "`{trait_name}` is dyn-incompatible, otherwise a trait object could be used"
920                ));
921            } else {
922                // No ampersand in suggestion if it's borrowed already
923                let (dyn_str, paren_dyn_str) =
924                    if borrowed { ("dyn ", "(dyn ") } else { ("&dyn ", "&(dyn ") };
925
926                let sugg = if let [_, _, ..] = hir_bounds {
927                    // There is more than one trait bound, we need surrounding parentheses.
928                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(), paren_dyn_str.to_string()),
                (span.shrink_to_hi(), ")".to_string())]))vec![
929                        (span.shrink_to_lo(), paren_dyn_str.to_string()),
930                        (span.shrink_to_hi(), ")".to_string()),
931                    ]
932                } else {
933                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(span.shrink_to_lo(), dyn_str.to_string())]))vec![(span.shrink_to_lo(), dyn_str.to_string())]
934                };
935                diag.multipart_suggestion(
936                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("alternatively, use a trait object to accept any type that implements `{0}`, accessing its methods at runtime using dynamic dispatch",
                trait_name))
    })format!(
937                        "alternatively, use a trait object to accept any type that implements \
938                         `{trait_name}`, accessing its methods at runtime using dynamic dispatch",
939                    ),
940                    sugg,
941                    Applicability::MachineApplicable,
942                );
943            }
944            return true;
945        }
946        false
947    }
948
949    fn maybe_suggest_assoc_ty_bound(&self, hir_id: hir::HirId, diag: &mut Diag<'_>) {
950        let mut parents = self.tcx().hir_parent_iter(hir_id);
951
952        if let Some((c_hir_id, hir::Node::AssocItemConstraint(constraint))) = parents.next()
953            && let Some(obj_ty) = constraint.ty()
954            && let Some((_, hir::Node::TraitRef(trait_ref))) = parents.next()
955        {
956            if let Some((_, hir::Node::Ty(ty))) = parents.next()
957                && let hir::TyKind::TraitObject(..) = ty.kind
958            {
959                // Assoc ty bounds aren't permitted inside trait object types.
960                return;
961            }
962
963            if trait_ref
964                .path
965                .segments
966                .iter()
967                .find_map(|seg| {
968                    seg.args.filter(|args| args.constraints.iter().any(|c| c.hir_id == c_hir_id))
969                })
970                .is_none_or(|args| args.parenthesized != hir::GenericArgsParentheses::No)
971            {
972                // Only consider angle-bracketed args (where we have a `=` to replace with `:`).
973                return;
974            }
975
976            let lo = if constraint.gen_args.span_ext.is_dummy() {
977                constraint.ident.span
978            } else {
979                constraint.gen_args.span_ext
980            };
981            let hi = obj_ty.span;
982
983            if !lo.eq_ctxt(hi) {
984                return;
985            }
986
987            diag.span_suggestion_verbose(
988                lo.between(hi),
989                "you might have meant to write a bound here",
990                ": ",
991                Applicability::MaybeIncorrect,
992            );
993        }
994    }
995
996    fn maybe_suggest_typoed_method(
997        &self,
998        hir_id: hir::HirId,
999        trait_def_id: Option<DefId>,
1000        diag: &mut Diag<'_>,
1001    ) {
1002        let tcx = self.tcx();
1003        let Some(trait_def_id) = trait_def_id else {
1004            return;
1005        };
1006        let hir::Node::Expr(hir::Expr {
1007            kind: hir::ExprKind::Path(hir::QPath::TypeRelative(path_ty, segment)),
1008            ..
1009        }) = tcx.parent_hir_node(hir_id)
1010        else {
1011            return;
1012        };
1013        if path_ty.hir_id != hir_id {
1014            return;
1015        }
1016        let names: Vec<_> = tcx
1017            .associated_items(trait_def_id)
1018            .in_definition_order()
1019            .filter(|assoc| assoc.namespace() == hir::def::Namespace::ValueNS)
1020            .map(|cand| cand.name())
1021            .collect();
1022        if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) {
1023            diag.span_suggestion_verbose(
1024                segment.ident.span,
1025                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("you may have misspelled this associated item, causing `{0}` to be interpreted as a type rather than a trait",
                tcx.item_name(trait_def_id)))
    })format!(
1026                    "you may have misspelled this associated item, causing `{}` \
1027                    to be interpreted as a type rather than a trait",
1028                    tcx.item_name(trait_def_id),
1029                ),
1030                typo,
1031                Applicability::MaybeIncorrect,
1032            );
1033        }
1034    }
1035}
1036
1037fn replace_dummy_self_with_error<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
1038    tcx: TyCtxt<'tcx>,
1039    t: T,
1040    guar: ErrorGuaranteed,
1041) -> T {
1042    t.fold_with(&mut BottomUpFolder {
1043        tcx,
1044        ty_op: |ty| {
1045            if ty == tcx.types.trait_object_dummy_self { Ty::new_error(tcx, guar) } else { ty }
1046        },
1047        lt_op: |lt| lt,
1048        ct_op: |ct| ct,
1049    })
1050}