Skip to content

Commit f70221c

Browse files
authored
Fix deduction crash for function with missing parameters. (#4461)
This is because `var x:! () = ();` modifies the binding index, which causes `A` to be generic, which causes the params to be used, which crashes. There may be another issue to fix here so that the invalid binding doesn't modify the binding index, but at least `param_patterns_id` should probably be set consistently with `params_id`.
1 parent 85f6bf3 commit f70221c

File tree

2 files changed

+75
-5
lines changed

2 files changed

+75
-5
lines changed

toolchain/check/handle_function.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,10 @@ static auto BuildFunctionDecl(Context& context,
183183

184184
auto name = PopNameComponent(context, return_slot_pattern_id);
185185
if (!name.params_id.is_valid()) {
186+
CARBON_CHECK(!name.param_patterns_id.is_valid());
186187
context.TODO(node_id, "function with positional parameters");
187188
name.params_id = SemIR::InstBlockId::Empty;
189+
name.param_patterns_id = SemIR::InstBlockId::Empty;
188190
}
189191

190192
auto name_context = context.decl_name_stack().FinishName(name);

toolchain/check/testdata/function/declaration/no_prelude/fail_todo_no_params.carbon

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,40 @@ fn A {
3131

3232
// TODO: We don't have parsing support for this yet.
3333
library "[[@TEST_NAME]]";
34-
// CHECK:STDERR: fail_todo_arrow_body.carbon:[[@LINE+7]]:1: error: semantics TODO: `function with positional parameters` [SemanticsTodo]
34+
// CHECK:STDERR: fail_todo_arrow_body.carbon:[[@LINE+8]]:1: error: semantics TODO: `function with positional parameters` [SemanticsTodo]
3535
// CHECK:STDERR: fn A => 0;
3636
// CHECK:STDERR: ^~~~~~~~~~
3737
// CHECK:STDERR:
38-
// CHECK:STDERR: fail_todo_arrow_body.carbon:[[@LINE+3]]:6: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition]
38+
// CHECK:STDERR: fail_todo_arrow_body.carbon:[[@LINE+4]]:6: error: `fn` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition]
3939
// CHECK:STDERR: fn A => 0;
4040
// CHECK:STDERR: ^~
41+
// CHECK:STDERR:
4142
fn A => 0;
4243

44+
// --- fail_invalid_file_generic_regression_test.carbon
45+
46+
library "[[@TEST_NAME]]";
47+
48+
// CHECK:STDERR: fail_invalid_file_generic_regression_test.carbon:[[@LINE+4]]:9: error: `var` declaration cannot declare a compile-time binding [CompileTimeBindingInVarDecl]
49+
// CHECK:STDERR: var x:! () = ();
50+
// CHECK:STDERR: ^~
51+
// CHECK:STDERR:
52+
var x:! () = ();
53+
54+
// CHECK:STDERR: fail_invalid_file_generic_regression_test.carbon:[[@LINE+4]]:1: error: semantics TODO: `function with positional parameters` [SemanticsTodo]
55+
// CHECK:STDERR: fn A {
56+
// CHECK:STDERR: ^~~~~~
57+
// CHECK:STDERR:
58+
fn A {
59+
// CHECK:STDERR: fail_invalid_file_generic_regression_test.carbon:[[@LINE+6]]:3: error: cannot deduce value for generic parameter `x` [DeductionIncomplete]
60+
// CHECK:STDERR: A();
61+
// CHECK:STDERR: ^~
62+
// CHECK:STDERR: fail_invalid_file_generic_regression_test.carbon:[[@LINE-4]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
63+
// CHECK:STDERR: fn A {
64+
// CHECK:STDERR: ^~~~~~
65+
A();
66+
}
67+
4368
// CHECK:STDOUT: --- fail_no_body.carbon
4469
// CHECK:STDOUT:
4570
// CHECK:STDOUT: constants {
@@ -55,7 +80,7 @@ fn A => 0;
5580
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [template = constants.%A] {} {}
5681
// CHECK:STDOUT: }
5782
// CHECK:STDOUT:
58-
// CHECK:STDOUT: fn @A;
83+
// CHECK:STDOUT: fn @A();
5984
// CHECK:STDOUT:
6085
// CHECK:STDOUT: --- fail_todo_brace_body.carbon
6186
// CHECK:STDOUT:
@@ -72,7 +97,7 @@ fn A => 0;
7297
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [template = constants.%A] {} {}
7398
// CHECK:STDOUT: }
7499
// CHECK:STDOUT:
75-
// CHECK:STDOUT: fn @A {
100+
// CHECK:STDOUT: fn @A() {
76101
// CHECK:STDOUT: !entry:
77102
// CHECK:STDOUT: return
78103
// CHECK:STDOUT: }
@@ -92,5 +117,48 @@ fn A => 0;
92117
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [template = constants.%A] {} {}
93118
// CHECK:STDOUT: }
94119
// CHECK:STDOUT:
95-
// CHECK:STDOUT: fn @A;
120+
// CHECK:STDOUT: fn @A();
121+
// CHECK:STDOUT:
122+
// CHECK:STDOUT: --- fail_invalid_file_generic_regression_test.carbon
123+
// CHECK:STDOUT:
124+
// CHECK:STDOUT: constants {
125+
// CHECK:STDOUT: %.1: type = tuple_type () [template]
126+
// CHECK:STDOUT: %x: %.1 = bind_symbolic_name x, 0 [symbolic]
127+
// CHECK:STDOUT: %tuple: %.1 = tuple_value () [template]
128+
// CHECK:STDOUT: %A.type: type = fn_type @A [template]
129+
// CHECK:STDOUT: %A: %A.type = struct_value () [template]
130+
// CHECK:STDOUT: }
131+
// CHECK:STDOUT:
132+
// CHECK:STDOUT: file {
133+
// CHECK:STDOUT: package: <namespace> = namespace [template] {
134+
// CHECK:STDOUT: .x = %x
135+
// CHECK:STDOUT: .A = %A.decl
136+
// CHECK:STDOUT: }
137+
// CHECK:STDOUT: %.loc8_10.1: %.1 = tuple_literal ()
138+
// CHECK:STDOUT: %.loc8_10.2: type = converted %.loc8_10.1, constants.%.1 [template = constants.%.1]
139+
// CHECK:STDOUT: %x.var: ref %.1 = var x
140+
// CHECK:STDOUT: %x: %.1 = bind_symbolic_name x, 0, %x.var [symbolic = constants.%x]
141+
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [template = constants.%A] {} {}
142+
// CHECK:STDOUT: }
143+
// CHECK:STDOUT:
144+
// CHECK:STDOUT: generic fn @A(file.%x: %.1) {
145+
// CHECK:STDOUT: !definition:
146+
// CHECK:STDOUT:
147+
// CHECK:STDOUT: fn() {
148+
// CHECK:STDOUT: !entry:
149+
// CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [template = constants.%A]
150+
// CHECK:STDOUT: return
151+
// CHECK:STDOUT: }
152+
// CHECK:STDOUT: }
153+
// CHECK:STDOUT:
154+
// CHECK:STDOUT: fn @__global_init() {
155+
// CHECK:STDOUT: !entry:
156+
// CHECK:STDOUT: %.loc8_15.1: %.1 = tuple_literal ()
157+
// CHECK:STDOUT: %.loc8_15.2: init %.1 = tuple_init () to file.%x.var [template = constants.%tuple]
158+
// CHECK:STDOUT: %.loc8_16: init %.1 = converted %.loc8_15.1, %.loc8_15.2 [template = constants.%tuple]
159+
// CHECK:STDOUT: assign file.%x.var, %.loc8_16
160+
// CHECK:STDOUT: return
161+
// CHECK:STDOUT: }
162+
// CHECK:STDOUT:
163+
// CHECK:STDOUT: specific @A(constants.%x) {}
96164
// CHECK:STDOUT:

0 commit comments

Comments
 (0)