Skip to content

Commit 6747458

Browse files
committed
Provide extra note if synthetic type args are specified
1 parent d973b35 commit 6747458

File tree

3 files changed

+79
-49
lines changed

3 files changed

+79
-49
lines changed

compiler/rustc_typeck/src/astconv/generics.rs

+58-49
Original file line numberDiff line numberDiff line change
@@ -512,61 +512,69 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
512512
explicit_late_bound == ExplicitLateBound::Yes,
513513
);
514514

515-
let mut check_types_and_consts =
516-
|expected_min, expected_max, provided, params_offset, args_offset| {
517-
debug!(
518-
?expected_min,
519-
?expected_max,
520-
?provided,
521-
?params_offset,
522-
?args_offset,
523-
"check_types_and_consts"
515+
let mut check_types_and_consts = |expected_min,
516+
expected_max,
517+
expected_max_with_synth,
518+
provided,
519+
params_offset,
520+
args_offset| {
521+
debug!(
522+
?expected_min,
523+
?expected_max,
524+
?provided,
525+
?params_offset,
526+
?args_offset,
527+
"check_types_and_consts"
528+
);
529+
if (expected_min..=expected_max).contains(&provided) {
530+
return true;
531+
}
532+
533+
let num_default_params = expected_max - expected_min;
534+
535+
let gen_args_info = if provided > expected_max {
536+
invalid_args.extend(
537+
gen_args.args[args_offset + expected_max..args_offset + provided]
538+
.iter()
539+
.map(|arg| arg.span()),
524540
);
525-
if (expected_min..=expected_max).contains(&provided) {
526-
return true;
541+
let num_redundant_args = provided - expected_max;
542+
543+
// Provide extra note if synthetic arguments like `impl Trait` are specified.
544+
let synth_provided = provided <= expected_max_with_synth;
545+
546+
GenericArgsInfo::ExcessTypesOrConsts {
547+
num_redundant_args,
548+
num_default_params,
549+
args_offset,
550+
synth_provided,
527551
}
552+
} else {
553+
let num_missing_args = expected_max - provided;
528554

529-
let num_default_params = expected_max - expected_min;
555+
GenericArgsInfo::MissingTypesOrConsts {
556+
num_missing_args,
557+
num_default_params,
558+
args_offset,
559+
}
560+
};
530561

531-
let gen_args_info = if provided > expected_max {
532-
invalid_args.extend(
533-
gen_args.args[args_offset + expected_max..args_offset + provided]
534-
.iter()
535-
.map(|arg| arg.span()),
536-
);
537-
let num_redundant_args = provided - expected_max;
562+
debug!(?gen_args_info);
538563

539-
GenericArgsInfo::ExcessTypesOrConsts {
540-
num_redundant_args,
541-
num_default_params,
542-
args_offset,
543-
}
544-
} else {
545-
let num_missing_args = expected_max - provided;
564+
WrongNumberOfGenericArgs::new(
565+
tcx,
566+
gen_args_info,
567+
seg,
568+
gen_params,
569+
params_offset,
570+
gen_args,
571+
def_id,
572+
)
573+
.diagnostic()
574+
.emit_unless(gen_args.has_err());
546575

547-
GenericArgsInfo::MissingTypesOrConsts {
548-
num_missing_args,
549-
num_default_params,
550-
args_offset,
551-
}
552-
};
553-
554-
debug!(?gen_args_info);
555-
556-
WrongNumberOfGenericArgs::new(
557-
tcx,
558-
gen_args_info,
559-
seg,
560-
gen_params,
561-
params_offset,
562-
gen_args,
563-
def_id,
564-
)
565-
.diagnostic()
566-
.emit_unless(gen_args.has_err());
567-
568-
false
569-
};
576+
false
577+
};
570578

571579
let args_correct = {
572580
let expected_min = if infer_args {
@@ -582,6 +590,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
582590
check_types_and_consts(
583591
expected_min,
584592
param_counts.consts + named_type_param_count,
593+
param_counts.consts + named_type_param_count + synth_type_param_count,
585594
gen_args.num_generic_params(),
586595
param_counts.lifetimes + has_self as usize,
587596
gen_args.num_lifetime_params(),

compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs

+20
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ pub enum GenericArgsInfo {
8484
// us infer the position of type and const generic arguments
8585
// in the angle brackets
8686
args_offset: usize,
87+
88+
// if synthetic type arguments (e.g. `impl Trait`) are specified
89+
synth_provided: bool,
8790
},
8891
}
8992

@@ -254,6 +257,13 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
254257
}
255258
}
256259

260+
fn is_synth_provided(&self) -> bool {
261+
match self.gen_args_info {
262+
ExcessTypesOrConsts { synth_provided, .. } => synth_provided,
263+
_ => false,
264+
}
265+
}
266+
257267
// Helper function to choose a quantifier word for the number of expected arguments
258268
// and to give a bound for the number of expected arguments
259269
fn get_quantifier_and_bound(&self) -> (&'static str, usize) {
@@ -780,6 +790,15 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
780790

781791
err.span_note(spans, &msg);
782792
}
793+
794+
/// Add note if `impl Trait` is explicitly specified.
795+
fn note_synth_provided(&self, err: &mut Diagnostic) {
796+
if !self.is_synth_provided() {
797+
return;
798+
}
799+
800+
err.note("`impl Trait` cannot be explicitly specified as a generic argument");
801+
}
783802
}
784803

785804
impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
@@ -797,6 +816,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
797816
self.notify(&mut err);
798817
self.suggest(&mut err);
799818
self.show_definition(&mut err);
819+
self.note_synth_provided(&mut err);
800820

801821
err
802822
}

src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ note: function defined here, with 1 generic parameter: `T`
1111
|
1212
LL | fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
1313
| ^^^ -
14+
= note: `impl Trait` cannot be explicitly specified as a generic argument
1415

1516
error: aborting due to previous error
1617

0 commit comments

Comments
 (0)