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