diff options
8 files changed, 221 insertions, 0 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index a887e20b0..d8e0b4320 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -332,6 +332,10 @@ impl InferenceTable { | |||
332 | | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), | 332 | | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), |
333 | _ => true, /* we checked equals_ctor already */ | 333 | _ => true, /* we checked equals_ctor already */ |
334 | } | 334 | } |
335 | } else if let (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) = | ||
336 | (ty1.kind(&Interner), ty2.kind(&Interner)) | ||
337 | { | ||
338 | self.unify_substs(substs1, substs2, depth + 1) | ||
335 | } else { | 339 | } else { |
336 | self.unify_inner_trivial(&ty1, &ty2, depth) | 340 | self.unify_inner_trivial(&ty1, &ty2, depth) |
337 | } | 341 | } |
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 5948d0bc2..0eefd70f2 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -1029,6 +1029,42 @@ fn infer_in_elseif() { | |||
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | #[test] | 1031 | #[test] |
1032 | fn infer_closure_unify() { | ||
1033 | check_infer( | ||
1034 | r#" | ||
1035 | fn foo(f: bool) { | ||
1036 | let a = |x| x; | ||
1037 | let b = |x| x; | ||
1038 | let id = if f { a } else { b }; | ||
1039 | id(123); | ||
1040 | } | ||
1041 | "#, | ||
1042 | expect![[r#" | ||
1043 | 7..8 'f': bool | ||
1044 | 16..106 '{ ...23); }': () | ||
1045 | 26..27 'a': |i32| -> i32 | ||
1046 | 30..35 '|x| x': |i32| -> i32 | ||
1047 | 31..32 'x': i32 | ||
1048 | 34..35 'x': i32 | ||
1049 | 45..46 'b': |i32| -> i32 | ||
1050 | 49..54 '|x| x': |i32| -> i32 | ||
1051 | 50..51 'x': i32 | ||
1052 | 53..54 'x': i32 | ||
1053 | 64..66 'id': |i32| -> i32 | ||
1054 | 69..90 'if f {... { b }': |i32| -> i32 | ||
1055 | 72..73 'f': bool | ||
1056 | 74..79 '{ a }': |i32| -> i32 | ||
1057 | 76..77 'a': |i32| -> i32 | ||
1058 | 85..90 '{ b }': |i32| -> i32 | ||
1059 | 87..88 'b': |i32| -> i32 | ||
1060 | 96..98 'id': |i32| -> i32 | ||
1061 | 96..103 'id(123)': i32 | ||
1062 | 99..102 '123': i32 | ||
1063 | "#]], | ||
1064 | ) | ||
1065 | } | ||
1066 | |||
1067 | #[test] | ||
1032 | fn infer_if_match_with_return() { | 1068 | fn infer_if_match_with_return() { |
1033 | check_infer( | 1069 | check_infer( |
1034 | r#" | 1070 | r#" |
diff --git a/crates/parser/src/grammar/type_args.rs b/crates/parser/src/grammar/type_args.rs index 42cd426bd..be36cad17 100644 --- a/crates/parser/src/grammar/type_args.rs +++ b/crates/parser/src/grammar/type_args.rs | |||
@@ -25,6 +25,38 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) { | |||
25 | m.complete(p, GENERIC_ARG_LIST); | 25 | m.complete(p, GENERIC_ARG_LIST); |
26 | } | 26 | } |
27 | 27 | ||
28 | pub(super) fn const_arg(p: &mut Parser) { | ||
29 | let m = p.start(); | ||
30 | // FIXME: duplicates the code below | ||
31 | match p.current() { | ||
32 | T!['{'] => { | ||
33 | expressions::block_expr(p); | ||
34 | m.complete(p, CONST_ARG); | ||
35 | } | ||
36 | k if k.is_literal() => { | ||
37 | expressions::literal(p); | ||
38 | m.complete(p, CONST_ARG); | ||
39 | } | ||
40 | T![true] | T![false] => { | ||
41 | expressions::literal(p); | ||
42 | m.complete(p, CONST_ARG); | ||
43 | } | ||
44 | T![-] => { | ||
45 | let lm = p.start(); | ||
46 | p.bump(T![-]); | ||
47 | expressions::literal(p); | ||
48 | lm.complete(p, PREFIX_EXPR); | ||
49 | m.complete(p, CONST_ARG); | ||
50 | } | ||
51 | _ => { | ||
52 | let lm = p.start(); | ||
53 | paths::use_path(p); | ||
54 | lm.complete(p, PATH_EXPR); | ||
55 | m.complete(p, CONST_ARG); | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
28 | // test type_arg | 60 | // test type_arg |
29 | // type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>; | 61 | // type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>; |
30 | fn generic_arg(p: &mut Parser) { | 62 | fn generic_arg(p: &mut Parser) { |
@@ -59,6 +91,15 @@ fn generic_arg(p: &mut Parser) { | |||
59 | expressions::literal(p); | 91 | expressions::literal(p); |
60 | m.complete(p, CONST_ARG); | 92 | m.complete(p, CONST_ARG); |
61 | } | 93 | } |
94 | // test const_generic_negated_literal | ||
95 | // fn f() { S::<-1> } | ||
96 | T![-] => { | ||
97 | let lm = p.start(); | ||
98 | p.bump(T![-]); | ||
99 | expressions::literal(p); | ||
100 | lm.complete(p, PREFIX_EXPR); | ||
101 | m.complete(p, CONST_ARG); | ||
102 | } | ||
62 | _ => { | 103 | _ => { |
63 | types::type_(p); | 104 | types::type_(p); |
64 | m.complete(p, TYPE_ARG); | 105 | m.complete(p, TYPE_ARG); |
diff --git a/crates/parser/src/grammar/type_params.rs b/crates/parser/src/grammar/type_params.rs index 3de5248da..b1f979281 100644 --- a/crates/parser/src/grammar/type_params.rs +++ b/crates/parser/src/grammar/type_params.rs | |||
@@ -70,6 +70,16 @@ fn const_param(p: &mut Parser, m: Marker) { | |||
70 | p.bump(T![const]); | 70 | p.bump(T![const]); |
71 | name(p); | 71 | name(p); |
72 | types::ascription(p); | 72 | types::ascription(p); |
73 | |||
74 | // test const_param_defaults | ||
75 | // struct A<const N: i32 = -1>; | ||
76 | // struct B<const N: i32 = {}>; | ||
77 | // struct C<const N: i32 = some::CONST>; | ||
78 | if p.at(T![=]) { | ||
79 | p.bump(T![=]); | ||
80 | type_args::const_arg(p); | ||
81 | } | ||
82 | |||
73 | m.complete(p, CONST_PARAM); | 83 | m.complete(p, CONST_PARAM); |
74 | } | 84 | } |
75 | 85 | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0164_const_generic_negated_literal.rast b/crates/syntax/test_data/parser/inline/ok/0164_const_generic_negated_literal.rast new file mode 100644 index 000000000..b20e523dc --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0164_const_generic_negated_literal.rast | |||
@@ -0,0 +1,30 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] "fn" | ||
4 | [email protected] " " | ||
5 | [email protected] | ||
6 | [email protected] "f" | ||
7 | [email protected] | ||
8 | [email protected] "(" | ||
9 | [email protected] ")" | ||
10 | [email protected] " " | ||
11 | [email protected] | ||
12 | [email protected] "{" | ||
13 | [email protected] " " | ||
14 | [email protected] | ||
15 | [email protected] | ||
16 | [email protected] | ||
17 | [email protected] | ||
18 | [email protected] "S" | ||
19 | [email protected] | ||
20 | [email protected] "::" | ||
21 | [email protected] "<" | ||
22 | [email protected] | ||
23 | [email protected] | ||
24 | [email protected] "-" | ||
25 | [email protected] | ||
26 | [email protected] "1" | ||
27 | [email protected] ">" | ||
28 | [email protected] " " | ||
29 | [email protected] "}" | ||
30 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0164_const_generic_negated_literal.rs b/crates/syntax/test_data/parser/inline/ok/0164_const_generic_negated_literal.rs new file mode 100644 index 000000000..8a81d05cd --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0164_const_generic_negated_literal.rs | |||
@@ -0,0 +1 @@ | |||
fn f() { S::<-1> } | |||
diff --git a/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rast b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rast new file mode 100644 index 000000000..e8f40a4cd --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rast | |||
@@ -0,0 +1,96 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] "struct" | ||
4 | [email protected] " " | ||
5 | [email protected] | ||
6 | [email protected] "A" | ||
7 | [email protected] | ||
8 | [email protected] "<" | ||
9 | [email protected] | ||
10 | [email protected] "const" | ||
11 | [email protected] " " | ||
12 | [email protected] | ||
13 | [email protected] "N" | ||
14 | [email protected] ":" | ||
15 | [email protected] " " | ||
16 | [email protected] | ||
17 | [email protected] | ||
18 | [email protected] | ||
19 | [email protected] | ||
20 | [email protected] "i32" | ||
21 | [email protected] " " | ||
22 | [email protected] "=" | ||
23 | [email protected] " " | ||
24 | [email protected] | ||
25 | [email protected] | ||
26 | [email protected] "-" | ||
27 | [email protected] | ||
28 | [email protected] "1" | ||
29 | [email protected] ">" | ||
30 | [email protected] ";" | ||
31 | [email protected] "\n" | ||
32 | [email protected] | ||
33 | [email protected] "struct" | ||
34 | [email protected] " " | ||
35 | [email protected] | ||
36 | [email protected] "B" | ||
37 | [email protected] | ||
38 | [email protected] "<" | ||
39 | [email protected] | ||
40 | [email protected] "const" | ||
41 | [email protected] " " | ||
42 | [email protected] | ||
43 | [email protected] "N" | ||
44 | [email protected] ":" | ||
45 | [email protected] " " | ||
46 | [email protected] | ||
47 | [email protected] | ||
48 | [email protected] | ||
49 | [email protected] | ||
50 | [email protected] "i32" | ||
51 | [email protected] " " | ||
52 | [email protected] "=" | ||
53 | [email protected] " " | ||
54 | [email protected] | ||
55 | [email protected] | ||
56 | [email protected] "{" | ||
57 | [email protected] "}" | ||
58 | [email protected] ">" | ||
59 | [email protected] ";" | ||
60 | [email protected] "\n" | ||
61 | [email protected] | ||
62 | [email protected] "struct" | ||
63 | [email protected] " " | ||
64 | [email protected] | ||
65 | [email protected] "C" | ||
66 | [email protected] | ||
67 | [email protected] "<" | ||
68 | [email protected] | ||
69 | [email protected] "const" | ||
70 | [email protected] " " | ||
71 | [email protected] | ||
72 | [email protected] "N" | ||
73 | [email protected] ":" | ||
74 | [email protected] " " | ||
75 | [email protected] | ||
76 | [email protected] | ||
77 | [email protected] | ||
78 | [email protected] | ||
79 | [email protected] "i32" | ||
80 | [email protected] " " | ||
81 | [email protected] "=" | ||
82 | [email protected] " " | ||
83 | [email protected] | ||
84 | [email protected] | ||
85 | [email protected] | ||
86 | [email protected] | ||
87 | [email protected] | ||
88 | [email protected] | ||
89 | [email protected] "some" | ||
90 | [email protected] "::" | ||
91 | [email protected] | ||
92 | [email protected] | ||
93 | [email protected] "CONST" | ||
94 | [email protected] ">" | ||
95 | [email protected] ";" | ||
96 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rs b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rs new file mode 100644 index 000000000..68388c8fb --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | struct A<const N: i32 = -1>; | ||
2 | struct B<const N: i32 = {}>; | ||
3 | struct C<const N: i32 = some::CONST>; | ||