diff --git a/toolchain/check/testdata/function/declaration/fail_todo_no_params.carbon b/toolchain/check/testdata/function/declaration/fail_todo_no_params.carbon index af631ea5cda3..ad784c0dd94b 100644 --- a/toolchain/check/testdata/function/declaration/fail_todo_no_params.carbon +++ b/toolchain/check/testdata/function/declaration/fail_todo_no_params.carbon @@ -71,7 +71,7 @@ library "[[@TEST_NAME]]"; // CHECK:STDERR: var x:! () = (); // CHECK:STDERR: ^~~~~~ // CHECK:STDERR: -// CHECK:STDERR: fail_invalid_file_generic_regression_test.carbon:[[@LINE+4]]:12: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] +// CHECK:STDERR: fail_invalid_file_generic_regression_test.carbon:[[@LINE+4]]:12: error: found `:!` pattern inside `var` pattern [NonRegularBindingInVarDecl] // CHECK:STDERR: var x:! () = (); // CHECK:STDERR: ^ // CHECK:STDERR: diff --git a/toolchain/check/testdata/var/fail_generic.carbon b/toolchain/check/testdata/var/fail_generic.carbon index eff9a366ae6b..0476ebc7962b 100644 --- a/toolchain/check/testdata/var/fail_generic.carbon +++ b/toolchain/check/testdata/var/fail_generic.carbon @@ -17,7 +17,7 @@ fn Main() { // CHECK:STDERR: var x:! () = (); // CHECK:STDERR: ^~~~~~ // CHECK:STDERR: - // CHECK:STDERR: fail_generic.carbon:[[@LINE+4]]:14: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] + // CHECK:STDERR: fail_generic.carbon:[[@LINE+4]]:14: error: found `:!` pattern inside `var` pattern [NonRegularBindingInVarDecl] // CHECK:STDERR: var x:! () = (); // CHECK:STDERR: ^ // CHECK:STDERR: diff --git a/toolchain/check/testdata/var/var_pattern.carbon b/toolchain/check/testdata/var/var_pattern.carbon index e064d9a1c0fd..2d4a23c7dea1 100644 --- a/toolchain/check/testdata/var/var_pattern.carbon +++ b/toolchain/check/testdata/var/var_pattern.carbon @@ -98,7 +98,7 @@ fn f() { // CHECK:STDERR: var T:! type; // CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: - // CHECK:STDERR: fail_compile_time.carbon:[[@LINE+4]]:15: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] + // CHECK:STDERR: fail_compile_time.carbon:[[@LINE+4]]:15: error: found `:!` pattern inside `var` pattern [NonRegularBindingInVarDecl] // CHECK:STDERR: var T:! type; // CHECK:STDERR: ^ // CHECK:STDERR: @@ -120,7 +120,7 @@ fn F[var u: ()](); // CHECK:STDERR: fn G[var T:! type](); // CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: -// CHECK:STDERR: fail_implicit.carbon:[[@LINE+4]]:18: error: `var` pattern cannot declare a compile-time binding [CompileTimeBindingInVarDecl] +// CHECK:STDERR: fail_implicit.carbon:[[@LINE+4]]:18: error: found `:!` pattern inside `var` pattern [NonRegularBindingInVarDecl] // CHECK:STDERR: fn G[var T:! type](); // CHECK:STDERR: ^ // CHECK:STDERR: diff --git a/toolchain/diagnostics/kind.def b/toolchain/diagnostics/kind.def index 8ab22855b9cd..e9932203349f 100644 --- a/toolchain/diagnostics/kind.def +++ b/toolchain/diagnostics/kind.def @@ -434,7 +434,6 @@ CARBON_DIAGNOSTIC_KIND(CoreNameNotFound) CARBON_DIAGNOSTIC_KIND(CoreNotFound) CARBON_DIAGNOSTIC_KIND(DerefOfNonPointer) CARBON_DIAGNOSTIC_KIND(DerefOfType) -CARBON_DIAGNOSTIC_KIND(CompileTimeBindingInVarDecl) CARBON_DIAGNOSTIC_KIND(CompoundMemberAccessDoesNotUseBase) CARBON_DIAGNOSTIC_KIND(EvalRequiresConstantValue) CARBON_DIAGNOSTIC_KIND(FormExprEvaluationFailure) @@ -466,6 +465,7 @@ CARBON_DIAGNOSTIC_KIND(IntWidthTooLarge) CARBON_DIAGNOSTIC_KIND(InvalidArrayExpr) CARBON_DIAGNOSTIC_KIND(NegativeIntInUnsignedType) CARBON_DIAGNOSTIC_KIND(NonConstantCallToCompTimeOnlyFunction) +CARBON_DIAGNOSTIC_KIND(NonRegularBindingInVarDecl) CARBON_DIAGNOSTIC_KIND(CompTimeOnlyFunctionHere) CARBON_DIAGNOSTIC_KIND(SelfOutsideImplicitParamList) CARBON_DIAGNOSTIC_KIND(StringAtIndexOutOfBounds) diff --git a/toolchain/parse/handle_binding_pattern.cpp b/toolchain/parse/handle_binding_pattern.cpp index 98267fe386ab..4777c34c985f 100644 --- a/toolchain/parse/handle_binding_pattern.cpp +++ b/toolchain/parse/handle_binding_pattern.cpp @@ -112,7 +112,7 @@ auto HandleBindingPattern(Context& context) -> void { } } -// Handles BindingPatternFinishAs(Generic|Regular). +// Handles BindingPatternFinishAs(Generic|Regular|Form). static auto HandleBindingPatternFinish(Context& context, StateKind finish_kind) -> void { auto state = context.PopState(); @@ -120,10 +120,13 @@ static auto HandleBindingPatternFinish(Context& context, StateKind finish_kind) auto node_kind = NodeKind::InvalidParse; if (state.in_var_pattern) { node_kind = NodeKind::VarBindingPattern; - if (finish_kind == StateKind::BindingPatternFinishAsGeneric) { - CARBON_DIAGNOSTIC(CompileTimeBindingInVarDecl, Error, - "`var` pattern cannot declare a compile-time binding"); - context.emitter().Emit(*context.position(), CompileTimeBindingInVarDecl); + if (finish_kind != StateKind::BindingPatternFinishAsRegular) { + CARBON_DIAGNOSTIC(NonRegularBindingInVarDecl, Error, + "found {0:`:!`|`:?`} pattern inside `var` pattern", + Diagnostics::BoolAsSelect); + context.emitter().Emit( + *context.position(), NonRegularBindingInVarDecl, + finish_kind == StateKind::BindingPatternFinishAsGeneric); state.has_error = true; } } else { diff --git a/toolchain/parse/testdata/function/declaration.carbon b/toolchain/parse/testdata/function/declaration.carbon index 342913304402..317f8fc65688 100644 --- a/toolchain/parse/testdata/function/declaration.carbon +++ b/toolchain/parse/testdata/function/declaration.carbon @@ -175,6 +175,14 @@ fn ComplexFormParam(x:? X.Y(Z)); // CHECK:STDERR: fn F(ref x:? Form); +// --- fail_form_within_var.carbon + +// CHECK:STDERR: fail_form_within_var.carbon:[[@LINE+4]]:26: error: found `:?` pattern inside `var` pattern [NonRegularBindingInVarDecl] +// CHECK:STDERR: fn FormInVar(var x:? Form); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn FormInVar(var x:? Form); + // --- return_form.carbon fn SimpleReturnForm() ->? Form; @@ -479,6 +487,20 @@ fn ComplexReturnForm() ->? X.Y(Z); // CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 9}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: fail_form_within_var.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameMaybeBeforeSignature', text: 'FormInVar'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'x'}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Form'}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':?', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', has_error: yes, subtree_size: 4}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] // CHECK:STDOUT: - filename: return_form.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''},