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