Skip to main content

rustc_hir_analysis/diagnostics/
wrong_number_of_generic_args.rs

1use GenericArgsInfo::*;
2use rustc_errors::codes::*;
3use rustc_errors::{Applicability, Diag, Diagnostic, MultiSpan, pluralize};
4use rustc_hir as hir;
5use rustc_middle::ty::{self as ty, AssocItem, AssocItems, TyCtxt};
6use rustc_span::def_id::{DefId, LocalDefId};
7use tracing::debug;
8
9/// Handles the `wrong number of type / lifetime / ... arguments` family of error messages.
10pub(crate) struct WrongNumberOfGenericArgs<'a, 'tcx> {
11    pub(crate) tcx: TyCtxt<'tcx>,
12
13    pub(crate) angle_brackets: AngleBrackets,
14
15    pub(crate) gen_args_info: GenericArgsInfo,
16
17    /// Offending path segment
18    pub(crate) path_segment: &'a hir::PathSegment<'a>,
19
20    /// Generic parameters as expected by type or trait
21    pub(crate) gen_params: &'a ty::Generics,
22
23    /// Index offset into parameters. Depends on whether `Self` is included and on
24    /// number of lifetime parameters in case we're processing missing or redundant
25    /// type or constant arguments.
26    pub(crate) params_offset: usize,
27
28    /// Generic arguments as provided by user
29    pub(crate) gen_args: &'a hir::GenericArgs<'a>,
30
31    /// DefId of the generic type
32    pub(crate) def_id: DefId,
33
34    /// DefId of the type that contains the generic
35    pub(crate) cx_def_id: LocalDefId,
36}
37
38// Provides information about the kind of arguments that were provided for
39// the PathSegment, for which missing generic arguments were detected
40#[derive(#[automatically_derived]
impl ::core::fmt::Debug for AngleBrackets {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AngleBrackets::Implied => "Implied",
                AngleBrackets::Missing => "Missing",
                AngleBrackets::Available => "Available",
            })
    }
}Debug)]
41pub(crate) enum AngleBrackets {
42    // No angle brackets were provided, but generic arguments exist in elided form
43    Implied,
44
45    // No angle brackets were provided
46    Missing,
47
48    // Angle brackets are available, but missing some generic arguments
49    Available,
50}
51
52// Information about the kind of arguments that are either missing or are unexpected
53#[derive(#[automatically_derived]
impl ::core::fmt::Debug for GenericArgsInfo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::MissingLifetimes { num_missing_args: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "MissingLifetimes", "num_missing_args", &__self_0),
            Self::ExcessLifetimes { num_redundant_args: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "ExcessLifetimes", "num_redundant_args", &__self_0),
            Self::MissingTypesOrConsts {
                num_missing_args: __self_0,
                num_default_params: __self_1,
                args_offset: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "MissingTypesOrConsts", "num_missing_args", __self_0,
                    "num_default_params", __self_1, "args_offset", &__self_2),
            Self::ExcessTypesOrConsts {
                num_redundant_args: __self_0,
                num_default_params: __self_1,
                args_offset: __self_2,
                synth_provided: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "ExcessTypesOrConsts", "num_redundant_args", __self_0,
                    "num_default_params", __self_1, "args_offset", __self_2,
                    "synth_provided", &__self_3),
        }
    }
}Debug)]
54pub(crate) enum GenericArgsInfo {
55    MissingLifetimes {
56        num_missing_args: usize,
57    },
58    ExcessLifetimes {
59        num_redundant_args: usize,
60    },
61    MissingTypesOrConsts {
62        num_missing_args: usize,
63
64        // type or const generic arguments can have default values
65        num_default_params: usize,
66
67        // lifetime arguments precede type and const parameters, this
68        // field gives the number of generic lifetime arguments to let
69        // us infer the position of type and const generic arguments
70        // in the angle brackets
71        args_offset: usize,
72    },
73
74    ExcessTypesOrConsts {
75        num_redundant_args: usize,
76
77        // type or const generic arguments can have default values
78        num_default_params: usize,
79
80        // lifetime arguments precede type and const parameters, this
81        // field gives the number of generic lifetime arguments to let
82        // us infer the position of type and const generic arguments
83        // in the angle brackets
84        args_offset: usize,
85
86        // if synthetic type arguments (e.g. `impl Trait`) are specified
87        synth_provided: bool,
88    },
89}
90
91impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
92    pub(crate) fn new(
93        tcx: TyCtxt<'tcx>,
94        gen_args_info: GenericArgsInfo,
95        path_segment: &'a hir::PathSegment<'_>,
96        gen_params: &'a ty::Generics,
97        params_offset: usize,
98        gen_args: &'a hir::GenericArgs<'a>,
99        def_id: DefId,
100        cx_def_id: LocalDefId,
101    ) -> Self {
102        let angle_brackets = if gen_args.span_ext().is_none() {
103            if gen_args.is_empty() { AngleBrackets::Missing } else { AngleBrackets::Implied }
104        } else {
105            AngleBrackets::Available
106        };
107
108        Self {
109            tcx,
110            angle_brackets,
111            gen_args_info,
112            path_segment,
113            gen_params,
114            params_offset,
115            gen_args,
116            def_id,
117            cx_def_id,
118        }
119    }
120
121    fn missing_lifetimes(&self) -> bool {
122        match self.gen_args_info {
123            MissingLifetimes { .. } | ExcessLifetimes { .. } => true,
124            MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => false,
125        }
126    }
127
128    fn kind(&self) -> &str {
129        if self.missing_lifetimes() { "lifetime" } else { "generic" }
130    }
131
132    /// Returns true if the generic type is a trait
133    /// and is being referred to from one of its trait impls
134    fn is_in_trait_impl(&self) -> bool {
135        if self.tcx.is_trait(self.def_id) {
136            // Here we check if the reference to the generic type
137            // is from the 'of_trait' field of the enclosing impl
138
139            let parent = self.tcx.parent_hir_node(self.path_segment.hir_id);
140            let parent_item = self
141                .tcx
142                .hir_node_by_def_id(self.tcx.hir_get_parent_item(self.path_segment.hir_id).def_id);
143
144            // Get the HIR id of the trait ref
145            let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else {
146                return false;
147            };
148
149            // Get the HIR id of the 'of_trait' field of the impl
150            let hir::Node::Item(hir::Item {
151                kind:
152                    hir::ItemKind::Impl(hir::Impl {
153                        of_trait:
154                            Some(hir::TraitImplHeader {
155                                trait_ref: hir::TraitRef { hir_ref_id: id_in_of_trait, .. },
156                                ..
157                            }),
158                        ..
159                    }),
160                ..
161            }) = parent_item
162            else {
163                return false;
164            };
165
166            // Check that trait is referred to from the of_trait field of impl
167            trait_ref_id == id_in_of_trait
168        } else {
169            false
170        }
171    }
172
173    fn num_provided_args(&self) -> usize {
174        if self.missing_lifetimes() {
175            self.num_provided_lifetime_args()
176        } else {
177            self.num_provided_type_or_const_args()
178        }
179    }
180
181    fn num_provided_lifetime_args(&self) -> usize {
182        match self.angle_brackets {
183            AngleBrackets::Missing => 0,
184            // Only lifetime arguments can be implied
185            AngleBrackets::Implied => self.gen_args.args.len(),
186            AngleBrackets::Available => self.gen_args.num_lifetime_args(),
187        }
188    }
189
190    fn num_provided_type_or_const_args(&self) -> usize {
191        match self.angle_brackets {
192            AngleBrackets::Missing => 0,
193            // Only lifetime arguments can be implied
194            AngleBrackets::Implied => 0,
195            AngleBrackets::Available => self.gen_args.num_generic_params(),
196        }
197    }
198
199    fn num_expected_lifetime_args(&self) -> usize {
200        let num_provided_args = self.num_provided_lifetime_args();
201        match self.gen_args_info {
202            MissingLifetimes { num_missing_args } => num_provided_args + num_missing_args,
203            ExcessLifetimes { num_redundant_args } => num_provided_args - num_redundant_args,
204            _ => 0,
205        }
206    }
207
208    fn num_expected_type_or_const_args(&self) -> usize {
209        let num_provided_args = self.num_provided_type_or_const_args();
210        match self.gen_args_info {
211            MissingTypesOrConsts { num_missing_args, .. } => num_provided_args + num_missing_args,
212            ExcessTypesOrConsts { num_redundant_args, .. } => {
213                num_provided_args - num_redundant_args
214            }
215            _ => 0,
216        }
217    }
218
219    // Gives the number of expected arguments taking into account default arguments
220    fn num_expected_type_or_const_args_including_defaults(&self) -> usize {
221        let provided_args = self.num_provided_type_or_const_args();
222        match self.gen_args_info {
223            MissingTypesOrConsts { num_missing_args, num_default_params, .. } => {
224                provided_args + num_missing_args - num_default_params
225            }
226            ExcessTypesOrConsts { num_redundant_args, num_default_params, .. } => {
227                provided_args - num_redundant_args - num_default_params
228            }
229            _ => 0,
230        }
231    }
232
233    fn num_missing_lifetime_args(&self) -> usize {
234        let missing_args = self.num_expected_lifetime_args() - self.num_provided_lifetime_args();
235        if !(missing_args > 0) {
    ::core::panicking::panic("assertion failed: missing_args > 0")
};assert!(missing_args > 0);
236        missing_args
237    }
238
239    fn num_missing_type_or_const_args(&self) -> usize {
240        let missing_args = self.num_expected_type_or_const_args_including_defaults()
241            - self.num_provided_type_or_const_args();
242        if !(missing_args > 0) {
    ::core::panicking::panic("assertion failed: missing_args > 0")
};assert!(missing_args > 0);
243        missing_args
244    }
245
246    fn num_excess_lifetime_args(&self) -> usize {
247        match self.gen_args_info {
248            ExcessLifetimes { num_redundant_args } => num_redundant_args,
249            _ => 0,
250        }
251    }
252
253    fn num_excess_type_or_const_args(&self) -> usize {
254        match self.gen_args_info {
255            ExcessTypesOrConsts { num_redundant_args, .. } => num_redundant_args,
256            _ => 0,
257        }
258    }
259
260    fn too_many_args_provided(&self) -> bool {
261        match self.gen_args_info {
262            MissingLifetimes { .. } | MissingTypesOrConsts { .. } => false,
263            ExcessLifetimes { num_redundant_args }
264            | ExcessTypesOrConsts { num_redundant_args, .. } => {
265                if !(num_redundant_args > 0) {
    ::core::panicking::panic("assertion failed: num_redundant_args > 0")
};assert!(num_redundant_args > 0);
266                true
267            }
268        }
269    }
270
271    fn not_enough_args_provided(&self) -> bool {
272        match self.gen_args_info {
273            MissingLifetimes { num_missing_args }
274            | MissingTypesOrConsts { num_missing_args, .. } => {
275                if !(num_missing_args > 0) {
    ::core::panicking::panic("assertion failed: num_missing_args > 0")
};assert!(num_missing_args > 0);
276                true
277            }
278            ExcessLifetimes { .. } | ExcessTypesOrConsts { .. } => false,
279        }
280    }
281
282    // Helper method to get the index offset in angle brackets, at which type or const arguments
283    // start appearing
284    fn get_lifetime_args_offset(&self) -> usize {
285        match self.gen_args_info {
286            MissingLifetimes { .. } | ExcessLifetimes { .. } => 0,
287            MissingTypesOrConsts { args_offset, .. } | ExcessTypesOrConsts { args_offset, .. } => {
288                args_offset
289            }
290        }
291    }
292
293    fn get_num_default_params(&self) -> usize {
294        match self.gen_args_info {
295            MissingTypesOrConsts { num_default_params, .. }
296            | ExcessTypesOrConsts { num_default_params, .. } => num_default_params,
297            _ => 0,
298        }
299    }
300
301    fn is_synth_provided(&self) -> bool {
302        match self.gen_args_info {
303            ExcessTypesOrConsts { synth_provided, .. } => synth_provided,
304            _ => false,
305        }
306    }
307
308    // Helper function to choose a quantifier word for the number of expected arguments
309    // and to give a bound for the number of expected arguments
310    fn get_quantifier_and_bound(&self) -> (&'static str, usize) {
311        if self.get_num_default_params() == 0 {
312            match self.gen_args_info {
313                MissingLifetimes { .. } | ExcessLifetimes { .. } => {
314                    ("", self.num_expected_lifetime_args())
315                }
316                MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => {
317                    ("", self.num_expected_type_or_const_args())
318                }
319            }
320        } else {
321            match self.gen_args_info {
322                MissingLifetimes { .. } => ("at least ", self.num_expected_lifetime_args()),
323                MissingTypesOrConsts { .. } => {
324                    ("at least ", self.num_expected_type_or_const_args_including_defaults())
325                }
326                ExcessLifetimes { .. } => ("at most ", self.num_expected_lifetime_args()),
327                ExcessTypesOrConsts { .. } => ("at most ", self.num_expected_type_or_const_args()),
328            }
329        }
330    }
331
332    // Creates lifetime name suggestions from the lifetime parameter names
333    fn get_lifetime_args_suggestions_from_param_names(
334        &self,
335        path_hir_id: hir::HirId,
336        num_params_to_take: usize,
337    ) -> String {
338        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:338",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(338u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("path_hir_id")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("path_hir_id");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&path_hir_id)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?path_hir_id);
339
340        // If there was already a lifetime among the arguments, just replicate that one.
341        if let Some(lt) = self.gen_args.args.iter().find_map(|arg| match arg {
342            hir::GenericArg::Lifetime(lt) => Some(lt),
343            _ => None,
344        }) {
345            return std::iter::repeat_n(lt.to_string(), num_params_to_take)
346                .collect::<Vec<_>>()
347                .join(", ");
348        }
349
350        let mut ret = Vec::new();
351        let mut ty_id = None;
352        for (id, node) in self.tcx.hir_parent_iter(path_hir_id) {
353            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:353",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(353u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("id")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("id");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&id)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?id);
354            if let hir::Node::Ty(_) = node {
355                ty_id = Some(id);
356            }
357
358            // Suggest `'_` when in function parameter or elided function return.
359            if let Some(fn_decl) = node.fn_decl()
360                && let Some(ty_id) = ty_id
361            {
362                let in_arg = fn_decl.inputs.iter().any(|t| t.hir_id == ty_id);
363                let in_ret =
364                    #[allow(non_exhaustive_omitted_patterns)] match fn_decl.output {
    hir::FnRetTy::Return(ty) if ty.hir_id == ty_id => true,
    _ => false,
}matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id);
365
366                if in_arg || (in_ret && fn_decl.lifetime_elision_allowed()) {
367                    return std::iter::repeat_n("'_".to_owned(), num_params_to_take)
368                        .collect::<Vec<_>>()
369                        .join(", ");
370                }
371            }
372
373            // Suggest `'static` when in const/static item-like.
374            if let hir::Node::Item(hir::Item {
375                kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
376                ..
377            })
378            | hir::Node::TraitItem(hir::TraitItem {
379                kind: hir::TraitItemKind::Const { .. },
380                ..
381            })
382            | hir::Node::ImplItem(hir::ImplItem {
383                kind: hir::ImplItemKind::Const { .. },
384                ..
385            })
386            | hir::Node::ForeignItem(hir::ForeignItem {
387                kind: hir::ForeignItemKind::Static { .. },
388                ..
389            })
390            | hir::Node::AnonConst(..) = node
391            {
392                return std::iter::repeat_n(
393                    "'static".to_owned(),
394                    num_params_to_take.saturating_sub(ret.len()),
395                )
396                .collect::<Vec<_>>()
397                .join(", ");
398            }
399
400            let params = if let Some(generics) = node.generics() {
401                generics.params
402            } else if let hir::Node::Ty(ty) = node
403                && let hir::TyKind::FnPtr(fn_ptr) = ty.kind
404            {
405                fn_ptr.generic_params
406            } else {
407                &[]
408            };
409            ret.extend(params.iter().filter_map(|p| {
410                let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } =
411                    p.kind
412                else {
413                    return None;
414                };
415                let hir::ParamName::Plain(name) = p.name else { return None };
416                Some(name.to_string())
417            }));
418
419            if ret.len() >= num_params_to_take {
420                return ret[..num_params_to_take].join(", ");
421            }
422            // We cannot refer to lifetimes defined in an outer function.
423            if let hir::Node::Item(_) = node {
424                break;
425            }
426        }
427
428        // We could not gather enough lifetime parameters in the scope.
429        // We use the parameter names from the target type's definition instead.
430        self.gen_params
431            .own_params
432            .iter()
433            .skip(self.params_offset + self.num_provided_lifetime_args())
434            .take(num_params_to_take)
435            .map(|param| param.name.to_string())
436            .collect::<Vec<_>>()
437            .join(", ")
438    }
439
440    // Creates type or constant name suggestions from the provided parameter names
441    fn get_type_or_const_args_suggestions_from_param_names(
442        &self,
443        num_params_to_take: usize,
444    ) -> String {
445        let is_in_a_method_call = self
446            .tcx
447            .hir_parent_iter(self.path_segment.hir_id)
448            .skip(1)
449            .find_map(|(_, node)| match node {
450                hir::Node::Expr(expr) => Some(expr),
451                _ => None,
452            })
453            .is_some_and(|expr| {
454                #[allow(non_exhaustive_omitted_patterns)] match expr.kind {
    hir::ExprKind::MethodCall(hir::PathSegment { args: Some(_), .. }, ..) =>
        true,
    _ => false,
}matches!(
455                    expr.kind,
456                    hir::ExprKind::MethodCall(hir::PathSegment { args: Some(_), .. }, ..)
457                )
458            });
459
460        let fn_sig = self.tcx.hir_get_if_local(self.def_id).and_then(hir::Node::fn_sig);
461        let is_used_in_input = |def_id| {
462            fn_sig.is_some_and(|fn_sig| {
463                fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
464                    hir::TyKind::Path(hir::QPath::Resolved(
465                        None,
466                        hir::Path { res: hir::def::Res::Def(_, id), .. },
467                    )) => *id == def_id,
468                    _ => false,
469                })
470            })
471        };
472        self.gen_params
473            .own_params
474            .iter()
475            .skip(self.params_offset + self.num_provided_type_or_const_args())
476            .take(num_params_to_take)
477            .map(|param| match param.kind {
478                // If it's in method call (turbofish), it might be inferred from the expression (e.g. `.collect::<Vec<_>>()`)
479                // If it is being inferred from the item's inputs, no need to set it.
480                ty::GenericParamDefKind::Type { .. }
481                    if is_in_a_method_call || is_used_in_input(param.def_id) =>
482                {
483                    "_"
484                }
485                _ => param.name.as_str(),
486            })
487            .intersperse(", ")
488            .collect()
489    }
490
491    fn get_unbound_associated_item(&self) -> Vec<&AssocItem> {
492        if self.tcx.is_trait(self.def_id) {
493            let items: &AssocItems = self.tcx.associated_items(self.def_id);
494            items
495                .in_definition_order()
496                .filter(|item| {
497                    item.can_have_equality_constraint(self.tcx)
498                        && !item.is_impl_trait_in_trait()
499                        && !self
500                            .gen_args
501                            .constraints
502                            .iter()
503                            .any(|constraint| constraint.ident.name == item.name())
504                })
505                .collect()
506        } else {
507            Vec::default()
508        }
509    }
510
511    fn create_error_message(&self) -> String {
512        let def_path = self.tcx.def_path_str(self.def_id);
513        let def_kind = self.tcx.def_descr(self.def_id);
514        let (quantifier, bound) = self.get_quantifier_and_bound();
515        let kind = self.kind();
516        let provided_lt_args = self.num_provided_lifetime_args();
517        let provided_type_or_const_args = self.num_provided_type_or_const_args();
518
519        let (provided_args_str, verb) = match self.gen_args_info {
520            MissingLifetimes { .. } | ExcessLifetimes { .. } => (
521                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} lifetime argument{1}",
                provided_lt_args,
                if provided_lt_args == 1 { "" } else { "s" }))
    })format!("{} lifetime argument{}", provided_lt_args, pluralize!(provided_lt_args)),
522                if provided_lt_args == 1 { "was" } else { "were" }pluralize!("was", provided_lt_args),
523            ),
524            MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => (
525                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} generic argument{1}",
                provided_type_or_const_args,
                if provided_type_or_const_args == 1 { "" } else { "s" }))
    })format!(
526                    "{} generic argument{}",
527                    provided_type_or_const_args,
528                    pluralize!(provided_type_or_const_args)
529                ),
530                if provided_type_or_const_args == 1 { "was" } else { "were" }pluralize!("was", provided_type_or_const_args),
531            ),
532        };
533
534        if self.gen_args.span_ext().is_some() {
535            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} takes {1}{2} {3} argument{4} but {5} {6} supplied",
                def_kind, quantifier, bound, kind,
                if bound == 1 { "" } else { "s" }, provided_args_str.as_str(),
                verb))
    })format!(
536                "{} takes {}{} {} argument{} but {} {} supplied",
537                def_kind,
538                quantifier,
539                bound,
540                kind,
541                pluralize!(bound),
542                provided_args_str.as_str(),
543                verb
544            )
545        } else {
546            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("missing generics for {0} `{1}`",
                def_kind, def_path))
    })format!("missing generics for {def_kind} `{def_path}`")
547        }
548    }
549
550    /// Builds the `expected 1 type argument / supplied 2 type arguments` message.
551    fn notify(&self, err: &mut Diag<'_>) {
552        let (quantifier, bound) = self.get_quantifier_and_bound();
553        let provided_args = self.num_provided_args();
554
555        err.span_label(
556            self.path_segment.ident.span,
557            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected {0}{1} {2} argument{3}",
                quantifier, bound, self.kind(),
                if bound == 1 { "" } else { "s" }))
    })format!(
558                "expected {}{} {} argument{}",
559                quantifier,
560                bound,
561                self.kind(),
562                pluralize!(bound),
563            ),
564        );
565
566        // When too many arguments were provided, we don't highlight each of them, because it
567        // would overlap with the suggestion to remove them:
568        //
569        // ```
570        // type Foo = Bar<usize, usize>;
571        //                -----  ----- supplied 2 type arguments
572        //                     ^^^^^^^ remove this type argument
573        // ```
574        if self.too_many_args_provided() {
575            return;
576        }
577
578        let args = self
579            .gen_args
580            .args
581            .iter()
582            .skip(self.get_lifetime_args_offset())
583            .take(provided_args)
584            .enumerate();
585
586        for (i, arg) in args {
587            err.span_label(
588                arg.span(),
589                if i + 1 == provided_args {
590                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("supplied {0} {1} argument{2}",
                provided_args, self.kind(),
                if provided_args == 1 { "" } else { "s" }))
    })format!(
591                        "supplied {} {} argument{}",
592                        provided_args,
593                        self.kind(),
594                        pluralize!(provided_args)
595                    )
596                } else {
597                    String::new()
598                },
599            );
600        }
601    }
602
603    fn suggest(&self, err: &mut Diag<'_>) {
604        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:604",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(604u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("suggest(self.provided {0:?}, self.gen_args.span(): {1:?})",
                                                    self.num_provided_args(), self.gen_args.span()) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
605            "suggest(self.provided {:?}, self.gen_args.span(): {:?})",
606            self.num_provided_args(),
607            self.gen_args.span(),
608        );
609
610        match self.angle_brackets {
611            AngleBrackets::Missing | AngleBrackets::Implied => self.suggest_adding_args(err),
612            AngleBrackets::Available => {
613                if self.not_enough_args_provided() {
614                    self.suggest_adding_args(err);
615                } else if self.too_many_args_provided() {
616                    self.suggest_moving_args_from_assoc_fn_to_trait(err);
617                    self.suggest_removing_args_or_generics(err);
618                } else {
619                    ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
620                }
621            }
622        }
623    }
624
625    /// Suggests to add missing argument(s) when current invocation site already contains some
626    /// generics:
627    ///
628    /// ```text
629    /// type Map = HashMap<String>;
630    /// ```
631    fn suggest_adding_args(&self, err: &mut Diag<'_>) {
632        if self.gen_args.parenthesized != hir::GenericArgsParentheses::No {
633            return;
634        }
635
636        // Do not suggest angle-bracketed arguments that require the unstable feature.
637        if !self.tcx.features().unboxed_closures()
638            && self.tcx.is_trait(self.def_id)
639            && self.tcx.trait_def(self.def_id).paren_sugar
640        {
641            return;
642        }
643
644        match self.gen_args_info {
645            MissingLifetimes { .. } => {
646                self.suggest_adding_lifetime_args(err);
647            }
648            MissingTypesOrConsts { .. } => {
649                self.suggest_adding_type_and_const_args(err);
650            }
651            ExcessTypesOrConsts { .. } => {
652                // this can happen with `[const] T` where T isn't a `const trait`.
653            }
654            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
655        }
656    }
657
658    fn suggest_adding_lifetime_args(&self, err: &mut Diag<'_>) {
659        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:659",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(659u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("suggest_adding_lifetime_args(path_segment: {0:?})",
                                                    self.path_segment) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment);
660        let num_missing_args = self.num_missing_lifetime_args();
661        let num_params_to_take = num_missing_args;
662        let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("add missing {0} argument{1}",
                self.kind(), if num_missing_args == 1 { "" } else { "s" }))
    })format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
663
664        let suggested_args = self.get_lifetime_args_suggestions_from_param_names(
665            self.path_segment.hir_id,
666            num_params_to_take,
667        );
668        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:668",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(668u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("suggested_args: {0:?}",
                                                    suggested_args) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("suggested_args: {suggested_args:?}");
669
670        match self.angle_brackets {
671            AngleBrackets::Missing => {
672                let span = self.path_segment.ident.span;
673
674                // insert a suggestion of the form "Y<'a, 'b>"
675                let sugg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0}>", suggested_args))
    })format!("<{suggested_args}>");
676                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:676",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(676u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
677
678                err.span_suggestion_verbose(
679                    span.shrink_to_hi(),
680                    msg,
681                    sugg,
682                    Applicability::HasPlaceholders,
683                );
684            }
685
686            AngleBrackets::Available => {
687                let (sugg_span, is_first) = if self.num_provided_lifetime_args() == 0 {
688                    (self.gen_args.span().unwrap().shrink_to_lo(), true)
689                } else {
690                    let last_lt = &self.gen_args.args[self.num_provided_lifetime_args() - 1];
691                    (last_lt.span().shrink_to_hi(), false)
692                };
693                let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
694                let has_constraints = !self.gen_args.constraints.is_empty();
695
696                let sugg_prefix = if is_first { "" } else { ", " };
697                let sugg_suffix =
698                    if is_first && (has_non_lt_args || has_constraints) { ", " } else { "" };
699
700                let sugg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}{2}", sugg_prefix,
                suggested_args, sugg_suffix))
    })format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
701                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:701",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(701u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
702
703                err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
704            }
705            AngleBrackets::Implied => {
706                // We never encounter missing lifetimes in situations in which lifetimes are elided
707                ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
708            }
709        }
710    }
711
712    fn suggest_adding_type_and_const_args(&self, err: &mut Diag<'_>) {
713        let num_missing_args = self.num_missing_type_or_const_args();
714        let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("add missing {0} argument{1}",
                self.kind(), if num_missing_args == 1 { "" } else { "s" }))
    })format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
715
716        let suggested_args =
717            self.get_type_or_const_args_suggestions_from_param_names(num_missing_args);
718        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:718",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(718u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("suggested_args: {0:?}",
                                                    suggested_args) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("suggested_args: {:?}", suggested_args);
719
720        match self.angle_brackets {
721            AngleBrackets::Missing | AngleBrackets::Implied => {
722                let span = self.path_segment.ident.span;
723
724                // insert a suggestion of the form "Y<T, U>"
725                let sugg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0}>", suggested_args))
    })format!("<{suggested_args}>");
726                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:726",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(726u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
727
728                err.span_suggestion_verbose(
729                    span.shrink_to_hi(),
730                    msg,
731                    sugg,
732                    Applicability::HasPlaceholders,
733                );
734            }
735            AngleBrackets::Available => {
736                let gen_args_span = self.gen_args.span().unwrap();
737                let sugg_offset =
738                    self.get_lifetime_args_offset() + self.num_provided_type_or_const_args();
739
740                let (sugg_span, is_first) = if sugg_offset == 0 {
741                    (gen_args_span.shrink_to_lo(), true)
742                } else {
743                    let arg_span = self.gen_args.args[sugg_offset - 1].span();
744                    // If we came here then inferred lifetime's spans can only point
745                    // to either the opening bracket or to the space right after.
746                    // Both of these spans have an `hi` lower than or equal to the span
747                    // of the generics excluding the brackets.
748                    // This allows us to check if `arg_span` is the artificial span of
749                    // an inferred lifetime, in which case the generic we're suggesting to
750                    // add will be the first visible, even if it isn't the actual first generic.
751                    (arg_span.shrink_to_hi(), arg_span.hi() <= gen_args_span.lo())
752                };
753
754                let sugg_prefix = if is_first { "" } else { ", " };
755                let sugg_suffix =
756                    if is_first && !self.gen_args.constraints.is_empty() { ", " } else { "" };
757
758                let sugg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}{2}", sugg_prefix,
                suggested_args, sugg_suffix))
    })format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
759                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:759",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(759u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
760
761                err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
762            }
763        }
764    }
765
766    /// Suggests moving redundant argument(s) of an associate function to the
767    /// trait it belongs to.
768    ///
769    /// ```compile_fail
770    /// Into::into::<Option<_>>(42) // suggests considering `Into::<Option<_>>::into(42)`
771    /// ```
772    fn suggest_moving_args_from_assoc_fn_to_trait(&self, err: &mut Diag<'_>) {
773        let Some(trait_) = self.tcx.trait_of_assoc(self.def_id) else {
774            return;
775        };
776
777        // Skip suggestion when the associated function is itself generic, it is unclear
778        // how to split the provided parameters between those to suggest to the trait and
779        // those to remain on the associated type.
780        let num_assoc_fn_expected_args =
781            self.num_expected_type_or_const_args() + self.num_expected_lifetime_args();
782        if num_assoc_fn_expected_args > 0 {
783            return;
784        }
785
786        let num_assoc_fn_excess_args =
787            self.num_excess_type_or_const_args() + self.num_excess_lifetime_args();
788
789        let trait_generics = self.tcx.generics_of(trait_);
790        let num_trait_generics_except_self =
791            trait_generics.count() - if trait_generics.has_self { 1 } else { 0 };
792
793        let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider moving {0} generic argument{1} to the `{2}` trait, which takes up to {3} argument{1}",
                if num_assoc_fn_excess_args == 1 { "this" } else { "these" },
                if num_assoc_fn_excess_args == 1 { "" } else { "s" },
                self.tcx.item_name(trait_), num_trait_generics_except_self))
    })format!(
794            "consider moving {these} generic argument{s} to the `{name}` trait, which takes up to {num} argument{s}",
795            these = pluralize!("this", num_assoc_fn_excess_args),
796            s = pluralize!(num_assoc_fn_excess_args),
797            name = self.tcx.item_name(trait_),
798            num = num_trait_generics_except_self,
799        );
800
801        if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(self.path_segment.hir_id) {
802            match &expr.kind {
803                hir::ExprKind::Path(qpath) => self
804                    .suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
805                        err,
806                        qpath,
807                        msg,
808                        num_assoc_fn_excess_args,
809                        num_trait_generics_except_self,
810                    ),
811                hir::ExprKind::MethodCall(..) => self
812                    .suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
813                        err,
814                        trait_,
815                        expr,
816                        msg,
817                        num_assoc_fn_excess_args,
818                        num_trait_generics_except_self,
819                    ),
820                _ => return,
821            }
822        }
823    }
824
825    fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
826        &self,
827        err: &mut Diag<'_>,
828        qpath: &'tcx hir::QPath<'tcx>,
829        msg: String,
830        num_assoc_fn_excess_args: usize,
831        num_trait_generics_except_self: usize,
832    ) {
833        if let hir::QPath::Resolved(_, path) = qpath
834            && let Some(trait_path_segment) = path.segments.get(0)
835        {
836            let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
837
838            if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args
839                == num_trait_generics_except_self
840                && let Some(span) = self.gen_args.span_ext()
841                && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
842            {
843                let sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(self.path_segment.ident.span,
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("{0}::{1}", snippet,
                                    self.path_segment.ident))
                        })),
                (span.with_lo(self.path_segment.ident.span.hi()),
                    "".to_owned())]))vec![
844                    (
845                        self.path_segment.ident.span,
846                        format!("{}::{}", snippet, self.path_segment.ident),
847                    ),
848                    (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()),
849                ];
850
851                err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
852            }
853        }
854    }
855
856    fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
857        &self,
858        err: &mut Diag<'_>,
859        trait_def_id: DefId,
860        expr: &'tcx hir::Expr<'tcx>,
861        msg: String,
862        num_assoc_fn_excess_args: usize,
863        num_trait_generics_except_self: usize,
864    ) {
865        let sm = self.tcx.sess.source_map();
866        let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else {
867            return;
868        };
869        if num_assoc_fn_excess_args != num_trait_generics_except_self {
870            return;
871        }
872        let Some(gen_args) = self.gen_args.span_ext() else {
873            return;
874        };
875        let Ok(generics) = sm.span_to_snippet(gen_args) else {
876            return;
877        };
878        let Ok(rcvr) =
879            sm.span_to_snippet(rcvr.span.find_ancestor_inside(expr.span).unwrap_or(rcvr.span))
880        else {
881            return;
882        };
883        let Ok(rest) = (match args {
884            [] => Ok(String::new()),
885            [arg] => {
886                sm.span_to_snippet(arg.span.find_ancestor_inside(expr.span).unwrap_or(arg.span))
887            }
888            [first, .., last] => {
889                let first_span = first.span.find_ancestor_inside(expr.span).unwrap_or(first.span);
890                let last_span = last.span.find_ancestor_inside(expr.span).unwrap_or(last.span);
891                sm.span_to_snippet(first_span.to(last_span))
892            }
893        }) else {
894            return;
895        };
896        let comma = if args.len() > 0 { ", " } else { "" };
897        let trait_path = self.tcx.def_path_str(trait_def_id);
898        let method_name = self.tcx.item_name(self.def_id);
899        err.span_suggestion_verbose(
900            expr.span,
901            msg,
902            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}::{1}::{2}({3}{4}{5})",
                trait_path, generics, method_name, rcvr, comma, rest))
    })format!("{trait_path}::{generics}::{method_name}({rcvr}{comma}{rest})"),
903            Applicability::MaybeIncorrect,
904        );
905    }
906
907    /// Suggests to remove redundant argument(s):
908    ///
909    /// ```text
910    /// type Map = HashMap<String, String, String, String>;
911    /// ```
912    fn suggest_removing_args_or_generics(&self, err: &mut Diag<'_>) {
913        let num_provided_lt_args = self.num_provided_lifetime_args();
914        let num_provided_type_const_args = self.num_provided_type_or_const_args();
915        let unbound_assoc_items = self.get_unbound_associated_item();
916        let num_provided_args = num_provided_lt_args + num_provided_type_const_args;
917        if !(num_provided_args > 0) {
    ::core::panicking::panic("assertion failed: num_provided_args > 0")
};assert!(num_provided_args > 0);
918
919        let num_redundant_lt_args = self.num_excess_lifetime_args();
920        let num_redundant_type_or_const_args = self.num_excess_type_or_const_args();
921        let num_redundant_args = num_redundant_lt_args + num_redundant_type_or_const_args;
922
923        let redundant_lifetime_args = num_redundant_lt_args > 0;
924        let redundant_type_or_const_args = num_redundant_type_or_const_args > 0;
925
926        let remove_entire_generics = num_redundant_args >= self.gen_args.args.len();
927
928        let remove_lifetime_args = |err: &mut Diag<'_>| {
929            let mut lt_arg_spans = Vec::new();
930            let mut found_redundant = false;
931            for arg in self.gen_args.args {
932                if let hir::GenericArg::Lifetime(_) = arg {
933                    lt_arg_spans.push(arg.span());
934                    if lt_arg_spans.len() > self.num_expected_lifetime_args() {
935                        found_redundant = true;
936                    }
937                } else if found_redundant {
938                    // Argument which is redundant and separated like this `'c`
939                    // is not included to avoid including `Bar` in span.
940                    // ```
941                    // type Foo<'a, T> = &'a T;
942                    // let _: Foo<'a, 'b, Bar, 'c>;
943                    // ```
944                    break;
945                }
946            }
947
948            let span_lo_redundant_lt_args = if self.num_expected_lifetime_args() == 0 {
949                lt_arg_spans[0]
950            } else {
951                lt_arg_spans[self.num_expected_lifetime_args() - 1]
952            };
953            let span_hi_redundant_lt_args = lt_arg_spans[lt_arg_spans.len() - 1];
954
955            let span_redundant_lt_args =
956                span_lo_redundant_lt_args.shrink_to_hi().to(span_hi_redundant_lt_args);
957            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:957",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(957u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("span_redundant_lt_args: {0:?}",
                                                    span_redundant_lt_args) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("span_redundant_lt_args: {:?}", span_redundant_lt_args);
958
959            let num_redundant_lt_args = lt_arg_spans.len() - self.num_expected_lifetime_args();
960            let msg_lifetimes =
961                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("remove the lifetime argument{0}",
                if num_redundant_lt_args == 1 { "" } else { "s" }))
    })format!("remove the lifetime argument{s}", s = pluralize!(num_redundant_lt_args));
962
963            err.span_suggestion_short(
964                span_redundant_lt_args,
965                msg_lifetimes,
966                "",
967                Applicability::MaybeIncorrect,
968            );
969        };
970
971        let remove_type_or_const_args = |err: &mut Diag<'_>| {
972            let mut gen_arg_spans = Vec::new();
973            let mut found_redundant = false;
974            for arg in self.gen_args.args {
975                match arg {
976                    hir::GenericArg::Type(_)
977                    | hir::GenericArg::Const(_)
978                    | hir::GenericArg::Infer(_) => {
979                        gen_arg_spans.push(arg.span());
980                        if gen_arg_spans.len() > self.num_expected_type_or_const_args() {
981                            found_redundant = true;
982                        }
983                    }
984                    _ if found_redundant => break,
985                    _ => {}
986                }
987            }
988
989            let span_lo_redundant_type_or_const_args =
990                if self.num_expected_type_or_const_args() == 0 {
991                    gen_arg_spans[0]
992                } else {
993                    gen_arg_spans[self.num_expected_type_or_const_args() - 1]
994                };
995            let span_hi_redundant_type_or_const_args = gen_arg_spans[gen_arg_spans.len() - 1];
996            if !span_lo_redundant_type_or_const_args.eq_ctxt(span_hi_redundant_type_or_const_args) {
997                return;
998            }
999            let span_redundant_type_or_const_args = span_lo_redundant_type_or_const_args
1000                .shrink_to_hi()
1001                .to(span_hi_redundant_type_or_const_args);
1002
1003            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:1003",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(1003u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::diagnostics::wrong_number_of_generic_args"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("span_redundant_type_or_const_args: {0:?}",
                                                    span_redundant_type_or_const_args) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("span_redundant_type_or_const_args: {:?}", span_redundant_type_or_const_args);
1004
1005            let num_redundant_gen_args =
1006                gen_arg_spans.len() - self.num_expected_type_or_const_args();
1007            let msg_types_or_consts = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("remove the unnecessary generic argument{0}",
                if num_redundant_gen_args == 1 { "" } else { "s" }))
    })format!(
1008                "remove the unnecessary generic argument{s}",
1009                s = pluralize!(num_redundant_gen_args),
1010            );
1011
1012            err.span_suggestion_short(
1013                span_redundant_type_or_const_args,
1014                msg_types_or_consts,
1015                "",
1016                Applicability::MaybeIncorrect,
1017            );
1018        };
1019
1020        // If there is an identical amount of unbound associated items and excess generic args
1021        // suggest turning the generic args into associated item bindings
1022        if unbound_assoc_items.len() == num_redundant_type_or_const_args
1023            && !unbound_assoc_items.is_empty()
1024        {
1025            // Don't suggest if we're in a trait impl as
1026            // that would result in invalid syntax (fixes #116464)
1027            if !self.is_in_trait_impl() {
1028                let unused_generics = &self.gen_args.args[self.num_expected_type_or_const_args()..];
1029                let mut unbound_assoc_consts = unbound_assoc_items
1030                    .iter()
1031                    .filter(|item| #[allow(non_exhaustive_omitted_patterns)] match item.kind {
    ty::AssocKind::Const { .. } => true,
    _ => false,
}matches!(item.kind, ty::AssocKind::Const { .. }));
1032                let mut unbound_assoc_types =
1033                    unbound_assoc_items.iter().filter(|item| item.is_type());
1034                let suggestions = unused_generics
1035                    .iter()
1036                    .filter_map(|potential| {
1037                        let item = match potential {
1038                            hir::GenericArg::Const(_) => unbound_assoc_consts.next(),
1039                            hir::GenericArg::Type(_) => unbound_assoc_types.next(),
1040                            _ => None,
1041                        }?;
1042                        Some((
1043                            potential.span().shrink_to_lo(),
1044                            // FIXME: This doesn't account for generic associated items
1045                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} = ",
                self.tcx.item_ident(item.def_id)))
    })format!("{} = ", self.tcx.item_ident(item.def_id)),
1046                        ))
1047                    })
1048                    .collect::<Vec<_>>();
1049
1050                if !suggestions.is_empty() {
1051                    let s = if suggestions.len() == 1 { "" } else { "s" }pluralize!(suggestions.len());
1052                    let article = if suggestions.len() == 1 { "an " } else { "" };
1053                    err.multipart_suggestion(
1054                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("turn the generic argument{0} into {1}associated item binding{0}",
                s, article))
    })format!(
1055                            "turn the generic argument{s} into {article}associated item binding{s}"
1056                        ),
1057                        suggestions,
1058                        Applicability::MaybeIncorrect,
1059                    );
1060                }
1061            }
1062        } else if remove_entire_generics {
1063            let span = self
1064                .path_segment
1065                .args
1066                .unwrap()
1067                .span_ext()
1068                .unwrap()
1069                .with_lo(self.path_segment.ident.span.hi());
1070
1071            let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("remove the unnecessary {0}generics",
                if self.gen_args.parenthesized ==
                        hir::GenericArgsParentheses::ParenSugar {
                    "parenthetical "
                } else { "" }))
    })format!(
1072                "remove the unnecessary {}generics",
1073                if self.gen_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
1074                    "parenthetical "
1075                } else {
1076                    ""
1077                },
1078            );
1079
1080            if span.is_empty() {
1081                // HACK: Avoid ICE when types with the same name with `derive`s are in the same scope:
1082                //     struct NotSM;
1083                //     #[derive(PartialEq, Eq)]
1084                //     struct NotSM<T>(T);
1085                // With the above code, the suggestion would be to remove the generics of the first
1086                // `NotSM`, which doesn't *have* generics, so we would suggest to remove no code with
1087                // no code, which would trigger an `assert!` later. Ideally, we would do something a
1088                // bit more principled. See closed PR #109082.
1089            } else {
1090                err.span_suggestion_short(span, msg, "", Applicability::MaybeIncorrect);
1091            }
1092        } else if redundant_lifetime_args && redundant_type_or_const_args {
1093            remove_lifetime_args(err);
1094            remove_type_or_const_args(err);
1095        } else if redundant_lifetime_args {
1096            remove_lifetime_args(err);
1097        } else {
1098            if !redundant_type_or_const_args {
    ::core::panicking::panic("assertion failed: redundant_type_or_const_args")
};assert!(redundant_type_or_const_args);
1099            remove_type_or_const_args(err);
1100        }
1101    }
1102
1103    /// Builds the `type defined here` message.
1104    fn show_definition(&self, err: &mut Diag<'_>) {
1105        let Some(def_span) = self.tcx.def_ident_span(self.def_id) else { return };
1106        if !self.tcx.sess.source_map().is_span_accessible(def_span) {
1107            return;
1108        };
1109        let mut spans: MultiSpan = def_span.into();
1110
1111        let msg = {
1112            let def_kind = self.tcx.def_descr(self.def_id);
1113            let (quantifier, bound) = self.get_quantifier_and_bound();
1114
1115            let params = if bound == 0 {
1116                String::new()
1117            } else {
1118                let params = self
1119                    .gen_params
1120                    .own_params
1121                    .iter()
1122                    .skip(self.params_offset)
1123                    .take(bound)
1124                    .map(|param| {
1125                        let span = self.tcx.def_span(param.def_id);
1126                        spans.push_span_label(span, "");
1127                        param
1128                    })
1129                    .map(|param| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}`", param.name))
    })format!("`{}`", param.name))
1130                    .collect::<Vec<_>>()
1131                    .join(", ");
1132
1133                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(": {0}", params))
    })format!(": {params}")
1134            };
1135
1136            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} defined here, with {1}{2} {3} parameter{4}{5}",
                def_kind, quantifier, bound, self.kind(),
                if bound == 1 { "" } else { "s" }, params))
    })format!(
1137                "{} defined here, with {}{} {} parameter{}{}",
1138                def_kind,
1139                quantifier,
1140                bound,
1141                self.kind(),
1142                pluralize!(bound),
1143                params,
1144            )
1145        };
1146
1147        err.span_note(spans, msg);
1148    }
1149
1150    /// Add note if `impl Trait` is explicitly specified.
1151    fn note_synth_provided(&self, err: &mut Diag<'_>) {
1152        if !self.is_synth_provided() {
1153            return;
1154        }
1155
1156        err.note("`impl Trait` cannot be explicitly specified as a generic argument");
1157    }
1158}
1159
1160impl<'a> Diagnostic<'a> for WrongNumberOfGenericArgs<'_, '_> {
1161    fn into_diag(
1162        self,
1163        dcx: rustc_errors::DiagCtxtHandle<'a>,
1164        level: rustc_errors::Level,
1165    ) -> Diag<'a> {
1166        let msg = self.create_error_message();
1167        let mut err = Diag::new(dcx, level, msg);
1168        err.code(E0107);
1169        err.span(self.path_segment.ident.span);
1170
1171        let cx_span = self.tcx.def_span(self.cx_def_id);
1172        if cx_span.in_derive_expansion() {
1173            // Very likely this is a botched `derive` which passes the iten name straight
1174            // through, but doesn't support type parameters.
1175            err.span_label(
1176                cx_span.ctxt().outer_expn_data().call_site,
1177                "this derive macro might not support items with generic parameters",
1178            );
1179        } else {
1180            self.notify(&mut err);
1181            self.suggest(&mut err);
1182            self.show_definition(&mut err);
1183            self.note_synth_provided(&mut err);
1184        }
1185
1186        err
1187    }
1188}