parent
30658b25d2
commit
6f67a46a6a
@ -140,13 +140,13 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
|
||||
let mut sig_tys = Vec::new();
|
||||
|
||||
for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) {
|
||||
let expected = if let Some(type_ref) = arg_type {
|
||||
// collect explicitly written argument types
|
||||
for arg_type in arg_types.iter() {
|
||||
let arg_ty = if let Some(type_ref) = arg_type {
|
||||
self.make_ty(type_ref)
|
||||
} else {
|
||||
Ty::Unknown
|
||||
self.table.new_type_var()
|
||||
};
|
||||
let arg_ty = self.infer_pat(*arg_pat, &expected, BindingMode::default());
|
||||
sig_tys.push(arg_ty);
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
sig_tys.push(ret_ty.clone());
|
||||
let sig_ty = Ty::apply(
|
||||
TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 },
|
||||
Substs(sig_tys.into()),
|
||||
Substs(sig_tys.clone().into()),
|
||||
);
|
||||
let closure_ty =
|
||||
Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty);
|
||||
@ -168,6 +168,12 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
// infer the body.
|
||||
self.coerce(&closure_ty, &expected.ty);
|
||||
|
||||
// Now go through the argument patterns
|
||||
for (arg_pat, arg_ty) in args.iter().zip(sig_tys) {
|
||||
let resolved = self.resolve_ty_as_possible(arg_ty);
|
||||
self.infer_pat(*arg_pat, &resolved, BindingMode::default());
|
||||
}
|
||||
|
||||
let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
|
||||
let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
|
||||
|
||||
|
@ -520,3 +520,53 @@ fn main() {
|
||||
105..107 '()': ()
|
||||
")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_ergonomics_in_closure_params() {
|
||||
assert_snapshot!(
|
||||
infer(r#"
|
||||
#[lang = "fn_once"]
|
||||
trait FnOnce<Args> {
|
||||
type Output;
|
||||
}
|
||||
|
||||
fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
|
||||
|
||||
fn test() {
|
||||
foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
|
||||
foo(&(1, "a"), |(x, y)| x);
|
||||
}
|
||||
"#),
|
||||
@r###"
|
||||
94..95 't': T
|
||||
100..101 'f': F
|
||||
111..122 '{ loop {} }': U
|
||||
113..120 'loop {}': !
|
||||
118..120 '{}': ()
|
||||
134..233 '{ ... x); }': ()
|
||||
140..143 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
|
||||
140..167 'foo(&(...y)| x)': i32
|
||||
144..153 '&(1, "a")': &(i32, &str)
|
||||
145..153 '(1, "a")': (i32, &str)
|
||||
146..147 '1': i32
|
||||
149..152 '"a"': &str
|
||||
155..166 '|&(x, y)| x': |&(i32, &str)| -> i32
|
||||
156..163 '&(x, y)': &(i32, &str)
|
||||
157..163 '(x, y)': (i32, &str)
|
||||
158..159 'x': i32
|
||||
161..162 'y': &str
|
||||
165..166 'x': i32
|
||||
204..207 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
|
||||
204..230 'foo(&(...y)| x)': &i32
|
||||
208..217 '&(1, "a")': &(i32, &str)
|
||||
209..217 '(1, "a")': (i32, &str)
|
||||
210..211 '1': i32
|
||||
213..216 '"a"': &str
|
||||
219..229 '|(x, y)| x': |&(i32, &str)| -> &i32
|
||||
220..226 '(x, y)': (i32, &str)
|
||||
221..222 'x': &i32
|
||||
224..225 'y': &&str
|
||||
228..229 'x': &i32
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user