Add diagnostic coverage, remove possibly-unreachable unary op diagnostic (#4519)

I'm working to make sure remaining diagnostics have coverage, at least
the ones I'd previously added a TODO for. Note in particular that I
couldn't figure out a repro for UnaryOperatorRequiresWhitespace; if you
have one, I can add a test, but otherwise maybe it's actually
unreachable due to being diagnosed through infix logic (or, maybe
this'll let fuzzing tell me an example).
This commit is contained in:
Jon Ross-Perkins
2024-11-13 18:04:25 +00:00
committed by GitHub
parent 3ba4997855
commit fa95892a37
10 changed files with 478 additions and 43 deletions
@@ -58,12 +58,28 @@ class C {
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
extern fn F();
// CHECK:STDERR: fail_member_extern.carbon:[[@LINE+3]]:3: error: `extern` not allowed; requires file or namespace scope [ModifierExternNotAllowed]
// CHECK:STDERR: fail_member_extern.carbon:[[@LINE+4]]:3: error: `extern` not allowed; requires file or namespace scope [ModifierExternNotAllowed]
// CHECK:STDERR: extern fn G[self: Self]();
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
extern fn G[self: Self]();
}
// --- fail_extern_library_in_importer.carbon
library "[[@TEST_NAME]]";
import library "basic";
// CHECK:STDERR: fail_extern_library_in_importer.carbon:[[@LINE+7]]:1: error: cannot declare imported `fn F` as `extern library` [ExternLibraryInImporter]
// CHECK:STDERR: extern library "basic" fn F();
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_extern_library_in_importer.carbon:[[@LINE-5]]:1: in import [InImport]
// CHECK:STDERR: basic.carbon:4:1: note: previously declared here [RedeclPrevDecl]
// CHECK:STDERR: extern fn F();
// CHECK:STDERR: ^~~~~~~~~~~~~~
extern library "basic" fn F();
// CHECK:STDOUT: --- basic.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -181,7 +197,7 @@ class C {
// CHECK:STDOUT: %self.param: %C = value_param runtime_param0
// CHECK:STDOUT: %self: %C = bind_name self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc14: <witness> = complete_type_witness %.1 [template = constants.%.2]
// CHECK:STDOUT: %.loc15: <witness> = complete_type_witness %.1 [template = constants.%.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
@@ -193,3 +209,25 @@ class C {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G[%self.param_patt: %C]();
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_extern_library_in_importer.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %import_ref: %F.type = import_ref Main//basic, inst+1, loaded [template = constants.%F]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .F = invalid
// CHECK:STDOUT: }
// CHECK:STDOUT: %default.import = import <invalid>
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: extern fn @F();
// CHECK:STDOUT:
@@ -132,15 +132,25 @@ library "[[@TEST_NAME]]";
import library "extern_of_import";
// CHECK:STDERR: fail_extern_of_import_redecl.carbon:[[@LINE+7]]:1: error: redeclarations of `fn F` must match use of `extern` [RedeclExternMismatch]
// CHECK:STDERR: fail_extern_of_import_redecl.carbon:[[@LINE+8]]:1: error: redeclarations of `fn F` must match use of `extern` [RedeclExternMismatch]
// CHECK:STDERR: extern library "extern_of_import" fn F();
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_extern_of_import_redecl.carbon:[[@LINE-5]]:1: in import [InImport]
// CHECK:STDERR: extern_of_import.carbon:4:1: note: previously declared here [RedeclPrevDecl]
// CHECK:STDERR: fn F();
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
extern library "extern_of_import" fn F();
// --- fail_extern_library_on_definition.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_extern_library_on_definition.carbon:[[@LINE+3]]:1: error: a library cannot be provided for an `extern` modifier on a definition [ExternLibraryOnDefinition]
// CHECK:STDERR: extern library "extern_library_owner" fn F() {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
extern library "extern_library_owner" fn F() {}
// CHECK:STDOUT: --- extern_library.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -367,3 +377,23 @@ extern library "extern_of_import" fn F();
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F();
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_extern_library_on_definition.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: extern fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -0,0 +1,55 @@
// 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/function/definition/no_prelude/basics.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/definition/no_prelude/basics.carbon
// --- fail_incomplete_type.carbon
class C;
// CHECK:STDERR: fail_incomplete_type.carbon:[[@LINE+6]]:6: error: parameter has incomplete type `C` in function definition [IncompleteTypeInFunctionParam]
// CHECK:STDERR: fn F(n: C) {}
// CHECK:STDERR: ^~~~
// CHECK:STDERR: fail_incomplete_type.carbon:[[@LINE-5]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
// CHECK:STDERR: class C;
// CHECK:STDERR: ^~~~~~~~
fn F(n: C) {}
// CHECK:STDOUT: --- fail_incomplete_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .C = %C.decl
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} {}
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
// CHECK:STDOUT: %n.patt: %C = binding_pattern n
// CHECK:STDOUT: %n.param_patt: %C = value_param_pattern %n.patt, runtime_param0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
// CHECK:STDOUT: %n.param: %C = value_param runtime_param0
// CHECK:STDOUT: %n: %C = bind_name n, %n.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C;
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%n.param_patt: %C) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -8,72 +8,240 @@
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/no_prelude/fail_modifiers.carbon
// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:1: error: `abstract` not allowed on `interface` declaration [ModifierNotAllowedOnDeclaration]
// --- fail_abstract.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_abstract.carbon:[[@LINE+4]]:1: error: `abstract` not allowed on `interface` declaration [ModifierNotAllowedOnDeclaration]
// CHECK:STDERR: abstract interface Abstract {
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR:
abstract interface Abstract {
}
// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:1: error: `default` not allowed on `interface` declaration [ModifierNotAllowedOnDeclaration]
// --- fail_default.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_default.carbon:[[@LINE+4]]:1: error: `default` not allowed on `interface` declaration [ModifierNotAllowedOnDeclaration]
// CHECK:STDERR: default interface Default;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
default interface Default;
// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:1: error: `virtual` not allowed on `interface` declaration [ModifierNotAllowedOnDeclaration]
// --- fail_virtual.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_virtual.carbon:[[@LINE+4]]:1: error: `virtual` not allowed on `interface` declaration [ModifierNotAllowedOnDeclaration]
// CHECK:STDERR: virtual interface Virtual {
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
virtual interface Virtual {
}
// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+3]]:1: error: `protected` not allowed; requires class scope [ModifierProtectedNotAllowed]
// --- fail_protected.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_protected.carbon:[[@LINE+4]]:1: error: `protected` not allowed; requires class scope [ModifierProtectedNotAllowed]
// CHECK:STDERR: protected interface Protected;
// CHECK:STDERR: ^~~~~~~~~
// CHECK:STDERR:
protected interface Protected;
// CHECK:STDOUT: --- fail_modifiers.carbon
// --- fail_private_member.carbon
library "[[@TEST_NAME]]";
interface I {
// CHECK:STDERR: fail_private_member.carbon:[[@LINE+4]]:3: error: `private` not allowed; requires class or file scope [ModifierPrivateNotAllowed]
// CHECK:STDERR: private fn F[self: Self]();
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
private fn F[self: Self]();
}
// --- fail_protected_member.carbon
library "[[@TEST_NAME]]";
interface I {
// CHECK:STDERR: fail_protected_member.carbon:[[@LINE+3]]:3: error: `protected` not allowed; requires class scope [ModifierProtectedNotAllowed]
// CHECK:STDERR: protected fn F[self: Self]();
// CHECK:STDERR: ^~~~~~~~~
protected fn F[self: Self]();
}
// CHECK:STDOUT: --- fail_abstract.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Abstract.type: type = facet_type <@Abstract> [template]
// CHECK:STDOUT: %Self.1: %Abstract.type = bind_symbolic_name Self, 0 [symbolic]
// CHECK:STDOUT: %Default.type: type = facet_type <@Default> [template]
// CHECK:STDOUT: %Virtual.type: type = facet_type <@Virtual> [template]
// CHECK:STDOUT: %Self.2: %Virtual.type = bind_symbolic_name Self, 0 [symbolic]
// CHECK:STDOUT: %Protected.type: type = facet_type <@Protected> [template]
// CHECK:STDOUT: %Self: %Abstract.type = bind_symbolic_name Self, 0 [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Abstract = %Abstract.decl
// CHECK:STDOUT: .Default = %Default.decl
// CHECK:STDOUT: .Virtual = %Virtual.decl
// CHECK:STDOUT: .Protected = %Protected.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %Abstract.decl: type = interface_decl @Abstract [template = constants.%Abstract.type] {} {}
// CHECK:STDOUT: %Default.decl: type = interface_decl @Default [template = constants.%Default.type] {} {}
// CHECK:STDOUT: %Virtual.decl: type = interface_decl @Virtual [template = constants.%Virtual.type] {} {}
// CHECK:STDOUT: %Protected.decl: type = interface_decl @Protected [template = constants.%Protected.type] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Abstract {
// CHECK:STDOUT: %Self: %Abstract.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.1]
// CHECK:STDOUT: %Self: %Abstract.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_default.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Default.type: type = facet_type <@Default> [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Default = %Default.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %Default.decl: type = interface_decl @Default [template = constants.%Default.type] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Default;
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_virtual.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Virtual.type: type = facet_type <@Virtual> [template]
// CHECK:STDOUT: %Self: %Virtual.type = bind_symbolic_name Self, 0 [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Virtual = %Virtual.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %Virtual.decl: type = interface_decl @Virtual [template = constants.%Virtual.type] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Virtual {
// CHECK:STDOUT: %Self: %Virtual.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.2]
// CHECK:STDOUT: %Self: %Virtual.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_protected.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Protected.type: type = facet_type <@Protected> [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Protected = %Protected.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %Protected.decl: type = interface_decl @Protected [template = constants.%Protected.type] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Protected;
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_private_member.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: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: %.1: type = assoc_entity_type %I.type, %F.type [template]
// CHECK:STDOUT: %.2: %.1 = assoc_entity element0, @I.%F.decl [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = 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: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
// CHECK:STDOUT: %self.patt: @F.%Self (%Self) = binding_pattern self
// CHECK:STDOUT: %self.param_patt: @F.%Self (%Self) = value_param_pattern %self.patt, runtime_param0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT: %.loc9_22.1: type = facet_type_access %Self.ref [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT: %.loc9_22.2: type = converted %Self.ref, %.loc9_22.1 [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT: %self.param: @F.%Self (%Self) = value_param runtime_param0
// CHECK:STDOUT: %self: @F.%Self (%Self) = bind_name self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc9: %.1 = assoc_entity element0, %F.decl [template = constants.%.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: .F = %.loc9
// CHECK:STDOUT: witness = (%F.decl)
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: @F.%Self (%Self)]();
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%Self) {
// CHECK:STDOUT: %Self => constants.%Self
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_protected_member.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: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: %.1: type = assoc_entity_type %I.type, %F.type [template]
// CHECK:STDOUT: %.2: %.1 = assoc_entity element0, @I.%F.decl [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = 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: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
// CHECK:STDOUT: %self.patt: @F.%Self (%Self) = binding_pattern self
// CHECK:STDOUT: %self.param_patt: @F.%Self (%Self) = value_param_pattern %self.patt, runtime_param0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT: %.loc8_24.1: type = facet_type_access %Self.ref [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT: %.loc8_24.2: type = converted %Self.ref, %.loc8_24.1 [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT: %self.param: @F.%Self (%Self) = value_param runtime_param0
// CHECK:STDOUT: %self: @F.%Self (%Self) = bind_name self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc8: %.1 = assoc_entity element0, %F.decl [template = constants.%.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: .F = %.loc8
// CHECK:STDOUT: witness = (%F.decl)
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @F(@I.%Self: %I.type) {
// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: @F.%Self (%Self)]();
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%Self) {
// CHECK:STDOUT: %Self => constants.%Self
// CHECK:STDOUT: }
// CHECK:STDOUT:
+4 -20
View File
@@ -33,30 +33,14 @@ constexpr DiagnosticKind UntestedDiagnosticKinds[] = {
// should be tested.
DiagnosticKind::ArrayBoundTooLarge,
// This isn't feasible to test with a normal testcase, but is tested in
// These aren't feasible to test with a normal testcase, but are tested in
// lex/tokenized_buffer_test.cpp.
DiagnosticKind::TooManyTokens,
// TODO: Should look closer at these, but adding tests is a high risk of
// loss in merge conflicts due to the amount of tests being changed right
// now.
DiagnosticKind::ExternLibraryInImporter,
DiagnosticKind::ExternLibraryOnDefinition,
DiagnosticKind::HexadecimalEscapeMissingDigits,
DiagnosticKind::IncompleteTypeInFunctionParam,
DiagnosticKind::InvalidDigit,
DiagnosticKind::InvalidDigitSeparator,
DiagnosticKind::InvalidHorizontalWhitespaceInString,
DiagnosticKind::MismatchedIndentInString,
DiagnosticKind::ModifierPrivateNotAllowed,
DiagnosticKind::MultiLineStringWithDoubleQuotes,
DiagnosticKind::TooManyDigits,
DiagnosticKind::UnaryOperatorRequiresWhitespace,
DiagnosticKind::UnicodeEscapeSurrogate,
DiagnosticKind::UnicodeEscapeTooLarge,
DiagnosticKind::UnknownBaseSpecifier,
DiagnosticKind::UnsupportedCRLineEnding,
DiagnosticKind::UnsupportedLFCRLineEnding,
// This is a little long but is tested in lex/numeric_literal_test.cpp.
DiagnosticKind::TooManyDigits,
};
// Looks for diagnostic kinds that aren't covered by a file_test.
+46
View File
@@ -0,0 +1,46 @@
// 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
//
// For multiline string literals, force autoupdates to the end so that we don't
// accidentally mix diagnostics with the literal.
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lex/testdata/multiline_string_literals.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lex/testdata/multiline_string_literals.carbon
// --- fail_indent_mismatch.carbon
'''
a
'''
// --- fail_quotes.carbon
"""
a
"""
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: fail_indent_mismatch.carbon:3:1: error: indentation does not match that of the closing `'''` in multi-line string literal [MismatchedIndentInString]
// CHECK:STDERR: a
// CHECK:STDERR: ^
// CHECK:STDERR:
// CHECK:STDERR: fail_quotes.carbon:2:1: error: use `'''` delimiters for a multi-line string literal, not `"""` [MultiLineStringWithDoubleQuotes]
// CHECK:STDERR: """
// CHECK:STDERR: ^
// CHECK:STDOUT: - filename: fail_indent_mismatch.carbon
// CHECK:STDOUT: tokens:
// CHECK:STDOUT: - { index: 1, kind: 'StringLiteral', line: {{ *}}2, column: 3, indent: 3, spelling: ''''
// CHECK:STDOUT: a
// CHECK:STDOUT: '''', value: `a
// CHECK:STDOUT: `, has_leading_space: true }
// CHECK:STDOUT: - filename: fail_quotes.carbon
// CHECK:STDOUT: tokens:
// CHECK:STDOUT: - { index: 1, kind: 'StringLiteral', line: {{ *}}2, column: 1, indent: 1, spelling: '"""
// CHECK:STDOUT: a
// CHECK:STDOUT: """', value: `a
// CHECK:STDOUT: `, has_leading_space: true }
+35 -2
View File
@@ -104,8 +104,41 @@ fn F() {
// CHECK:STDOUT: - filename: fail_wrong_real_exponent.carbon
// CHECK:STDOUT: tokens:
// CHECK:STDERR: fail_wrong_real_exponent.carbon:[[@LINE+3]]:4: error: expected 'e' to introduce exponent [WrongRealLiteralExponent]
// CHECK:STDERR: fail_wrong_real_exponent.carbon:[[@LINE+4]]:4: error: expected 'e' to introduce exponent [WrongRealLiteralExponent]
// CHECK:STDERR: 1.0r3
// CHECK:STDERR: ^
// CHECK:STDERR:
1.0r3
// CHECK:STDOUT: - { index: 1, kind: 'Error', line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: '1.0r3', has_leading_space: true }
// CHECK:STDOUT: - { index: 1, kind: 'Error', line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: '1.0r3', has_leading_space: true }
// --- fail_invalid_digit.carbon
// CHECK:STDOUT: - filename: fail_invalid_digit.carbon
// CHECK:STDOUT: tokens:
// CHECK:STDERR: fail_invalid_digit.carbon:[[@LINE+4]]:4: error: invalid digit 'a' in hexadecimal numeric literal [InvalidDigit]
// CHECK:STDERR: 0x1a
// CHECK:STDERR: ^
// CHECK:STDERR:
0x1a
// CHECK:STDOUT: - { index: 1, kind: 'Error', line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: '0x1a', has_leading_space: true }
// --- fail_invalid_separator.carbon
// CHECK:STDOUT: - filename: fail_invalid_separator.carbon
// CHECK:STDOUT: tokens:
// CHECK:STDERR: fail_invalid_separator.carbon:[[@LINE+4]]:2: error: misplaced digit separator in numeric literal [InvalidDigitSeparator]
// CHECK:STDERR: 1__2
// CHECK:STDERR: ^
// CHECK:STDERR:
1__2
// CHECK:STDOUT: - { index: 1, kind: 'IntLiteral', line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: '1__2', value: `12`, has_leading_space: true }
// --- fail_unknown_base.carbon
// CHECK:STDOUT: - filename: fail_unknown_base.carbon
// CHECK:STDOUT: tokens:
// CHECK:STDERR: fail_unknown_base.carbon:[[@LINE+3]]:1: error: unknown base specifier in numeric literal [UnknownBaseSpecifier]
// CHECK:STDERR: 05
// CHECK:STDERR: ^
05
// CHECK:STDOUT: - { index: 1, kind: 'Error', line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: '05', has_leading_space: true }
Binary file not shown.
+16
View File
@@ -1119,6 +1119,22 @@ TEST_F(LexerTest, DiagnosticInvalidDigit) {
compile_helper_.GetTokenizedBuffer("0x123abc", &consumer);
}
TEST_F(LexerTest, DiagnosticCR) {
Testing::MockDiagnosticConsumer consumer;
EXPECT_CALL(consumer, HandleDiagnostic(IsSingleDiagnostic(
DiagnosticKind::UnsupportedCRLineEnding,
DiagnosticLevel::Error, 1, 1, _)));
compile_helper_.GetTokenizedBuffer("\r", &consumer);
}
TEST_F(LexerTest, DiagnosticLFCR) {
Testing::MockDiagnosticConsumer consumer;
EXPECT_CALL(consumer, HandleDiagnostic(IsSingleDiagnostic(
DiagnosticKind::UnsupportedLFCRLineEnding,
DiagnosticLevel::Error, 2, 1, _)));
compile_helper_.GetTokenizedBuffer("\n\r", &consumer);
}
TEST_F(LexerTest, DiagnosticMissingTerminator) {
Testing::MockDiagnosticConsumer consumer;
EXPECT_CALL(consumer, HandleDiagnostic(IsSingleDiagnostic(
+65
View File
@@ -0,0 +1,65 @@
// 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/parse/testdata/operators/unary.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/operators/unary.carbon
// --- fail_space_before.carbon
fn F() {
// CHECK:STDERR: fail_space_before.carbon:[[@LINE+3]]:16: error: whitespace is required before this unary operator [UnaryOperatorRequiresWhitespace]
// CHECK:STDERR: if (false) {}--0;
// CHECK:STDERR: ^~
if (false) {}--0;
}
// --- todo_fail_space_before_op_with_keyword.carbon
fn F() {
if (false) {}--false;
}
// CHECK:STDOUT: - filename: fail_space_before.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'F'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'BoolLiteralFalse', text: 'false'},
// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'},
// CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 6},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'PrefixOperatorMinusMinus', text: '--', subtree_size: 2},
// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 15},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
// CHECK:STDOUT: - filename: todo_fail_space_before_op_with_keyword.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'F'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'BoolLiteralFalse', text: 'false'},
// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'},
// CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 6},
// CHECK:STDOUT: {kind: 'BoolLiteralFalse', text: 'false'},
// CHECK:STDOUT: {kind: 'PrefixOperatorMinusMinus', text: '--', subtree_size: 2},
// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 15},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]