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
11pub(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 pub(crate) path_segment: &'a hir::PathSegment<'a>,
21
22 pub(crate) gen_params: &'a ty::Generics,
24
25 pub(crate) params_offset: usize,
29
30 pub(crate) gen_args: &'a hir::GenericArgs<'a>,
32
33 pub(crate) def_id: DefId,
35}
36
37#[derive(#[automatically_derived]
impl ::core::fmt::Debug for AngleBrackets {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
AngleBrackets::Implied => "Implied",
AngleBrackets::Missing => "Missing",
AngleBrackets::Available => "Available",
})
}
}Debug)]
40pub(crate) enum AngleBrackets {
41 Implied,
43
44 Missing,
46
47 Available,
49}
50
51#[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 num_default_params: usize,
65
66 args_offset: usize,
71 },
72
73 ExcessTypesOrConsts {
74 num_redundant_args: usize,
75
76 num_default_params: usize,
78
79 args_offset: usize,
84
85 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 fn is_in_trait_impl(&self) -> bool {
132 if self.tcx.is_trait(self.def_id) {
133 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 let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else {
143 return false;
144 };
145
146 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 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 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 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 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 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 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 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 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 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 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 if let hir::Node::Item(_) = node {
421 break;
422 }
423 }
424
425 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 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 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 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 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 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 }
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 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 ::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 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 (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 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 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 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 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 provided_args_matches_unbound_traits && !unbound_types.is_empty() {
1018 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 } 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 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 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}