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:
commit
5dcee689d1
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user