diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-04-08 21:25:59 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-08 21:25:59 +0200 |
| commit | b41e2bd807884180cb06bb971d7add2a5ed93b03 (patch) | |
| tree | 6d0f5658456db58313645cca62b835a4ac1e0934 | |
| parent | df9796f20dd9a6cd983cbef739ec612c0582509a (diff) | |
| parent | d940038636c3694c896988c5cb035da4456a2cb0 (diff) | |
| download | rust-b41e2bd807884180cb06bb971d7add2a5ed93b03.tar.gz rust-b41e2bd807884180cb06bb971d7add2a5ed93b03.zip | |
Rollup merge of #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
9 files changed, 70 insertions, 44 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 794502d7aae..bd13c413a4d 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -647,9 +647,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { #[rustc_lint_diagnostics] pub fn note_expected_found( &mut self, - expected_label: &dyn fmt::Display, + expected_label: &str, expected: DiagStyledString, - found_label: &dyn fmt::Display, + found_label: &str, found: DiagStyledString, ) -> &mut Self { self.note_expected_found_extra( @@ -665,9 +665,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { #[rustc_lint_diagnostics] pub fn note_expected_found_extra( &mut self, - expected_label: &dyn fmt::Display, + expected_label: &str, expected: DiagStyledString, - found_label: &dyn fmt::Display, + found_label: &str, found: DiagStyledString, expected_extra: DiagStyledString, found_extra: DiagStyledString, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 55d010e6d34..51214c8e8a4 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -513,7 +513,7 @@ impl Subdiagnostic for BuiltinClashingExternSub<'_> { expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false); let mut found_str = DiagStyledString::new(); found_str.push(self.found.fn_sig(self.tcx).to_string(), true); - diag.note_expected_found(&"", expected_str, &"", found_str); + diag.note_expected_found("", expected_str, "", found_str); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index c7f0a88f951..fcb98f740b0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -967,7 +967,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { format!("...so that the {}", sup_trace.cause.as_requirement_str()), ); - err.note_expected_found(&"", sup_expected, &"", sup_found); + err.note_expected_found("", sup_expected, "", sup_found); return if sub_region.is_error() | sup_region.is_error() { err.delay_as_bug() } else { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index bc45fc11e9b..5648021f613 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2,6 +2,7 @@ use core::ops::ControlFlow; use std::borrow::Cow; use std::path::PathBuf; +use rustc_abi::ExternAbi; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::unord::UnordSet; @@ -2799,32 +2800,57 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } // Note any argument mismatches - let given_ty = params.skip_binder(); + let ty::Tuple(given) = *params.skip_binder().kind() else { + return; + }; + let expected_ty = trait_pred.skip_binder().trait_ref.args.type_at(1); - if let ty::Tuple(given) = given_ty.kind() - && let ty::Tuple(expected) = expected_ty.kind() - { - if expected.len() != given.len() { - // Note number of types that were expected and given - err.note( - format!( - "expected a closure taking {} argument{}, but one taking {} argument{} was given", - given.len(), - pluralize!(given.len()), - expected.len(), - pluralize!(expected.len()), - ) - ); - } else if !self.same_type_modulo_infer(given_ty, expected_ty) { - // Print type mismatch - let (expected_args, given_args) = self.cmp(given_ty, expected_ty); - err.note_expected_found( - &"a closure with arguments", - expected_args, - &"a closure with arguments", - given_args, - ); - } + let ty::Tuple(expected) = *expected_ty.kind() else { + return; + }; + + if expected.len() != given.len() { + // Note number of types that were expected and given + err.note(format!( + "expected a closure taking {} argument{}, but one taking {} argument{} was given", + given.len(), + pluralize!(given.len()), + expected.len(), + pluralize!(expected.len()), + )); + return; + } + + let given_ty = Ty::new_fn_ptr( + self.tcx, + params.rebind(self.tcx.mk_fn_sig( + given, + self.tcx.types.unit, + false, + hir::Safety::Safe, + ExternAbi::Rust, + )), + ); + let expected_ty = Ty::new_fn_ptr( + self.tcx, + trait_pred.rebind(self.tcx.mk_fn_sig( + expected, + self.tcx.types.unit, + false, + hir::Safety::Safe, + ExternAbi::Rust, + )), + ); + + if !self.same_type_modulo_infer(given_ty, expected_ty) { + // Print type mismatch + let (expected_args, given_args) = self.cmp(expected_ty, given_ty); + err.note_expected_found( + "a closure with signature", + expected_args, + "a closure with signature", + given_args, + ); } } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 9f7bfe5101a..bb4aba9d29e 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -415,7 +415,7 @@ impl Subdiagnostic for RegionOriginNote<'_> { label_or_note(span, fluent::trait_selection_subtype); diag.arg("requirement", requirement); - diag.note_expected_found(&"", expected, &"", found); + diag.note_expected_found("", expected, "", found); } RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => { // FIXME: this really should be handled at some earlier stage. Our diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr index 64707642eeb..36264b0d997 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr @@ -6,8 +6,8 @@ LL | call(f, ()); | | | required by a bound introduced by this call | - = note: expected a closure with arguments `((),)` - found a closure with arguments `(<_ as ATC<'a>>::Type,)` + = note: expected a closure with signature `for<'a> fn(<_ as ATC<'a>>::Type)` + found a closure with signature `fn(())` note: this is a known limitation of the trait solver that will be lifted in the future --> $DIR/issue-62529-3.rs:25:14 | diff --git a/tests/ui/implied-bounds/issue-100690.stderr b/tests/ui/implied-bounds/issue-100690.stderr index 4964dccd551..d00895d8fc9 100644 --- a/tests/ui/implied-bounds/issue-100690.stderr +++ b/tests/ui/implied-bounds/issue-100690.stderr @@ -6,8 +6,8 @@ LL | real_dispatch(f) | | | required by a bound introduced by this call | - = note: expected a closure with arguments `(&mut UIView<'a, _>,)` - found a closure with arguments `(&mut UIView<'_, _>,)` + = note: expected a closure with signature `for<'a, 'b> fn(&'a mut UIView<'b, _>)` + found a closure with signature `fn(&mut UIView<'a, _>)` note: required by a bound in `real_dispatch` --> $DIR/issue-100690.rs:8:8 | diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr index b7161310619..7912ed4d707 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr @@ -7,8 +7,8 @@ LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0); | required by a bound introduced by this call | = 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}` - = note: expected a closure with arguments `(i32,)` - found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)` + = note: expected a closure with signature `for<'a> fn(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` + found a closure with signature `fn(i32)` note: required by a bound in `find` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL @@ -27,8 +27,8 @@ LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); | required by a bound introduced by this call | = 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}` - = note: expected a closure with arguments `(&&&i32,)` - found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)` + = note: expected a closure with signature `for<'a> fn(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` + found a closure with signature `fn(&&&i32)` note: required by a bound in `find` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL diff --git a/tests/ui/trait-bounds/mismatch-fn-trait.stderr b/tests/ui/trait-bounds/mismatch-fn-trait.stderr index 519aa9ea3f3..051e660c2d1 100644 --- a/tests/ui/trait-bounds/mismatch-fn-trait.stderr +++ b/tests/ui/trait-bounds/mismatch-fn-trait.stderr @@ -6,8 +6,8 @@ LL | take(f) | | | required by a bound introduced by this call | - = note: expected a closure with arguments `(u32,)` - found a closure with arguments `(i32,)` + = note: expected a closure with signature `fn(i32)` + found a closure with signature `fn(u32)` note: required by a bound in `take` --> $DIR/mismatch-fn-trait.rs:1:18 | @@ -68,8 +68,8 @@ LL | take(f) | required by a bound introduced by this call | = note: `impl FnOnce(u32)` implements `FnOnce`, but it must implement `FnMut`, which is more general - = note: expected a closure with arguments `(u32,)` - found a closure with arguments `(i32,)` + = note: expected a closure with signature `fn(i32)` + found a closure with signature `fn(u32)` note: required by a bound in `take` --> $DIR/mismatch-fn-trait.rs:1:18 | |
