From 4025e79c2c5fef8133641416fc140377f50aca16 Mon Sep 17 00:00:00 2001 From: Geoffrey Romer Date: Thu, 6 Feb 2025 10:29:00 -0800 Subject: [PATCH 1/2] Diagnose `var` in interfaces Previously this was ignored, and then #4720 accidentally made it a crash bug --- toolchain/check/handle_let_and_var.cpp | 6 +++ .../var/no_prelude/fail_in_interface.carbon | 41 +++++++++++++++++++ toolchain/diagnostics/diagnostic_kind.def | 1 + 3 files changed, 48 insertions(+) create mode 100644 toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon diff --git a/toolchain/check/handle_let_and_var.cpp b/toolchain/check/handle_let_and_var.cpp index ff18b32467f7f..5778d37d741a7 100644 --- a/toolchain/check/handle_let_and_var.cpp +++ b/toolchain/check/handle_let_and_var.cpp @@ -386,6 +386,12 @@ auto HandleParseNode(Context& context, Parse::VariableDeclId node_id) -> bool { } return true; } + if (context.GetCurrentScopeAs()) { + CARBON_DIAGNOSTIC(VarInInterfaceDecl, Error, + "interfaces cannot have `var` members"); + context.emitter().Emit(node_id, VarInInterfaceDecl); + return true; + } LocalPatternMatch(context, decl_info.pattern_id, decl_info.init_id); return true; diff --git a/toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon b/toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon new file mode 100644 index 0000000000000..5a218f3d98870 --- /dev/null +++ b/toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon @@ -0,0 +1,41 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon + +interface I { + // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:3: error: interfaces cannot have `var` members [VarInInterfaceDecl] + // CHECK:STDERR: var v: (); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: + var v: (); +} + +// CHECK:STDOUT: --- fail_in_interface.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [template] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%I.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .v = .inst20.loc12_7 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 4f14e04f078b3..2ff282f826b5e 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -272,6 +272,7 @@ CARBON_DIAGNOSTIC_KIND(ExportPrevious) // Interface checking. CARBON_DIAGNOSTIC_KIND(InterfaceForwardDeclaredHere) CARBON_DIAGNOSTIC_KIND(InterfaceUndefinedWithinDefinition) +CARBON_DIAGNOSTIC_KIND(VarInInterfaceDecl) // Impl checking. CARBON_DIAGNOSTIC_KIND(AssociatedConstantHere) From 14bf289c7fd8f71734796a6a6f83309d930ad943 Mon Sep 17 00:00:00 2001 From: Geoffrey Romer Date: Thu, 6 Feb 2025 11:12:10 -0800 Subject: [PATCH 2/2] Respond to reviewer commentsxsx --- toolchain/check/handle_let_and_var.cpp | 2 +- .../check/testdata/var/no_prelude/fail_in_interface.carbon | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/toolchain/check/handle_let_and_var.cpp b/toolchain/check/handle_let_and_var.cpp index 5778d37d741a7..d04076b3a41e8 100644 --- a/toolchain/check/handle_let_and_var.cpp +++ b/toolchain/check/handle_let_and_var.cpp @@ -388,7 +388,7 @@ auto HandleParseNode(Context& context, Parse::VariableDeclId node_id) -> bool { } if (context.GetCurrentScopeAs()) { CARBON_DIAGNOSTIC(VarInInterfaceDecl, Error, - "interfaces cannot have `var` members"); + "`var` declaration in interface"); context.emitter().Emit(node_id, VarInInterfaceDecl); return true; } diff --git a/toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon b/toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon index 5a218f3d98870..6c2c64fad526c 100644 --- a/toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon +++ b/toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon @@ -9,7 +9,7 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/var/no_prelude/fail_in_interface.carbon interface I { - // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:3: error: interfaces cannot have `var` members [VarInInterfaceDecl] + // CHECK:STDERR: fail_in_interface.carbon:[[@LINE+4]]:3: error: `var` declaration in interface [VarInInterfaceDecl] // CHECK:STDERR: var v: (); // CHECK:STDERR: ^~~~~~~~~~ // CHECK:STDERR: @@ -35,7 +35,7 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .v = .inst20.loc12_7 +// CHECK:STDOUT: .v = .inst20.loc16_7 // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: