Skip to content

Commit 416d3e7

Browse files
committed
1 parent e780264 commit 416d3e7

File tree

1 file changed

+49
-29
lines changed
  • compiler/rustc_typeck/src/check/fn_ctxt

1 file changed

+49
-29
lines changed

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

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
106106
// Expression of the call site
107107
call_expr: &'tcx hir::Expr<'tcx>,
108108
// Types (as defined in the *signature* of the target function)
109-
formal_input_tys: &[Ty<'tcx>],
109+
pr_formal_input_tys: &[Ty<'tcx>],
110110
// More specific expected types, after unifying with caller output types
111-
expected_input_tys: Vec<Ty<'tcx>>,
111+
pr_expected_input_tys: Vec<Ty<'tcx>>,
112112
// The expressions for each provided argument
113113
provided_args: &'tcx [hir::Expr<'tcx>],
114114
// Whether the function is variadic, for example when imported from C
@@ -118,6 +118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
118118
// The DefId for the function being called, for better error messages
119119
fn_def_id: Option<DefId>,
120120
) {
121+
let pr_expected_input_tys_cpy = pr_expected_input_tys.clone();
121122
let tcx = self.tcx;
122123
// Grab the argument types, supplying fresh type variables
123124
// if the wrong number of arguments were supplied
@@ -126,26 +127,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
126127

127128
// All the input types from the fn signature must outlive the call
128129
// so as to validate implied bounds.
129-
for (&fn_input_ty, arg_expr) in iter::zip(formal_input_tys, provided_args) {
130+
for (&fn_input_ty, arg_expr) in iter::zip(pr_formal_input_tys, provided_args) {
130131
self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
131132
}
132133

133-
let expected_arg_count = formal_input_tys.len();
134+
let expected_arg_count = pr_formal_input_tys.len();
134135

135136
// expected_count, arg_count, error_code, sugg_unit, sugg_tuple_wrap_args
136-
let mut error: Option<(usize, usize, &str, bool, Option<FnArgsAsTuple<'_>>)> = None;
137+
let mut error: Option<(usize, usize, &str, bool)> = None;
137138

138139
// If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
139140
let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
140-
let tuple_type = self.structurally_resolved_type(call_span, formal_input_tys[0]);
141+
let tuple_type = self.structurally_resolved_type(call_span, pr_formal_input_tys[0]);
141142
match tuple_type.kind() {
142143
// We expected a tuple and got a tuple
143144
ty::Tuple(arg_types) => {
144145
// Argument length differs
145146
if arg_types.len() != provided_args.len() {
146-
error = Some((arg_types.len(), provided_args.len(), "E0057", false, None));
147+
error = Some((arg_types.len(), provided_args.len(), "E0057", false));
147148
}
148-
let expected_input_tys = match expected_input_tys.get(0) {
149+
let expected_input_tys = match pr_expected_input_tys.get(0) {
149150
Some(&ty) => match ty.kind() {
150151
ty::Tuple(tys) => tys.iter().collect(),
151152
_ => vec![],
@@ -169,41 +170,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
169170
}
170171
}
171172
} else if expected_arg_count == supplied_arg_count {
172-
(formal_input_tys.to_vec(), expected_input_tys)
173+
(pr_formal_input_tys.to_vec(), pr_expected_input_tys)
173174
} else if c_variadic {
174175
if supplied_arg_count >= expected_arg_count {
175-
(formal_input_tys.to_vec(), expected_input_tys)
176+
(pr_formal_input_tys.to_vec(), pr_expected_input_tys)
176177
} else {
177-
error = Some((expected_arg_count, supplied_arg_count, "E0060", false, None));
178+
error = Some((expected_arg_count, supplied_arg_count, "E0060", false));
178179
(self.err_args(supplied_arg_count), vec![])
179180
}
180181
} else {
181182
// is the missing argument of type `()`?
182-
let sugg_unit = if expected_input_tys.len() == 1 && supplied_arg_count == 0 {
183-
self.resolve_vars_if_possible(expected_input_tys[0]).is_unit()
184-
} else if formal_input_tys.len() == 1 && supplied_arg_count == 0 {
185-
self.resolve_vars_if_possible(formal_input_tys[0]).is_unit()
183+
let sugg_unit = if pr_expected_input_tys.len() == 1 && supplied_arg_count == 0 {
184+
self.resolve_vars_if_possible(pr_expected_input_tys[0]).is_unit()
185+
} else if pr_formal_input_tys.len() == 1 && supplied_arg_count == 0 {
186+
self.resolve_vars_if_possible(pr_formal_input_tys[0]).is_unit()
186187
} else {
187188
false
188189
};
189190

190-
// are we passing elements of a tuple without the tuple parentheses?
191-
let expected_input_tys = if expected_input_tys.is_empty() {
192-
// In most cases we can use expected_input_tys, but some callers won't have the type
193-
// information, in which case we fall back to the types from the input expressions.
194-
formal_input_tys
195-
} else {
196-
&*expected_input_tys
197-
};
198-
199-
let sugg_tuple_wrap_args = self.suggested_tuple_wrap(expected_input_tys, provided_args);
200-
201191
error = Some((
202192
expected_arg_count,
203193
supplied_arg_count,
204194
"E0061",
205195
sugg_unit,
206-
sugg_tuple_wrap_args,
207196
));
208197
(self.err_args(supplied_arg_count), vec![])
209198
};
@@ -327,8 +316,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
327316
}
328317
}
329318

319+
// are we passing elements of a tuple without the tuple parentheses?
320+
let tuple_expected_input_tys = if pr_expected_input_tys_cpy.is_empty() {
321+
// In most cases we can use expected_input_tys, but some callers won't have the type
322+
// information, in which case we fall back to the types from the input expressions.
323+
pr_formal_input_tys
324+
} else {
325+
&*pr_expected_input_tys_cpy
326+
};
327+
328+
let suggest_tuple_wrap = if tuple_arguments != TupleArguments && expected_arg_count != supplied_arg_count && !c_variadic {
329+
self.suggested_tuple_wrap(tuple_expected_input_tys, provided_args)
330+
} else {
331+
None
332+
};
333+
330334
// If there was an error in parameter count, emit that here
331-
if let Some((expected_count, arg_count, err_code, sugg_unit, sugg_tuple_wrap_args)) = error
335+
if let (Some((expected_count, arg_count, err_code, sugg_unit)), sugg_tuple_wrap_args) = (error, suggest_tuple_wrap)
332336
{
333337
let (span, start_span, args, ctor_of) = match &call_expr.kind {
334338
hir::ExprKind::Call(
@@ -495,15 +499,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
495499
expected_input_tys: &[Ty<'tcx>],
496500
provided_args: &'tcx [hir::Expr<'tcx>],
497501
) -> Option<FnArgsAsTuple<'_>> {
502+
println!("checking tuple wrap!");
498503
let [expected_arg_type] = expected_input_tys[..] else { return None };
499504

500505
let &ty::Tuple(expected_types) = self.resolve_vars_if_possible(expected_arg_type).kind()
501506
else { return None };
507+
println!("resolved vars!");
508+
509+
let supplied_types: Vec<_> = provided_args.iter().map(|arg| /*self.resolve_vars_if_possible(arg)*/self.typeck_results.borrow().node_type(arg.hir_id)).collect(); // FIXME: Here is the issue!
502510

503-
let supplied_types: Vec<_> = provided_args.iter().map(|arg| self.check_expr(arg)).collect();
511+
println!("checked exprs!");
504512

505513
let all_match = iter::zip(expected_types, supplied_types)
506514
.all(|(expected, supplied)| self.can_eq(self.param_env, expected, supplied).is_ok());
515+
println!("can eq!");
516+
517+
/*
518+
let supplied_types: Vec<_> = provided_args.iter().enumerate().map(|arg| !self.check_expr_with_expectation(arg.1, Expectation::ExpectHasType(expected_types[arg.0])).references_error()).collect(); // FIXME: This is the issue!
519+
520+
println!("checked exprs!");
521+
522+
/*
523+
let all_match = iter::zip(expected_types, supplied_types)
524+
.all(|(expected, supplied)| self.can_eq(self.param_env, expected, supplied).is_ok());*/
525+
let all_match = supplied_types.into_iter().all(|x| x);
526+
*/
507527

508528
if all_match {
509529
match provided_args {

0 commit comments

Comments
 (0)