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
This commit is contained in:
commit
b41e2bd807
9 changed files with 70 additions and 44 deletions
|
@ -647,9 +647,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
pub fn note_expected_found(
|
pub fn note_expected_found(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected_label: &dyn fmt::Display,
|
expected_label: &str,
|
||||||
expected: DiagStyledString,
|
expected: DiagStyledString,
|
||||||
found_label: &dyn fmt::Display,
|
found_label: &str,
|
||||||
found: DiagStyledString,
|
found: DiagStyledString,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.note_expected_found_extra(
|
self.note_expected_found_extra(
|
||||||
|
@ -665,9 +665,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
pub fn note_expected_found_extra(
|
pub fn note_expected_found_extra(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected_label: &dyn fmt::Display,
|
expected_label: &str,
|
||||||
expected: DiagStyledString,
|
expected: DiagStyledString,
|
||||||
found_label: &dyn fmt::Display,
|
found_label: &str,
|
||||||
found: DiagStyledString,
|
found: DiagStyledString,
|
||||||
expected_extra: DiagStyledString,
|
expected_extra: DiagStyledString,
|
||||||
found_extra: DiagStyledString,
|
found_extra: DiagStyledString,
|
||||||
|
|
|
@ -513,7 +513,7 @@ impl Subdiagnostic for BuiltinClashingExternSub<'_> {
|
||||||
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
|
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
|
||||||
let mut found_str = DiagStyledString::new();
|
let mut found_str = DiagStyledString::new();
|
||||||
found_str.push(self.found.fn_sig(self.tcx).to_string(), true);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -967,7 +967,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
format!("...so that the {}", sup_trace.cause.as_requirement_str()),
|
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() {
|
return if sub_region.is_error() | sup_region.is_error() {
|
||||||
err.delay_as_bug()
|
err.delay_as_bug()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,6 +2,7 @@ use core::ops::ControlFlow;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use rustc_abi::ExternAbi;
|
||||||
use rustc_ast::TraitObjectSyntax;
|
use rustc_ast::TraitObjectSyntax;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::unord::UnordSet;
|
use rustc_data_structures::unord::UnordSet;
|
||||||
|
@ -2799,34 +2800,59 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note any argument mismatches
|
// 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);
|
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() else {
|
||||||
&& let ty::Tuple(expected) = expected_ty.kind()
|
return;
|
||||||
{
|
};
|
||||||
|
|
||||||
if expected.len() != given.len() {
|
if expected.len() != given.len() {
|
||||||
// Note number of types that were expected and given
|
// Note number of types that were expected and given
|
||||||
err.note(
|
err.note(format!(
|
||||||
format!(
|
|
||||||
"expected a closure taking {} argument{}, but one taking {} argument{} was given",
|
"expected a closure taking {} argument{}, but one taking {} argument{} was given",
|
||||||
given.len(),
|
given.len(),
|
||||||
pluralize!(given.len()),
|
pluralize!(given.len()),
|
||||||
expected.len(),
|
expected.len(),
|
||||||
pluralize!(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,
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
} else if !self.same_type_modulo_infer(given_ty, expected_ty) {
|
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
|
// Print type mismatch
|
||||||
let (expected_args, given_args) = self.cmp(given_ty, expected_ty);
|
let (expected_args, given_args) = self.cmp(expected_ty, given_ty);
|
||||||
err.note_expected_found(
|
err.note_expected_found(
|
||||||
&"a closure with arguments",
|
"a closure with signature",
|
||||||
expected_args,
|
expected_args,
|
||||||
&"a closure with arguments",
|
"a closure with signature",
|
||||||
given_args,
|
given_args,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn maybe_add_note_for_unsatisfied_const(
|
fn maybe_add_note_for_unsatisfied_const(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -415,7 +415,7 @@ impl Subdiagnostic for RegionOriginNote<'_> {
|
||||||
label_or_note(span, fluent::trait_selection_subtype);
|
label_or_note(span, fluent::trait_selection_subtype);
|
||||||
diag.arg("requirement", requirement);
|
diag.arg("requirement", requirement);
|
||||||
|
|
||||||
diag.note_expected_found(&"", expected, &"", found);
|
diag.note_expected_found("", expected, "", found);
|
||||||
}
|
}
|
||||||
RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
|
RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
|
||||||
// FIXME: this really should be handled at some earlier stage. Our
|
// FIXME: this really should be handled at some earlier stage. Our
|
||||||
|
|
|
@ -6,8 +6,8 @@ LL | call(f, ());
|
||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: expected a closure with arguments `((),)`
|
= note: expected a closure with signature `for<'a> fn(<_ as ATC<'a>>::Type)`
|
||||||
found a closure with arguments `(<_ 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
|
note: this is a known limitation of the trait solver that will be lifted in the future
|
||||||
--> $DIR/issue-62529-3.rs:25:14
|
--> $DIR/issue-62529-3.rs:25:14
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ LL | real_dispatch(f)
|
||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: expected a closure with arguments `(&mut UIView<'a, _>,)`
|
= note: expected a closure with signature `for<'a, 'b> fn(&'a mut UIView<'b, _>)`
|
||||||
found a closure with arguments `(&mut UIView<'_, _>,)`
|
found a closure with signature `fn(&mut UIView<'a, _>)`
|
||||||
note: required by a bound in `real_dispatch`
|
note: required by a bound in `real_dispatch`
|
||||||
--> $DIR/issue-100690.rs:8:8
|
--> $DIR/issue-100690.rs:8:8
|
||||||
|
|
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0);
|
||||||
| required by a bound introduced by this call
|
| 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}`
|
= 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,)`
|
= note: expected a closure with signature `for<'a> fn(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)`
|
||||||
found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)`
|
found a closure with signature `fn(i32)`
|
||||||
note: required by a bound in `find`
|
note: required by a bound in `find`
|
||||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--> $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
|
| 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}`
|
= 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,)`
|
= note: expected a closure with signature `for<'a> fn(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)`
|
||||||
found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)`
|
found a closure with signature `fn(&&&i32)`
|
||||||
note: required by a bound in `find`
|
note: required by a bound in `find`
|
||||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ LL | take(f)
|
||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: expected a closure with arguments `(u32,)`
|
= note: expected a closure with signature `fn(i32)`
|
||||||
found a closure with arguments `(i32,)`
|
found a closure with signature `fn(u32)`
|
||||||
note: required by a bound in `take`
|
note: required by a bound in `take`
|
||||||
--> $DIR/mismatch-fn-trait.rs:1:18
|
--> $DIR/mismatch-fn-trait.rs:1:18
|
||||||
|
|
|
|
||||||
|
@ -68,8 +68,8 @@ LL | take(f)
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: `impl FnOnce(u32)` implements `FnOnce`, but it must implement `FnMut`, which is more general
|
= note: `impl FnOnce(u32)` implements `FnOnce`, but it must implement `FnMut`, which is more general
|
||||||
= note: expected a closure with arguments `(u32,)`
|
= note: expected a closure with signature `fn(i32)`
|
||||||
found a closure with arguments `(i32,)`
|
found a closure with signature `fn(u32)`
|
||||||
note: required by a bound in `take`
|
note: required by a bound in `take`
|
||||||
--> $DIR/mismatch-fn-trait.rs:1:18
|
--> $DIR/mismatch-fn-trait.rs:1:18
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue