mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:40:12 +01:00
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:
@@ -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:
|
||||
|
||||
+31
-1
@@ -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:
|
||||
+186
-18
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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 }
|
||||
|
||||
BIN
Binary file not shown.
@@ -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
@@ -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: ]
|
||||
Reference in New Issue
Block a user