Rollup merge of #93982 - nbdd0121:explicit-generic-args, r=jackh726

Provide extra note if synthetic type args are specified

Implement the unresolved question in #83701 as suggested in https://github.com/rust-lang/rust/pull/86176#discussion_r680613890.

r? ``@jackh726``
This commit is contained in:
Matthias Krüger 2022-02-26 07:52:41 +01:00 committed by GitHub
commit 5dcee689d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 51 deletions

View File

@ -512,62 +512,70 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
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;
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;
GenericArgsInfo::ExcessTypesOrConsts {
num_redundant_args,
num_default_params,
args_offset,
}
} else {
let num_missing_args = expected_max - provided;
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
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
};
let args_correct = {
let expected_min = if infer_args {
0
@ -582,6 +590,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
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(),

View File

@ -84,6 +84,9 @@ pub enum GenericArgsInfo {
// 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,
},
}
@ -254,6 +257,13 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
}
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) {
@ -780,6 +790,15 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
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> {
@ -797,6 +816,7 @@ 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
}

View File

@ -11,6 +11,7 @@ note: function defined here, with 1 generic parameter: `T`
|
LL | fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
| ^^^ -
= note: `impl Trait` cannot be explicitly specified as a generic argument
error: aborting due to previous error