Skip to main content

rustc_hir_analysis/errors/
wrong_number_of_generic_args.rs

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