explicit_late_bound == ExplicitLateBound::Yes,
);
- let mut check_types_and_consts =
- |expected_min, expected_max, provided, params_offset, args_offset| {
- debug!(
- ?expected_min,
- ?expected_max,
- ?provided,
- ?params_offset,
- ?args_offset,
- "check_types_and_consts"
+ let mut check_types_and_consts = |expected_min,
+ expected_max,
+ expected_max_with_synth,
+ provided,
+ params_offset,
+ args_offset| {
+ debug!(
+ ?expected_min,
+ ?expected_max,
+ ?provided,
+ ?params_offset,
+ ?args_offset,
+ "check_types_and_consts"
+ );
+ if (expected_min..=expected_max).contains(&provided) {
+ return true;
+ }
+
+ let num_default_params = expected_max - expected_min;
+
+ let gen_args_info = if provided > expected_max {
+ invalid_args.extend(
+ gen_args.args[args_offset + expected_max..args_offset + provided]
+ .iter()
+ .map(|arg| arg.span()),
);
- if (expected_min..=expected_max).contains(&provided) {
- return true;
+ let num_redundant_args = provided - expected_max;
+
+ // Provide extra note if synthetic arguments like `impl Trait` are specified.
+ let synth_provided = provided <= expected_max_with_synth;
+
+ GenericArgsInfo::ExcessTypesOrConsts {
+ num_redundant_args,
+ num_default_params,
+ args_offset,
+ synth_provided,
}
+ } else {
+ let num_missing_args = expected_max - provided;
- let num_default_params = expected_max - expected_min;
+ GenericArgsInfo::MissingTypesOrConsts {
+ num_missing_args,
+ num_default_params,
+ args_offset,
+ }
+ };
- let gen_args_info = if provided > expected_max {
- invalid_args.extend(
- gen_args.args[args_offset + expected_max..args_offset + provided]
- .iter()
- .map(|arg| arg.span()),
- );
- let num_redundant_args = provided - expected_max;
+ debug!(?gen_args_info);
- GenericArgsInfo::ExcessTypesOrConsts {
- num_redundant_args,
- num_default_params,
- args_offset,
- }
- } else {
- let num_missing_args = expected_max - provided;
+ WrongNumberOfGenericArgs::new(
+ tcx,
+ gen_args_info,
+ seg,
+ gen_params,
+ params_offset,
+ gen_args,
+ def_id,
+ )
+ .diagnostic()
+ .emit_unless(gen_args.has_err());
- GenericArgsInfo::MissingTypesOrConsts {
- num_missing_args,
- num_default_params,
- args_offset,
- }
- };
-
- debug!(?gen_args_info);
-
- WrongNumberOfGenericArgs::new(
- tcx,
- gen_args_info,
- seg,
- gen_params,
- params_offset,
- gen_args,
- def_id,
- )
- .diagnostic()
- .emit_unless(gen_args.has_err());
-
- false
- };
+ false
+ };
let args_correct = {
let expected_min = if infer_args {
check_types_and_consts(
expected_min,
param_counts.consts + named_type_param_count,
+ param_counts.consts + named_type_param_count + synth_type_param_count,
gen_args.num_generic_params(),
param_counts.lifetimes + has_self as usize,
gen_args.num_lifetime_params(),
// us infer the position of type and const generic arguments
// in the angle brackets
args_offset: usize,
+
+ // if synthetic type arguments (e.g. `impl Trait`) are specified
+ synth_provided: bool,
},
}
}
}
+ fn is_synth_provided(&self) -> bool {
+ match self.gen_args_info {
+ ExcessTypesOrConsts { synth_provided, .. } => synth_provided,
+ _ => false,
+ }
+ }
+
// Helper function to choose a quantifier word for the number of expected arguments
// and to give a bound for the number of expected arguments
fn get_quantifier_and_bound(&self) -> (&'static str, usize) {
err.span_note(spans, &msg);
}
+
+ /// Add note if `impl Trait` is explicitly specified.
+ fn note_synth_provided(&self, err: &mut Diagnostic) {
+ if !self.is_synth_provided() {
+ return;
+ }
+
+ err.note("`impl Trait` cannot be explicitly specified as a generic argument");
+ }
}
impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
self.notify(&mut err);
self.suggest(&mut err);
self.show_definition(&mut err);
+ self.note_synth_provided(&mut err);
err
}