Skip to content

Commit b41e2bd

Browse files
authored
Rollup merge of rust-lang#139515 - compiler-errors:sig-mismatch, r=lcnr
Improve presentation of closure signature mismatch from `Fn` trait goal Flip the order of "expected" and "found" since that wasn't correct. Don't present the arguments as a tuple, since it leaves a trailing comma. Instead, just use `fn(arg, arg)`. Finally, be better with binders since we were just skipping binders. r? oli-obk or reassign
2 parents df9796f + d940038 commit b41e2bd

File tree

9 files changed

+70
-44
lines changed

9 files changed

+70
-44
lines changed

compiler/rustc_errors/src/diagnostic.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -647,9 +647,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
647647
#[rustc_lint_diagnostics]
648648
pub fn note_expected_found(
649649
&mut self,
650-
expected_label: &dyn fmt::Display,
650+
expected_label: &str,
651651
expected: DiagStyledString,
652-
found_label: &dyn fmt::Display,
652+
found_label: &str,
653653
found: DiagStyledString,
654654
) -> &mut Self {
655655
self.note_expected_found_extra(
@@ -665,9 +665,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
665665
#[rustc_lint_diagnostics]
666666
pub fn note_expected_found_extra(
667667
&mut self,
668-
expected_label: &dyn fmt::Display,
668+
expected_label: &str,
669669
expected: DiagStyledString,
670-
found_label: &dyn fmt::Display,
670+
found_label: &str,
671671
found: DiagStyledString,
672672
expected_extra: DiagStyledString,
673673
found_extra: DiagStyledString,

compiler/rustc_lint/src/lints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ impl Subdiagnostic for BuiltinClashingExternSub<'_> {
513513
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
514514
let mut found_str = DiagStyledString::new();
515515
found_str.push(self.found.fn_sig(self.tcx).to_string(), true);
516-
diag.note_expected_found(&"", expected_str, &"", found_str);
516+
diag.note_expected_found("", expected_str, "", found_str);
517517
}
518518
}
519519

compiler/rustc_trait_selection/src/error_reporting/infer/region.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
967967
format!("...so that the {}", sup_trace.cause.as_requirement_str()),
968968
);
969969

970-
err.note_expected_found(&"", sup_expected, &"", sup_found);
970+
err.note_expected_found("", sup_expected, "", sup_found);
971971
return if sub_region.is_error() | sup_region.is_error() {
972972
err.delay_as_bug()
973973
} else {

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+51-25
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use core::ops::ControlFlow;
22
use std::borrow::Cow;
33
use std::path::PathBuf;
44

5+
use rustc_abi::ExternAbi;
56
use rustc_ast::TraitObjectSyntax;
67
use rustc_data_structures::fx::FxHashMap;
78
use rustc_data_structures::unord::UnordSet;
@@ -2799,32 +2800,57 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
27992800
}
28002801

28012802
// Note any argument mismatches
2802-
let given_ty = params.skip_binder();
2803+
let ty::Tuple(given) = *params.skip_binder().kind() else {
2804+
return;
2805+
};
2806+
28032807
let expected_ty = trait_pred.skip_binder().trait_ref.args.type_at(1);
2804-
if let ty::Tuple(given) = given_ty.kind()
2805-
&& let ty::Tuple(expected) = expected_ty.kind()
2806-
{
2807-
if expected.len() != given.len() {
2808-
// Note number of types that were expected and given
2809-
err.note(
2810-
format!(
2811-
"expected a closure taking {} argument{}, but one taking {} argument{} was given",
2812-
given.len(),
2813-
pluralize!(given.len()),
2814-
expected.len(),
2815-
pluralize!(expected.len()),
2816-
)
2817-
);
2818-
} else if !self.same_type_modulo_infer(given_ty, expected_ty) {
2819-
// Print type mismatch
2820-
let (expected_args, given_args) = self.cmp(given_ty, expected_ty);
2821-
err.note_expected_found(
2822-
&"a closure with arguments",
2823-
expected_args,
2824-
&"a closure with arguments",
2825-
given_args,
2826-
);
2827-
}
2808+
let ty::Tuple(expected) = *expected_ty.kind() else {
2809+
return;
2810+
};
2811+
2812+
if expected.len() != given.len() {
2813+
// Note number of types that were expected and given
2814+
err.note(format!(
2815+
"expected a closure taking {} argument{}, but one taking {} argument{} was given",
2816+
given.len(),
2817+
pluralize!(given.len()),
2818+
expected.len(),
2819+
pluralize!(expected.len()),
2820+
));
2821+
return;
2822+
}
2823+
2824+
let given_ty = Ty::new_fn_ptr(
2825+
self.tcx,
2826+
params.rebind(self.tcx.mk_fn_sig(
2827+
given,
2828+
self.tcx.types.unit,
2829+
false,
2830+
hir::Safety::Safe,
2831+
ExternAbi::Rust,
2832+
)),
2833+
);
2834+
let expected_ty = Ty::new_fn_ptr(
2835+
self.tcx,
2836+
trait_pred.rebind(self.tcx.mk_fn_sig(
2837+
expected,
2838+
self.tcx.types.unit,
2839+
false,
2840+
hir::Safety::Safe,
2841+
ExternAbi::Rust,
2842+
)),
2843+
);
2844+
2845+
if !self.same_type_modulo_infer(given_ty, expected_ty) {
2846+
// Print type mismatch
2847+
let (expected_args, given_args) = self.cmp(expected_ty, given_ty);
2848+
err.note_expected_found(
2849+
"a closure with signature",
2850+
expected_args,
2851+
"a closure with signature",
2852+
given_args,
2853+
);
28282854
}
28292855
}
28302856

compiler/rustc_trait_selection/src/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ impl Subdiagnostic for RegionOriginNote<'_> {
415415
label_or_note(span, fluent::trait_selection_subtype);
416416
diag.arg("requirement", requirement);
417417

418-
diag.note_expected_found(&"", expected, &"", found);
418+
diag.note_expected_found("", expected, "", found);
419419
}
420420
RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
421421
// FIXME: this really should be handled at some earlier stage. Our

tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | call(f, ());
66
| |
77
| required by a bound introduced by this call
88
|
9-
= note: expected a closure with arguments `((),)`
10-
found a closure with arguments `(<_ as ATC<'a>>::Type,)`
9+
= note: expected a closure with signature `for<'a> fn(<_ as ATC<'a>>::Type)`
10+
found a closure with signature `fn(())`
1111
note: this is a known limitation of the trait solver that will be lifted in the future
1212
--> $DIR/issue-62529-3.rs:25:14
1313
|

tests/ui/implied-bounds/issue-100690.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | real_dispatch(f)
66
| |
77
| required by a bound introduced by this call
88
|
9-
= note: expected a closure with arguments `(&mut UIView<'a, _>,)`
10-
found a closure with arguments `(&mut UIView<'_, _>,)`
9+
= note: expected a closure with signature `for<'a, 'b> fn(&'a mut UIView<'b, _>)`
10+
found a closure with signature `fn(&mut UIView<'a, _>)`
1111
note: required by a bound in `real_dispatch`
1212
--> $DIR/issue-100690.rs:8:8
1313
|

tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0);
77
| required by a bound introduced by this call
88
|
99
= help: the trait `for<'a> FnMut(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
10-
= note: expected a closure with arguments `(i32,)`
11-
found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)`
10+
= note: expected a closure with signature `for<'a> fn(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)`
11+
found a closure with signature `fn(i32)`
1212
note: required by a bound in `find`
1313
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
1414

@@ -27,8 +27,8 @@ LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
2727
| required by a bound introduced by this call
2828
|
2929
= help: the trait `for<'a> FnMut(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
30-
= note: expected a closure with arguments `(&&&i32,)`
31-
found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)`
30+
= note: expected a closure with signature `for<'a> fn(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)`
31+
found a closure with signature `fn(&&&i32)`
3232
note: required by a bound in `find`
3333
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
3434

tests/ui/trait-bounds/mismatch-fn-trait.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | take(f)
66
| |
77
| required by a bound introduced by this call
88
|
9-
= note: expected a closure with arguments `(u32,)`
10-
found a closure with arguments `(i32,)`
9+
= note: expected a closure with signature `fn(i32)`
10+
found a closure with signature `fn(u32)`
1111
note: required by a bound in `take`
1212
--> $DIR/mismatch-fn-trait.rs:1:18
1313
|
@@ -68,8 +68,8 @@ LL | take(f)
6868
| required by a bound introduced by this call
6969
|
7070
= note: `impl FnOnce(u32)` implements `FnOnce`, but it must implement `FnMut`, which is more general
71-
= note: expected a closure with arguments `(u32,)`
72-
found a closure with arguments `(i32,)`
71+
= note: expected a closure with signature `fn(i32)`
72+
found a closure with signature `fn(u32)`
7373
note: required by a bound in `take`
7474
--> $DIR/mismatch-fn-trait.rs:1:18
7575
|

0 commit comments

Comments
 (0)