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 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("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(&["path_hir_id"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&path_hir_id)
                                            as &dyn 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 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("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(&["id"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&id) as
                                            &dyn 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.is_type() || item.is_type_const())
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 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("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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("suggest(self.provided {0:?}, self.gen_args.span(): {1:?})",
                                                    self.num_provided_args(), self.gen_args.span()) as
                                            &dyn 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        match self.gen_args_info {
632            MissingLifetimes { .. } => {
633                self.suggest_adding_lifetime_args(err);
634            }
635            MissingTypesOrConsts { .. } => {
636                self.suggest_adding_type_and_const_args(err);
637            }
638            ExcessTypesOrConsts { .. } => {
639                // this can happen with `[const] T` where T isn't a `const trait`.
640            }
641            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
642        }
643    }
644
645    fn suggest_adding_lifetime_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
646        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:646",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(646u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("suggest_adding_lifetime_args(path_segment: {0:?})",
                                                    self.path_segment) as &dyn Value))])
            });
    } else { ; }
};debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment);
647        let num_missing_args = self.num_missing_lifetime_args();
648        let num_params_to_take = num_missing_args;
649        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));
650
651        let suggested_args = self.get_lifetime_args_suggestions_from_param_names(
652            self.path_segment.hir_id,
653            num_params_to_take,
654        );
655        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:655",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(655u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("suggested_args: {0:?}",
                                                    suggested_args) as &dyn Value))])
            });
    } else { ; }
};debug!("suggested_args: {suggested_args:?}");
656
657        match self.angle_brackets {
658            AngleBrackets::Missing => {
659                let span = self.path_segment.ident.span;
660
661                // insert a suggestion of the form "Y<'a, 'b>"
662                let sugg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0}>", suggested_args))
    })format!("<{suggested_args}>");
663                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/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("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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
664
665                err.span_suggestion_verbose(
666                    span.shrink_to_hi(),
667                    msg,
668                    sugg,
669                    Applicability::HasPlaceholders,
670                );
671            }
672
673            AngleBrackets::Available => {
674                let (sugg_span, is_first) = if self.num_provided_lifetime_args() == 0 {
675                    (self.gen_args.span().unwrap().shrink_to_lo(), true)
676                } else {
677                    let last_lt = &self.gen_args.args[self.num_provided_lifetime_args() - 1];
678                    (last_lt.span().shrink_to_hi(), false)
679                };
680                let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
681                let has_constraints = !self.gen_args.constraints.is_empty();
682
683                let sugg_prefix = if is_first { "" } else { ", " };
684                let sugg_suffix =
685                    if is_first && (has_non_lt_args || has_constraints) { ", " } else { "" };
686
687                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}");
688                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:688",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(688u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
689
690                err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
691            }
692            AngleBrackets::Implied => {
693                // We never encounter missing lifetimes in situations in which lifetimes are elided
694                ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
695            }
696        }
697    }
698
699    fn suggest_adding_type_and_const_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
700        let num_missing_args = self.num_missing_type_or_const_args();
701        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));
702
703        let suggested_args =
704            self.get_type_or_const_args_suggestions_from_param_names(num_missing_args);
705        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:705",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(705u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("suggested_args: {0:?}",
                                                    suggested_args) as &dyn Value))])
            });
    } else { ; }
};debug!("suggested_args: {:?}", suggested_args);
706
707        match self.angle_brackets {
708            AngleBrackets::Missing | AngleBrackets::Implied => {
709                let span = self.path_segment.ident.span;
710
711                // insert a suggestion of the form "Y<T, U>"
712                let sugg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0}>", suggested_args))
    })format!("<{suggested_args}>");
713                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/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("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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
714
715                err.span_suggestion_verbose(
716                    span.shrink_to_hi(),
717                    msg,
718                    sugg,
719                    Applicability::HasPlaceholders,
720                );
721            }
722            AngleBrackets::Available => {
723                let gen_args_span = self.gen_args.span().unwrap();
724                let sugg_offset =
725                    self.get_lifetime_args_offset() + self.num_provided_type_or_const_args();
726
727                let (sugg_span, is_first) = if sugg_offset == 0 {
728                    (gen_args_span.shrink_to_lo(), true)
729                } else {
730                    let arg_span = self.gen_args.args[sugg_offset - 1].span();
731                    // If we came here then inferred lifetime's spans can only point
732                    // to either the opening bracket or to the space right after.
733                    // Both of these spans have an `hi` lower than or equal to the span
734                    // of the generics excluding the brackets.
735                    // This allows us to check if `arg_span` is the artificial span of
736                    // an inferred lifetime, in which case the generic we're suggesting to
737                    // add will be the first visible, even if it isn't the actual first generic.
738                    (arg_span.shrink_to_hi(), arg_span.hi() <= gen_args_span.lo())
739                };
740
741                let sugg_prefix = if is_first { "" } else { ", " };
742                let sugg_suffix =
743                    if is_first && !self.gen_args.constraints.is_empty() { ", " } else { "" };
744
745                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}");
746                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:746",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(746u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("sugg: {0:?}",
                                                    sugg) as &dyn Value))])
            });
    } else { ; }
};debug!("sugg: {:?}", sugg);
747
748                err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
749            }
750        }
751    }
752
753    /// Suggests moving redundant argument(s) of an associate function to the
754    /// trait it belongs to.
755    ///
756    /// ```compile_fail
757    /// Into::into::<Option<_>>(42) // suggests considering `Into::<Option<_>>::into(42)`
758    /// ```
759    fn suggest_moving_args_from_assoc_fn_to_trait(
760        &self,
761        err: &mut Diag<'_, impl EmissionGuarantee>,
762    ) {
763        let Some(trait_) = self.tcx.trait_of_assoc(self.def_id) else {
764            return;
765        };
766
767        // Skip suggestion when the associated function is itself generic, it is unclear
768        // how to split the provided parameters between those to suggest to the trait and
769        // those to remain on the associated type.
770        let num_assoc_fn_expected_args =
771            self.num_expected_type_or_const_args() + self.num_expected_lifetime_args();
772        if num_assoc_fn_expected_args > 0 {
773            return;
774        }
775
776        let num_assoc_fn_excess_args =
777            self.num_excess_type_or_const_args() + self.num_excess_lifetime_args();
778
779        let trait_generics = self.tcx.generics_of(trait_);
780        let num_trait_generics_except_self =
781            trait_generics.count() - if trait_generics.has_self { 1 } else { 0 };
782
783        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!(
784            "consider moving {these} generic argument{s} to the `{name}` trait, which takes up to {num} argument{s}",
785            these = pluralize!("this", num_assoc_fn_excess_args),
786            s = pluralize!(num_assoc_fn_excess_args),
787            name = self.tcx.item_name(trait_),
788            num = num_trait_generics_except_self,
789        );
790
791        if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(self.path_segment.hir_id) {
792            match &expr.kind {
793                hir::ExprKind::Path(qpath) => self
794                    .suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
795                        err,
796                        qpath,
797                        msg,
798                        num_assoc_fn_excess_args,
799                        num_trait_generics_except_self,
800                    ),
801                hir::ExprKind::MethodCall(..) => self
802                    .suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
803                        err,
804                        trait_,
805                        expr,
806                        msg,
807                        num_assoc_fn_excess_args,
808                        num_trait_generics_except_self,
809                    ),
810                _ => return,
811            }
812        }
813    }
814
815    fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
816        &self,
817        err: &mut Diag<'_, impl EmissionGuarantee>,
818        qpath: &'tcx hir::QPath<'tcx>,
819        msg: String,
820        num_assoc_fn_excess_args: usize,
821        num_trait_generics_except_self: usize,
822    ) {
823        if let hir::QPath::Resolved(_, path) = qpath
824            && let Some(trait_path_segment) = path.segments.get(0)
825        {
826            let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
827
828            if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args
829                == num_trait_generics_except_self
830                && let Some(span) = self.gen_args.span_ext()
831                && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
832            {
833                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![
834                    (
835                        self.path_segment.ident.span,
836                        format!("{}::{}", snippet, self.path_segment.ident),
837                    ),
838                    (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()),
839                ];
840
841                err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
842            }
843        }
844    }
845
846    fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
847        &self,
848        err: &mut Diag<'_, impl EmissionGuarantee>,
849        trait_def_id: DefId,
850        expr: &'tcx hir::Expr<'tcx>,
851        msg: String,
852        num_assoc_fn_excess_args: usize,
853        num_trait_generics_except_self: usize,
854    ) {
855        let sm = self.tcx.sess.source_map();
856        let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else {
857            return;
858        };
859        if num_assoc_fn_excess_args != num_trait_generics_except_self {
860            return;
861        }
862        let Some(gen_args) = self.gen_args.span_ext() else {
863            return;
864        };
865        let Ok(generics) = sm.span_to_snippet(gen_args) else {
866            return;
867        };
868        let Ok(rcvr) =
869            sm.span_to_snippet(rcvr.span.find_ancestor_inside(expr.span).unwrap_or(rcvr.span))
870        else {
871            return;
872        };
873        let Ok(rest) = (match args {
874            [] => Ok(String::new()),
875            [arg] => {
876                sm.span_to_snippet(arg.span.find_ancestor_inside(expr.span).unwrap_or(arg.span))
877            }
878            [first, .., last] => {
879                let first_span = first.span.find_ancestor_inside(expr.span).unwrap_or(first.span);
880                let last_span = last.span.find_ancestor_inside(expr.span).unwrap_or(last.span);
881                sm.span_to_snippet(first_span.to(last_span))
882            }
883        }) else {
884            return;
885        };
886        let comma = if args.len() > 0 { ", " } else { "" };
887        let trait_path = self.tcx.def_path_str(trait_def_id);
888        let method_name = self.tcx.item_name(self.def_id);
889        err.span_suggestion_verbose(
890            expr.span,
891            msg,
892            ::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})"),
893            Applicability::MaybeIncorrect,
894        );
895    }
896
897    /// Suggests to remove redundant argument(s):
898    ///
899    /// ```text
900    /// type Map = HashMap<String, String, String, String>;
901    /// ```
902    fn suggest_removing_args_or_generics(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
903        let num_provided_lt_args = self.num_provided_lifetime_args();
904        let num_provided_type_const_args = self.num_provided_type_or_const_args();
905        let unbound_assoc_items = self.get_unbound_associated_item();
906        let num_provided_args = num_provided_lt_args + num_provided_type_const_args;
907        if !(num_provided_args > 0) {
    ::core::panicking::panic("assertion failed: num_provided_args > 0")
};assert!(num_provided_args > 0);
908
909        let num_redundant_lt_args = self.num_excess_lifetime_args();
910        let num_redundant_type_or_const_args = self.num_excess_type_or_const_args();
911        let num_redundant_args = num_redundant_lt_args + num_redundant_type_or_const_args;
912
913        let redundant_lifetime_args = num_redundant_lt_args > 0;
914        let redundant_type_or_const_args = num_redundant_type_or_const_args > 0;
915
916        let remove_entire_generics = num_redundant_args >= self.gen_args.args.len();
917
918        let remove_lifetime_args = |err: &mut Diag<'_, _>| {
919            let mut lt_arg_spans = Vec::new();
920            let mut found_redundant = false;
921            for arg in self.gen_args.args {
922                if let hir::GenericArg::Lifetime(_) = arg {
923                    lt_arg_spans.push(arg.span());
924                    if lt_arg_spans.len() > self.num_expected_lifetime_args() {
925                        found_redundant = true;
926                    }
927                } else if found_redundant {
928                    // Argument which is redundant and separated like this `'c`
929                    // is not included to avoid including `Bar` in span.
930                    // ```
931                    // type Foo<'a, T> = &'a T;
932                    // let _: Foo<'a, 'b, Bar, 'c>;
933                    // ```
934                    break;
935                }
936            }
937
938            let span_lo_redundant_lt_args = if self.num_expected_lifetime_args() == 0 {
939                lt_arg_spans[0]
940            } else {
941                lt_arg_spans[self.num_expected_lifetime_args() - 1]
942            };
943            let span_hi_redundant_lt_args = lt_arg_spans[lt_arg_spans.len() - 1];
944
945            let span_redundant_lt_args =
946                span_lo_redundant_lt_args.shrink_to_hi().to(span_hi_redundant_lt_args);
947            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:947",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(947u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("span_redundant_lt_args: {0:?}",
                                                    span_redundant_lt_args) as &dyn Value))])
            });
    } else { ; }
};debug!("span_redundant_lt_args: {:?}", span_redundant_lt_args);
948
949            let num_redundant_lt_args = lt_arg_spans.len() - self.num_expected_lifetime_args();
950            let msg_lifetimes =
951                ::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));
952
953            err.span_suggestion(
954                span_redundant_lt_args,
955                msg_lifetimes,
956                "",
957                Applicability::MaybeIncorrect,
958            );
959        };
960
961        let remove_type_or_const_args = |err: &mut Diag<'_, _>| {
962            let mut gen_arg_spans = Vec::new();
963            let mut found_redundant = false;
964            for arg in self.gen_args.args {
965                match arg {
966                    hir::GenericArg::Type(_)
967                    | hir::GenericArg::Const(_)
968                    | hir::GenericArg::Infer(_) => {
969                        gen_arg_spans.push(arg.span());
970                        if gen_arg_spans.len() > self.num_expected_type_or_const_args() {
971                            found_redundant = true;
972                        }
973                    }
974                    _ if found_redundant => break,
975                    _ => {}
976                }
977            }
978
979            let span_lo_redundant_type_or_const_args =
980                if self.num_expected_type_or_const_args() == 0 {
981                    gen_arg_spans[0]
982                } else {
983                    gen_arg_spans[self.num_expected_type_or_const_args() - 1]
984                };
985            let span_hi_redundant_type_or_const_args = gen_arg_spans[gen_arg_spans.len() - 1];
986            if !span_lo_redundant_type_or_const_args.eq_ctxt(span_hi_redundant_type_or_const_args) {
987                return;
988            }
989            let span_redundant_type_or_const_args = span_lo_redundant_type_or_const_args
990                .shrink_to_hi()
991                .to(span_hi_redundant_type_or_const_args);
992
993            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs:993",
                        "rustc_hir_analysis::diagnostics::wrong_number_of_generic_args",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs"),
                        ::tracing_core::__macro_support::Option::Some(993u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("span_redundant_type_or_const_args: {0:?}",
                                                    span_redundant_type_or_const_args) as &dyn Value))])
            });
    } else { ; }
};debug!("span_redundant_type_or_const_args: {:?}", span_redundant_type_or_const_args);
994
995            let num_redundant_gen_args =
996                gen_arg_spans.len() - self.num_expected_type_or_const_args();
997            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!(
998                "remove the unnecessary generic argument{s}",
999                s = pluralize!(num_redundant_gen_args),
1000            );
1001
1002            err.span_suggestion(
1003                span_redundant_type_or_const_args,
1004                msg_types_or_consts,
1005                "",
1006                Applicability::MaybeIncorrect,
1007            );
1008        };
1009
1010        // If there is an identical amount of unbound associated items and excess generic args
1011        // suggest turning the generic args into associated item bindings
1012        if unbound_assoc_items.len() == num_redundant_type_or_const_args
1013            && !unbound_assoc_items.is_empty()
1014        {
1015            // Don't suggest if we're in a trait impl as
1016            // that would result in invalid syntax (fixes #116464)
1017            if !self.is_in_trait_impl() {
1018                let unused_generics = &self.gen_args.args[self.num_expected_type_or_const_args()..];
1019                let mut unbound_assoc_consts =
1020                    unbound_assoc_items.iter().filter(|item| item.is_type_const());
1021                let mut unbound_assoc_types =
1022                    unbound_assoc_items.iter().filter(|item| item.is_type());
1023                let suggestions = unused_generics
1024                    .iter()
1025                    .filter_map(|potential| {
1026                        let item = match potential {
1027                            hir::GenericArg::Const(_) => unbound_assoc_consts.next(),
1028                            hir::GenericArg::Type(_) => unbound_assoc_types.next(),
1029                            _ => None,
1030                        }?;
1031                        Some((
1032                            potential.span().shrink_to_lo(),
1033                            // FIXME: This doesn't account for generic associated items
1034                            ::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)),
1035                        ))
1036                    })
1037                    .collect::<Vec<_>>();
1038
1039                if !suggestions.is_empty() {
1040                    let s = if suggestions.len() == 1 { "" } else { "s" }pluralize!(suggestions.len());
1041                    let article = if suggestions.len() == 1 { "an " } else { "" };
1042                    err.multipart_suggestion(
1043                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("turn the generic argument{0} into {1}associated item binding{0}",
                s, article))
    })format!(
1044                            "turn the generic argument{s} into {article}associated item binding{s}"
1045                        ),
1046                        suggestions,
1047                        Applicability::MaybeIncorrect,
1048                    );
1049                }
1050            }
1051        } else if remove_entire_generics {
1052            let span = self
1053                .path_segment
1054                .args
1055                .unwrap()
1056                .span_ext()
1057                .unwrap()
1058                .with_lo(self.path_segment.ident.span.hi());
1059
1060            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!(
1061                "remove the unnecessary {}generics",
1062                if self.gen_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
1063                    "parenthetical "
1064                } else {
1065                    ""
1066                },
1067            );
1068
1069            if span.is_empty() {
1070                // HACK: Avoid ICE when types with the same name with `derive`s are in the same scope:
1071                //     struct NotSM;
1072                //     #[derive(PartialEq, Eq)]
1073                //     struct NotSM<T>(T);
1074                // With the above code, the suggestion would be to remove the generics of the first
1075                // `NotSM`, which doesn't *have* generics, so we would suggest to remove no code with
1076                // no code, which would trigger an `assert!` later. Ideally, we would do something a
1077                // bit more principled. See closed PR #109082.
1078            } else {
1079                err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
1080            }
1081        } else if redundant_lifetime_args && redundant_type_or_const_args {
1082            remove_lifetime_args(err);
1083            remove_type_or_const_args(err);
1084        } else if redundant_lifetime_args {
1085            remove_lifetime_args(err);
1086        } else {
1087            if !redundant_type_or_const_args {
    ::core::panicking::panic("assertion failed: redundant_type_or_const_args")
};assert!(redundant_type_or_const_args);
1088            remove_type_or_const_args(err);
1089        }
1090    }
1091
1092    /// Builds the `type defined here` message.
1093    fn show_definition(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
1094        let Some(def_span) = self.tcx.def_ident_span(self.def_id) else { return };
1095        if !self.tcx.sess.source_map().is_span_accessible(def_span) {
1096            return;
1097        };
1098        let mut spans: MultiSpan = def_span.into();
1099
1100        let msg = {
1101            let def_kind = self.tcx.def_descr(self.def_id);
1102            let (quantifier, bound) = self.get_quantifier_and_bound();
1103
1104            let params = if bound == 0 {
1105                String::new()
1106            } else {
1107                let params = self
1108                    .gen_params
1109                    .own_params
1110                    .iter()
1111                    .skip(self.params_offset)
1112                    .take(bound)
1113                    .map(|param| {
1114                        let span = self.tcx.def_span(param.def_id);
1115                        spans.push_span_label(span, "");
1116                        param
1117                    })
1118                    .map(|param| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}`", param.name))
    })format!("`{}`", param.name))
1119                    .collect::<Vec<_>>()
1120                    .join(", ");
1121
1122                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(": {0}", params))
    })format!(": {params}")
1123            };
1124
1125            ::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!(
1126                "{} defined here, with {}{} {} parameter{}{}",
1127                def_kind,
1128                quantifier,
1129                bound,
1130                self.kind(),
1131                pluralize!(bound),
1132                params,
1133            )
1134        };
1135
1136        err.span_note(spans, msg);
1137    }
1138
1139    /// Add note if `impl Trait` is explicitly specified.
1140    fn note_synth_provided(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
1141        if !self.is_synth_provided() {
1142            return;
1143        }
1144
1145        err.note("`impl Trait` cannot be explicitly specified as a generic argument");
1146    }
1147}
1148
1149impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for WrongNumberOfGenericArgs<'_, '_> {
1150    fn into_diag(
1151        self,
1152        dcx: rustc_errors::DiagCtxtHandle<'a>,
1153        level: rustc_errors::Level,
1154    ) -> Diag<'a, G> {
1155        let msg = self.create_error_message();
1156        let mut err = Diag::new(dcx, level, msg);
1157        err.code(E0107);
1158        err.span(self.path_segment.ident.span);
1159
1160        self.notify(&mut err);
1161        self.suggest(&mut err);
1162        self.show_definition(&mut err);
1163        self.note_synth_provided(&mut err);
1164
1165        err
1166    }
1167}