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
3 changed files with 81 additions and 51 deletions
|
@ -512,62 +512,70 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
explicit_late_bound == ExplicitLateBound::Yes,
|
explicit_late_bound == ExplicitLateBound::Yes,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut check_types_and_consts =
|
let mut check_types_and_consts = |expected_min,
|
||||||
|expected_min, expected_max, provided, params_offset, args_offset| {
|
expected_max,
|
||||||
debug!(
|
expected_max_with_synth,
|
||||||
?expected_min,
|
provided,
|
||||||
?expected_max,
|
params_offset,
|
||||||
?provided,
|
args_offset| {
|
||||||
?params_offset,
|
debug!(
|
||||||
?args_offset,
|
?expected_min,
|
||||||
"check_types_and_consts"
|
?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) {
|
let num_redundant_args = provided - expected_max;
|
||||||
return true;
|
|
||||||
|
// 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,
|
||||||
let gen_args_info = if provided > expected_max {
|
num_default_params,
|
||||||
invalid_args.extend(
|
args_offset,
|
||||||
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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 args_correct = {
|
||||||
let expected_min = if infer_args {
|
let expected_min = if infer_args {
|
||||||
0
|
0
|
||||||
|
@ -582,6 +590,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
check_types_and_consts(
|
check_types_and_consts(
|
||||||
expected_min,
|
expected_min,
|
||||||
param_counts.consts + named_type_param_count,
|
param_counts.consts + named_type_param_count,
|
||||||
|
param_counts.consts + named_type_param_count + synth_type_param_count,
|
||||||
gen_args.num_generic_params(),
|
gen_args.num_generic_params(),
|
||||||
param_counts.lifetimes + has_self as usize,
|
param_counts.lifetimes + has_self as usize,
|
||||||
gen_args.num_lifetime_params(),
|
gen_args.num_lifetime_params(),
|
||||||
|
|
|
@ -84,6 +84,9 @@ pub enum GenericArgsInfo {
|
||||||
// us infer the position of type and const generic arguments
|
// us infer the position of type and const generic arguments
|
||||||
// in the angle brackets
|
// in the angle brackets
|
||||||
args_offset: usize,
|
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
|
// Helper function to choose a quantifier word for the number of expected arguments
|
||||||
// and to give a bound 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) {
|
fn get_quantifier_and_bound(&self) -> (&'static str, usize) {
|
||||||
|
@ -780,6 +790,15 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
|
|
||||||
err.span_note(spans, &msg);
|
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> {
|
impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
|
||||||
|
@ -797,6 +816,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
|
||||||
self.notify(&mut err);
|
self.notify(&mut err);
|
||||||
self.suggest(&mut err);
|
self.suggest(&mut err);
|
||||||
self.show_definition(&mut err);
|
self.show_definition(&mut err);
|
||||||
|
self.note_synth_provided(&mut err);
|
||||||
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ note: function defined here, with 1 generic parameter: `T`
|
||||||
|
|
|
|
||||||
LL | fn foo<T: ?Sized>(_f: impl AsRef<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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue