Skip to content

Commit 030c886

Browse files
committed
Auto merge of #96155 - jackh726:param-heuristics-followup, r=estebank
Followups for method call error change Each commit is self-contained. Fixes most of the followup reviews from that PR. r? `@estebank`
2 parents 4d1076c + 7d8e10d commit 030c886

File tree

44 files changed

+265
-312
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+265
-312
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1584,9 +1584,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15841584
Variable(ty::error::ExpectedFound<Ty<'a>>),
15851585
Fixed(&'static str),
15861586
}
1587-
let (expected_found, exp_found, is_simple_error) = match values {
1588-
None => (None, Mismatch::Fixed("type"), false),
1587+
let (expected_found, exp_found, is_simple_error, values) = match values {
1588+
None => (None, Mismatch::Fixed("type"), false, None),
15891589
Some(values) => {
1590+
let values = self.resolve_vars_if_possible(values);
15901591
let (is_simple_error, exp_found) = match values {
15911592
ValuePairs::Terms(infer::ExpectedFound {
15921593
expected: ty::Term::Ty(expected),
@@ -1614,7 +1615,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16141615
return;
16151616
}
16161617
};
1617-
(vals, exp_found, is_simple_error)
1618+
(vals, exp_found, is_simple_error, Some(values))
16181619
}
16191620
};
16201621

compiler/rustc_typeck/src/check/callee.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub fn check_legal_trait_for_method_call(
5959

6060
enum CallStep<'tcx> {
6161
Builtin(Ty<'tcx>),
62-
DeferredClosure(ty::FnSig<'tcx>),
62+
DeferredClosure(DefId, ty::FnSig<'tcx>),
6363
/// E.g., enum variant constructors.
6464
Overloaded(MethodCallee<'tcx>),
6565
}
@@ -107,8 +107,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
107107
self.confirm_builtin_call(call_expr, callee_expr, callee_ty, arg_exprs, expected)
108108
}
109109

110-
Some(CallStep::DeferredClosure(fn_sig)) => {
111-
self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig)
110+
Some(CallStep::DeferredClosure(def_id, fn_sig)) => {
111+
self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, def_id, fn_sig)
112112
}
113113

114114
Some(CallStep::Overloaded(method_callee)) => {
@@ -171,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
171171
closure_substs: substs,
172172
},
173173
);
174-
return Some(CallStep::DeferredClosure(closure_sig));
174+
return Some(CallStep::DeferredClosure(def_id, closure_sig));
175175
}
176176
}
177177

@@ -533,6 +533,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
533533
call_expr: &'tcx hir::Expr<'tcx>,
534534
arg_exprs: &'tcx [hir::Expr<'tcx>],
535535
expected: Expectation<'tcx>,
536+
closure_def_id: DefId,
536537
fn_sig: ty::FnSig<'tcx>,
537538
) -> Ty<'tcx> {
538539
// `fn_sig` is the *signature* of the closure being called. We
@@ -555,7 +556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
555556
arg_exprs,
556557
fn_sig.c_variadic,
557558
TupleArgumentsFlag::TupleArguments,
558-
None,
559+
Some(closure_def_id),
559560
);
560561

561562
fn_sig.output()

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+63-79
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_infer::infer::TypeTrace;
2424
use rustc_middle::ty::adjustment::AllowTwoPhase;
2525
use rustc_middle::ty::error::TypeError;
2626
use rustc_middle::ty::fold::TypeFoldable;
27-
use rustc_middle::ty::{self, Ty};
27+
use rustc_middle::ty::{self, Ty, TyCtxt};
2828
use rustc_session::Session;
2929
use rustc_span::symbol::Ident;
3030
use rustc_span::{self, Span};
@@ -394,6 +394,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
394394
break 'errors;
395395
}
396396

397+
self.set_tainted_by_errors();
398+
397399
// The algorithm here is inspired by levenshtein distance and longest common subsequence.
398400
// We'll try to detect 4 different types of mistakes:
399401
// - An extra parameter has been provided that doesn't satisfy *any* of the other inputs
@@ -502,6 +504,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
502504
TupleMatchFound::Single => {
503505
let expected_ty = expected_input_tys[0];
504506
let provided_ty = final_arg_types[0].map(|ty| ty.0).unwrap();
507+
let expected_ty = self.resolve_vars_if_possible(expected_ty);
508+
let provided_ty = self.resolve_vars_if_possible(provided_ty);
505509
let cause = &self.misc(provided_args[0].span);
506510
let compatibility = demand_compatible(0, &mut final_arg_types);
507511
let type_error = match compatibility {
@@ -523,24 +527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
523527
format!("arguments to this {} are incorrect", call_name),
524528
);
525529
// Call out where the function is defined
526-
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
527-
let mut spans: MultiSpan = def_span.into();
528-
529-
let params = tcx
530-
.hir()
531-
.get_if_local(def_id)
532-
.and_then(|node| node.body_id())
533-
.into_iter()
534-
.map(|id| tcx.hir().body(id).params)
535-
.flatten();
536-
537-
for param in params {
538-
spans.push_span_label(param.span, String::new());
539-
}
540-
541-
let def_kind = tcx.def_kind(def_id);
542-
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
543-
}
530+
label_fn_like(tcx, &mut err, fn_def_id);
544531
err.emit();
545532
break 'errors;
546533
}
@@ -558,24 +545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
558545
DiagnosticId::Error(err_code.to_owned()),
559546
);
560547
// Call out where the function is defined
561-
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
562-
let mut spans: MultiSpan = def_span.into();
563-
564-
let params = tcx
565-
.hir()
566-
.get_if_local(def_id)
567-
.and_then(|node| node.body_id())
568-
.into_iter()
569-
.map(|id| tcx.hir().body(id).params)
570-
.flatten();
571-
572-
for param in params {
573-
spans.push_span_label(param.span, String::new());
574-
}
575-
576-
let def_kind = tcx.def_kind(def_id);
577-
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
578-
}
548+
label_fn_like(tcx, &mut err, fn_def_id);
579549
err.multipart_suggestion(
580550
"use parentheses to construct a tuple",
581551
vec![(start, '('.to_string()), (end, ')'.to_string())],
@@ -597,13 +567,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
597567
{
598568
let expected_ty = expected_input_tys[*input_idx];
599569
let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap();
570+
let expected_ty = self.resolve_vars_if_possible(expected_ty);
571+
let provided_ty = self.resolve_vars_if_possible(provided_ty);
600572
let cause = &self.misc(provided_args[*input_idx].span);
601573
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
602574
let mut err = self.report_and_explain_type_error(trace, error);
603575
self.emit_coerce_suggestions(
604576
&mut err,
605577
&provided_args[*input_idx],
606-
final_arg_types[*input_idx].map(|ty| ty.0).unwrap(),
578+
provided_ty,
607579
final_arg_types[*input_idx].map(|ty| ty.1).unwrap(),
608580
None,
609581
None,
@@ -613,24 +585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
613585
format!("arguments to this {} are incorrect", call_name),
614586
);
615587
// Call out where the function is defined
616-
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
617-
let mut spans: MultiSpan = def_span.into();
618-
619-
let params = tcx
620-
.hir()
621-
.get_if_local(def_id)
622-
.and_then(|node| node.body_id())
623-
.into_iter()
624-
.map(|id| tcx.hir().body(id).params)
625-
.flatten();
626-
627-
for param in params {
628-
spans.push_span_label(param.span, String::new());
629-
}
630-
631-
let def_kind = tcx.def_kind(def_id);
632-
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
633-
}
588+
label_fn_like(tcx, &mut err, fn_def_id);
634589
err.emit();
635590
break 'errors;
636591
}
@@ -678,12 +633,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
678633
match error {
679634
Error::Invalid(input_idx, compatibility) => {
680635
let expected_ty = expected_input_tys[input_idx];
636+
let provided_ty = final_arg_types
637+
.get(input_idx)
638+
.and_then(|x| x.as_ref())
639+
.map(|ty| ty.0)
640+
.unwrap_or(tcx.ty_error());
641+
let expected_ty = self.resolve_vars_if_possible(expected_ty);
642+
let provided_ty = self.resolve_vars_if_possible(provided_ty);
681643
if let Compatibility::Incompatible(error) = &compatibility {
682-
let provided_ty = final_arg_types
683-
.get(input_idx)
684-
.and_then(|x| x.as_ref())
685-
.map(|ty| ty.0)
686-
.unwrap_or(tcx.ty_error());
687644
let cause = &self.misc(
688645
provided_args.get(input_idx).map(|i| i.span).unwrap_or(call_span),
689646
);
@@ -948,24 +905,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
948905
}
949906

950907
// Call out where the function is defined
951-
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
952-
let mut spans: MultiSpan = def_span.into();
953-
954-
let params = tcx
955-
.hir()
956-
.get_if_local(def_id)
957-
.and_then(|node| node.body_id())
958-
.into_iter()
959-
.flat_map(|id| tcx.hir().body(id).params)
960-
;
961-
962-
for param in params {
963-
spans.push_span_label(param.span, String::new());
964-
}
965-
966-
let def_kind = tcx.def_kind(def_id);
967-
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
968-
}
908+
label_fn_like(tcx, &mut err, fn_def_id);
969909

970910
// And add a suggestion block for all of the parameters
971911
let suggestion_text = match suggestion_text {
@@ -1790,3 +1730,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17901730
}
17911731
}
17921732
}
1733+
1734+
fn label_fn_like<'tcx>(
1735+
tcx: TyCtxt<'tcx>,
1736+
err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
1737+
def_id: Option<DefId>,
1738+
) {
1739+
let Some(def_id) = def_id else {
1740+
return;
1741+
};
1742+
1743+
if let Some(def_span) = tcx.def_ident_span(def_id) {
1744+
let mut spans: MultiSpan = def_span.into();
1745+
1746+
let params = tcx
1747+
.hir()
1748+
.get_if_local(def_id)
1749+
.and_then(|node| node.body_id())
1750+
.into_iter()
1751+
.map(|id| tcx.hir().body(id).params)
1752+
.flatten();
1753+
1754+
for param in params {
1755+
spans.push_span_label(param.span, String::new());
1756+
}
1757+
1758+
let def_kind = tcx.def_kind(def_id);
1759+
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
1760+
} else {
1761+
match tcx.hir().get_if_local(def_id) {
1762+
Some(hir::Node::Expr(hir::Expr {
1763+
kind: hir::ExprKind::Closure(_, _, _, span, ..),
1764+
..
1765+
})) => {
1766+
let spans: MultiSpan = (*span).into();
1767+
1768+
// Note: We don't point to param spans here because they overlap
1769+
// with the closure span itself
1770+
1771+
err.span_note(spans, "closure defined here");
1772+
}
1773+
_ => {}
1774+
}
1775+
}
1776+
}

src/test/ui/argument-suggestions/basic.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ fn main() {
2222
missing(); //~ ERROR this function takes
2323
swapped("", 1); //~ ERROR arguments to this function are incorrect
2424
permuted(Y {}, Z {}, X {}); //~ ERROR arguments to this function are incorrect
25+
26+
let closure = |x| x;
27+
closure(); //~ ERROR this function takes
2528
}

src/test/ui/argument-suggestions/basic.stderr

+19-3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,23 @@ help: reorder these arguments
8181
LL | permuted(X {}, Y {}, Z {});
8282
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
8383

84-
error: aborting due to 5 previous errors
84+
error[E0057]: this function takes 1 argument but 0 arguments were supplied
85+
--> $DIR/basic.rs:27:5
86+
|
87+
LL | closure();
88+
| ^^^^^^^-- an argument is missing
89+
|
90+
note: closure defined here
91+
--> $DIR/basic.rs:26:19
92+
|
93+
LL | let closure = |x| x;
94+
| ^^^
95+
help: provide the argument
96+
|
97+
LL | closure({_});
98+
| ~~~~~~~~~~~~
99+
100+
error: aborting due to 6 previous errors
85101

86-
Some errors have detailed explanations: E0061, E0308.
87-
For more information about an error, try `rustc --explain E0061`.
102+
Some errors have detailed explanations: E0057, E0061, E0308.
103+
For more information about an error, try `rustc --explain E0057`.

src/test/ui/associated-types/associated-types-issue-20346.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ note: expected this to be `Option<T>`
1212
|
1313
LL | type Item = T;
1414
| ^
15-
= note: expected enum `Option<T>`
16-
found type `T`
15+
= note: expected enum `Option<T>`
16+
found type parameter `T`
1717
note: required by a bound in `is_iterator_of`
1818
--> $DIR/associated-types-issue-20346.rs:15:34
1919
|

src/test/ui/associated-types/higher-ranked-projection.bad.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | foo(());
55
| ^^^ lifetime mismatch
66
|
77
= note: expected reference `&'a ()`
8-
found type `&()`
8+
found reference `&()`
99
note: the lifetime requirement is introduced here
1010
--> $DIR/higher-ranked-projection.rs:15:33
1111
|

src/test/ui/async-await/generator-desc.stderr

+16-11
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,18 @@ LL | fun(one(), two());
2424
| |
2525
| arguments to this function are incorrect
2626
|
27+
note: while checking the return type of the `async fn`
28+
--> $DIR/generator-desc.rs:5:16
29+
|
30+
LL | async fn one() {}
31+
| ^ checked the `Output` of this `async fn`, expected opaque type
2732
note: while checking the return type of the `async fn`
2833
--> $DIR/generator-desc.rs:6:16
2934
|
3035
LL | async fn two() {}
3136
| ^ checked the `Output` of this `async fn`, found opaque type
32-
= note: expected type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>)
33-
found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>)
37+
= note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>)
38+
found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>)
3439
= help: consider `await`ing on both `Future`s
3540
= note: distinct uses of `impl Trait` result in different opaque types
3641
note: function defined here
@@ -43,26 +48,26 @@ error[E0308]: mismatched types
4348
--> $DIR/generator-desc.rs:14:26
4449
|
4550
LL | fun((async || {})(), (async || {})());
46-
| --- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
47-
| |
51+
| --- -- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
52+
| | |
53+
| | the expected `async` closure body
4854
| arguments to this function are incorrect
4955
|
5056
::: $SRC_DIR/core/src/future/mod.rs:LL:COL
5157
|
5258
LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
53-
| ------------------------------- the found opaque type
59+
| -------------------------------
60+
| |
61+
| the expected opaque type
62+
| the found opaque type
5463
|
55-
= note: expected type `impl Future<Output = ()>` (`async` closure body)
56-
found opaque type `impl Future<Output = ()>` (`async` closure body)
64+
= note: expected opaque type `impl Future<Output = ()>` (`async` closure body)
65+
found opaque type `impl Future<Output = ()>` (`async` closure body)
5766
note: function defined here
5867
--> $DIR/generator-desc.rs:8:4
5968
|
6069
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
6170
| ^^^ ----- -----
62-
help: consider `await`ing on the `Future`
63-
|
64-
LL | fun((async || {})(), (async || {})().await);
65-
| ++++++
6671

6772
error: aborting due to 3 previous errors
6873

0 commit comments

Comments
 (0)