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