Improve recovery from bad type imports. (#5953)

The main change here is that a bad type appearing somewhere within a
field or base class of a class shouldn't cause an import of that class
to fail. Instead, only that field or base class becomes inaccessible
from Carbon.

Also improve the way that type importing errors are diagnosed. While we
lose the precision of a diagnostic saying why a type is not supported,
we gain a useful source location for where the type was mentioned in C++
code.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2025-08-13 22:07:54 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 2140a57294
commit b2b0b4a73f
9 changed files with 165 additions and 146 deletions
+18 -24
View File
@@ -121,18 +121,15 @@ class Bar {
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./static_data_member.h:4:15: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
// CHECK:STDERR: static Bar* foo;
// CHECK:STDERR: ^
import Cpp library "static_data_member.h";
fn MyF() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+11]]:23: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+8]]:23: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:23: error: member name `foo` not found in `Cpp.Bar` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:23: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
@@ -224,17 +221,14 @@ class Bar {};
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./template.h:3:7: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: class Bar {};
// CHECK:STDERR: ^
import Cpp library "template.h";
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+11]]:13: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+8]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:13: error: member name `Bar` not found in `Cpp` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
@@ -394,13 +388,13 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Cpp.ref.loc19_23: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc19_26: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %Cpp.ref.loc16_23: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc16_26: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
// CHECK:STDOUT: %.loc19: type = splice_block %ptr [concrete = constants.%ptr.f68] {
// CHECK:STDOUT: %Cpp.ref.loc19_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc19_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc19_15 [concrete = constants.%ptr.f68]
// CHECK:STDOUT: %.loc16: type = splice_block %ptr [concrete = constants.%ptr.f68] {
// CHECK:STDOUT: %Cpp.ref.loc16_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc16_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc16_15 [concrete = constants.%ptr.f68]
// CHECK:STDOUT: }
// CHECK:STDOUT: %bar: %ptr.f68 = bind_name bar, <error> [concrete = <error>]
// CHECK:STDOUT: <elided>
@@ -584,7 +578,7 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .Bar = <poisoned>
// CHECK:STDOUT: .Bar = <error>
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -595,7 +589,7 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
// CHECK:STDOUT: %.loc18: type = splice_block %ptr [concrete = <error>] {
// CHECK:STDOUT: %.loc15: type = splice_block %ptr [concrete = <error>] {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
+75 -15
View File
@@ -123,35 +123,29 @@ fn G(s: Cpp.Union) -> i32 {
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./with_bitfields.h:4:7: error: semantics TODO: `Unsupported: field declaration has unhandled type or kind` [SemanticsTodo]
// CHECK:STDERR: int b : 2;
// CHECK:STDERR: ^
import Cpp library "with_bitfields.h";
fn F(s: Cpp.Struct) -> i32 {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Unhandled kind of field declaration` [SemanticsTodo]
// CHECK:STDERR: return s.b;
// CHECK:STDERR: ^~~
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `b` [InCppNameLookup]
// CHECK:STDERR: return s.b;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+4]]:10: error: member name `b` not found in `Cpp.Struct` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: return s.b;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE-8]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./with_bitfields.h:9:7: error: semantics TODO: `Unsupported: field declaration has unhandled type or kind` [SemanticsTodo]
// CHECK:STDERR: int d : 3;
// CHECK:STDERR: ^
return s.b;
//@dump-sem-ir-end
}
fn G(s: Cpp.Union) -> i32 {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Unhandled kind of field declaration` [SemanticsTodo]
// CHECK:STDERR: return s.d;
// CHECK:STDERR: ^~~
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `d` [InCppNameLookup]
// CHECK:STDERR: return s.d;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+4]]:10: error: member name `d` not found in `Cpp.Union` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+4]]:10: note: in `Cpp` name lookup for `d` [InCppNameLookup]
// CHECK:STDERR: return s.d;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
@@ -159,6 +153,72 @@ fn G(s: Cpp.Union) -> i32 {
//@dump-sem-ir-end
}
// --- unsupported_members.h
struct UnsupportedMembers {
// Volatile is not supported.
volatile int is_volatile;
// Nullable pointers are not supported.
int *is_nullable;
// References are not supported.
int &is_reference;
// But this should be fine.
int integer;
};
void Consume(UnsupportedMembers);
// --- supported_members_in_type_with_unsupported_members.carbon
library "[[@TEST_NAME]]";
import Cpp library "unsupported_members.h";
fn Test(m: Cpp.UnsupportedMembers*) {
// OK: Can still access supported members.
m->integer = 42;
// OK: Can still pass the class to a C++ function.
Cpp.Consume(*m);
}
// --- fail_use_unsupported_members.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_use_unsupported_members.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./unsupported_members.h:4:16: error: semantics TODO: `Unsupported: field declaration has unhandled type or kind` [SemanticsTodo]
// CHECK:STDERR: volatile int is_volatile;
// CHECK:STDERR: ^
import Cpp library "unsupported_members.h";
fn Test(m: Cpp.UnsupportedMembers*) {
// CHECK:STDERR: fail_use_unsupported_members.carbon:[[@LINE+8]]:16: note: in `Cpp` name lookup for `is_volatile` [InCppNameLookup]
// CHECK:STDERR: let a: i32 = m->is_volatile;
// CHECK:STDERR: ^~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_use_unsupported_members.carbon:[[@LINE-7]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./unsupported_members.h:6:8: error: semantics TODO: `Unsupported: field declaration has unhandled type or kind` [SemanticsTodo]
// CHECK:STDERR: int *is_nullable;
// CHECK:STDERR: ^
let a: i32 = m->is_volatile;
// CHECK:STDERR: fail_use_unsupported_members.carbon:[[@LINE+8]]:17: note: in `Cpp` name lookup for `is_nullable` [InCppNameLookup]
// CHECK:STDERR: let b: i32 = *m->is_nullable;
// CHECK:STDERR: ^~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_use_unsupported_members.carbon:[[@LINE-17]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./unsupported_members.h:8:8: error: semantics TODO: `Unsupported: field declaration has unhandled type or kind` [SemanticsTodo]
// CHECK:STDERR: int &is_reference;
// CHECK:STDERR: ^
let b: i32 = *m->is_nullable;
// CHECK:STDERR: fail_use_unsupported_members.carbon:[[@LINE+4]]:16: note: in `Cpp` name lookup for `is_reference` [InCppNameLookup]
// CHECK:STDERR: let c: i32 = m->is_reference;
// CHECK:STDERR: ^~~~~~~~~~~~~~~
// CHECK:STDERR:
let c: i32 = m->is_reference;
}
// CHECK:STDOUT: --- use_struct_fields.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
+3 -8
View File
@@ -57,18 +57,13 @@ fn Value(v: Cpp.HasQualifiers) {
v.plain();
// TODO: This should remain invalid once we support `volatile`.
// CHECK:STDERR: fail_bad_object_param_qualifiers_by_value.carbon:[[@LINE+12]]:3: error: semantics TODO: `Unsupported: qualified type: volatile struct HasQualifiers` [SemanticsTodo]
// CHECK:STDERR: fail_bad_object_param_qualifiers_by_value.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: object parameter type: volatile struct HasQualifiers` [SemanticsTodo]
// CHECK:STDERR: v.volatile_this();
// CHECK:STDERR: ^~~~~~~~~~~~~~~
// CHECK:STDERR: fail_bad_object_param_qualifiers_by_value.carbon:[[@LINE+9]]:3: note: in `Cpp` name lookup for `volatile_this` [InCppNameLookup]
// CHECK:STDERR: fail_bad_object_param_qualifiers_by_value.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `volatile_this` [InCppNameLookup]
// CHECK:STDERR: v.volatile_this();
// CHECK:STDERR: ^~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_bad_object_param_qualifiers_by_value.carbon:[[@LINE+5]]:3: error: `addr self` method cannot be invoked on a value [AddrSelfIsNonRef]
// CHECK:STDERR: v.volatile_this();
// CHECK:STDERR: ^
// CHECK:STDERR: fail_bad_object_param_qualifiers_by_value.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR:
v.volatile_this();
// CHECK:STDERR: fail_bad_object_param_qualifiers_by_value.carbon:[[@LINE+5]]:3: error: `addr self` method cannot be invoked on a value [AddrSelfIsNonRef]
@@ -105,7 +100,7 @@ import Cpp library "object_param_qualifiers.h";
fn Ref(p: Cpp.HasQualifiers*) {
// TODO: This should eventually be accepted if we support `volatile`.
// CHECK:STDERR: fail_todo_bad_object_param_qualifiers_by_ref.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: qualified type: volatile struct HasQualifiers` [SemanticsTodo]
// CHECK:STDERR: fail_todo_bad_object_param_qualifiers_by_ref.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: object parameter type: volatile struct HasQualifiers` [SemanticsTodo]
// CHECK:STDERR: p->volatile_this();
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_todo_bad_object_param_qualifiers_by_ref.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `volatile_this` [InCppNameLookup]
+18 -24
View File
@@ -119,18 +119,15 @@ struct Bar {
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./static_data_member.h:3:24: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
// CHECK:STDERR: static Bar* _Nonnull foo;
// CHECK:STDERR: ^
import Cpp library "static_data_member.h";
fn MyF() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+11]]:23: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+8]]:23: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:23: error: member name `foo` not found in `Cpp.Bar` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:23: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
@@ -212,17 +209,14 @@ struct Bar {};
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./template.h:3:8: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: struct Bar {};
// CHECK:STDERR: ^
import Cpp library "template.h";
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+11]]:13: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+8]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:13: error: member name `Bar` not found in `Cpp` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
@@ -382,13 +376,13 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Cpp.ref.loc19_23: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc19_26: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %Cpp.ref.loc16_23: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc16_26: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
// CHECK:STDOUT: %.loc19: type = splice_block %ptr [concrete = constants.%ptr.f68] {
// CHECK:STDOUT: %Cpp.ref.loc19_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc19_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc19_15 [concrete = constants.%ptr.f68]
// CHECK:STDOUT: %.loc16: type = splice_block %ptr [concrete = constants.%ptr.f68] {
// CHECK:STDOUT: %Cpp.ref.loc16_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc16_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc16_15 [concrete = constants.%ptr.f68]
// CHECK:STDOUT: }
// CHECK:STDOUT: %bar: %ptr.f68 = bind_name bar, <error> [concrete = <error>]
// CHECK:STDOUT: <elided>
@@ -532,7 +526,7 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .Bar = <poisoned>
// CHECK:STDOUT: .Bar = <error>
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -543,7 +537,7 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
// CHECK:STDOUT: %.loc18: type = splice_block %ptr [concrete = <error>] {
// CHECK:STDOUT: %.loc15: type = splice_block %ptr [concrete = <error>] {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
+18 -24
View File
@@ -121,18 +121,15 @@ union Bar {
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./static_data_member.h:4:24: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
// CHECK:STDERR: static Bar* _Nonnull foo;
// CHECK:STDERR: ^
import Cpp library "static_data_member.h";
fn MyF() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+11]]:23: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+8]]:23: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:23: error: member name `foo` not found in `Cpp.Bar` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_import_static_data_member.carbon:[[@LINE+4]]:23: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: let bar: Cpp.Bar* = Cpp.Bar.foo();
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
@@ -176,17 +173,14 @@ union Bar {};
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./template.h:3:7: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: union Bar {};
// CHECK:STDERR: ^
import Cpp library "template.h";
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+11]]:13: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+8]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:13: error: member name `Bar` not found in `Cpp` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_import_template.carbon:[[@LINE+4]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
@@ -346,13 +340,13 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Cpp.ref.loc19_23: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc19_26: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %Cpp.ref.loc16_23: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc16_26: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
// CHECK:STDOUT: %.loc19: type = splice_block %ptr [concrete = constants.%ptr.f68] {
// CHECK:STDOUT: %Cpp.ref.loc19_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc19_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc19_15 [concrete = constants.%ptr.f68]
// CHECK:STDOUT: %.loc16: type = splice_block %ptr [concrete = constants.%ptr.f68] {
// CHECK:STDOUT: %Cpp.ref.loc16_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref.loc16_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc16_15 [concrete = constants.%ptr.f68]
// CHECK:STDOUT: }
// CHECK:STDOUT: %bar: %ptr.f68 = bind_name bar, <error> [concrete = <error>]
// CHECK:STDOUT: <elided>
@@ -420,7 +414,7 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .Bar = <poisoned>
// CHECK:STDOUT: .Bar = <error>
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -431,7 +425,7 @@ fn MyF(bar: Cpp.Bar*);
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
// CHECK:STDOUT: %.loc18: type = splice_block %ptr [concrete = <error>] {
// CHECK:STDOUT: %.loc15: type = splice_block %ptr [concrete = <error>] {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
@@ -176,7 +176,7 @@ import Cpp library "nullable_pointer_param.h";
fn F() {
//@dump-sem-ir-begin
var s: Cpp.S = {};
// CHECK:STDERR: fail_todo_import_nullable_pointer_param.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: nullable pointer: S *` [SemanticsTodo]
// CHECK:STDERR: fail_todo_import_nullable_pointer_param.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: parameter type: S *` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo(&s);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_nullable_pointer_param.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
@@ -524,8 +524,6 @@ fn F() {
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %pattern_type.7da: type = pattern_type %S [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.642: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %T.as.Destroy.impl.Op.ab5: %T.as.Destroy.impl.Op.type.642 = struct_value () [concrete]
@@ -534,15 +532,10 @@ fn F() {
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .S = %S.decl
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: .foo = <error>
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
@@ -562,10 +555,9 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %s: ref %S = bind_name s, %s.var
// CHECK:STDOUT: %Cpp.ref.loc16: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
// CHECK:STDOUT: %s.ref: ref %S = name_ref s, %s
// CHECK:STDOUT: %addr.loc16: %ptr.5c7 = addr_of %s.ref
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %s.var, constants.%T.as.Destroy.impl.Op.ab5
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %s.var, %T.as.Destroy.impl.Op.specific_fn
@@ -18,18 +18,15 @@ template<typename T> class C {};
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_use_template.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./template.h:2:28: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: template<typename T> class C {};
// CHECK:STDERR: ^
import Cpp library "template.h";
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_use_template.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Declaration type ClassTemplate` [SemanticsTodo]
// CHECK:STDERR: var c: Cpp.C({});
// CHECK:STDERR: ^~~~~
// CHECK:STDERR: fail_todo_use_template.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `C` [InCppNameLookup]
// CHECK:STDERR: var c: Cpp.C({});
// CHECK:STDERR: ^~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_use_template.carbon:[[@LINE+4]]:10: error: member name `C` not found in `Cpp` [MemberNameNotFoundInInstScope]
// CHECK:STDERR: fail_todo_use_template.carbon:[[@LINE+4]]:10: note: in `Cpp` name lookup for `C` [InCppNameLookup]
// CHECK:STDERR: var c: Cpp.C({});
// CHECK:STDERR: ^~~~~
// CHECK:STDERR: