C++ Interop: Set location when creating param patterns (#6184)

Follow up of #5197.
Part of #5064.
This commit is contained in:
Boaz Brickner
2025-10-10 09:00:00 +00:00
committed by GitHub
parent fd15949fe5
commit f713964db4
7 changed files with 137 additions and 93 deletions
+15 -15
View File
@@ -1407,31 +1407,31 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
? SemIR::NameId::Underscore
: AddIdentifierName(context, param_name);
SemIR::LocId param_loc_id =
AddImportIRInst(context.sem_ir(), param->getLocation());
// TODO: Fix this once templates are supported.
bool is_template = false;
// TODO: Fix this once generics are supported.
bool is_generic = false;
SemIR::InstId pattern_id =
// TODO: Fill in a location once available.
AddBindingPattern(context, SemIR::LocId::None, name_id, type_id,
AddBindingPattern(context, param_loc_id, name_id, type_id,
type_expr_region_id, is_generic, is_template)
.pattern_id;
pattern_id = AddPatternInst(
context,
// TODO: Fill in a location once available.
SemIR::LocIdAndInst::NoLoc(SemIR::ValueParamPattern(
{.type_id = context.insts().Get(pattern_id).type_id(),
.subpattern_id = pattern_id,
.index = SemIR::CallParamIndex::None})));
context, {param_loc_id,
SemIR::ValueParamPattern(
{.type_id = context.insts().Get(pattern_id).type_id(),
.subpattern_id = pattern_id,
.index = SemIR::CallParamIndex::None})});
if (is_ref_param) {
pattern_id = AddPatternInst(
context,
// TODO: Fill in a location once available.
SemIR::LocIdAndInst::NoLoc(SemIR::AddrPattern(
{.type_id = GetPatternType(
context,
context.types().GetTypeIdForTypeInstId(orig_type_inst_id)),
.inner_id = pattern_id})));
context, {param_loc_id,
SemIR::AddrPattern(
{.type_id = GetPatternType(
context, context.types().GetTypeIdForTypeInstId(
orig_type_inst_id)),
.inner_id = pattern_id})});
}
params.push_back(pattern_id);
}
@@ -37,6 +37,8 @@ fn G(x: Cpp.X) {
// CHECK:STDOUT: 'import_ir(Cpp)': {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: import_ir_insts:
// CHECK:STDOUT: import_ir_inst0: {ir_id: import_ir(Cpp), clang_source_loc_id: clang_source_loc0}
// CHECK:STDOUT: import_ir_inst1: {ir_id: import_ir(Cpp), clang_source_loc_id: clang_source_loc1}
// CHECK:STDOUT: import_ir_inst2: {ir_id: import_ir(Cpp), clang_source_loc_id: clang_source_loc2}
// CHECK:STDOUT: clang_decls:
// CHECK:STDOUT: clang_decl_id0: {key: "<translation unit>", inst_id: inst60000010}
// CHECK:STDOUT: clang_decl_id1: {key: "struct X {}", inst_id: inst60000012}
@@ -242,10 +242,13 @@ library "[[@TEST_NAME]]";
import Cpp library "short_param.h";
fn F() {
// CHECK:STDERR: fail_import_short_param_overflow_max.carbon:[[@LINE+5]]:11: error: integer value 32768 too large for type `i16` [IntTooLargeForType]
// CHECK:STDERR: fail_import_short_param_overflow_max.carbon:[[@LINE+8]]:11: error: integer value 32768 too large for type `i16` [IntTooLargeForType]
// CHECK:STDERR: Cpp.foo(0x8000);
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR: fail_import_short_param_overflow_max.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_short_param_overflow_max.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./short_param.h:2:16: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(short a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(0x8000);
}
@@ -269,10 +272,13 @@ library "[[@TEST_NAME]]";
import Cpp library "short_param.h";
fn F() {
// CHECK:STDERR: fail_import_short_param_overflow_min.carbon:[[@LINE+5]]:11: error: integer value -32769 too large for type `i16` [IntTooLargeForType]
// CHECK:STDERR: fail_import_short_param_overflow_min.carbon:[[@LINE+8]]:11: error: integer value -32769 too large for type `i16` [IntTooLargeForType]
// CHECK:STDERR: Cpp.foo(-0x8001);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_import_short_param_overflow_min.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_short_param_overflow_min.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./short_param.h:2:16: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(short a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(-0x8001);
}
@@ -284,13 +290,16 @@ library "[[@TEST_NAME]]";
import Cpp library "short_param.h";
fn F() {
// CHECK:STDERR: fail_import_short_param_int32_arg.carbon:[[@LINE+8]]:11: error: cannot implicitly convert expression of type `i32` to `i16` [ConversionFailure]
// CHECK:STDERR: fail_import_short_param_int32_arg.carbon:[[@LINE+11]]:11: error: cannot implicitly convert expression of type `i32` to `i16` [ConversionFailure]
// CHECK:STDERR: Cpp.foo(1 as i32);
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_import_short_param_int32_arg.carbon:[[@LINE+5]]:11: note: type `i32` does not implement interface `Core.ImplicitAs(i16)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: fail_import_short_param_int32_arg.carbon:[[@LINE+8]]:11: note: type `i32` does not implement interface `Core.ImplicitAs(i16)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: Cpp.foo(1 as i32);
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_import_short_param_int32_arg.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_short_param_int32_arg.carbon:[[@LINE-9]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./short_param.h:2:16: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(short a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(1 as i32);
}
@@ -53,10 +53,13 @@ library "[[@TEST_NAME]]";
import Cpp library "int_param.h";
fn F() {
// CHECK:STDERR: fail_import_int_param_overflow_max.carbon:[[@LINE+5]]:11: error: integer value 2147483648 too large for type `i32` [IntTooLargeForType]
// CHECK:STDERR: fail_import_int_param_overflow_max.carbon:[[@LINE+8]]:11: error: integer value 2147483648 too large for type `i32` [IntTooLargeForType]
// CHECK:STDERR: Cpp.foo(0x8000_0000);
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR: fail_import_int_param_overflow_max.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_int_param_overflow_max.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./int_param.h:2:14: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(int a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(0x8000_0000);
}
@@ -80,10 +83,13 @@ library "[[@TEST_NAME]]";
import Cpp library "int_param.h";
fn F() {
// CHECK:STDERR: fail_import_int_param_overflow_min.carbon:[[@LINE+5]]:11: error: integer value -2147483649 too large for type `i32` [IntTooLargeForType]
// CHECK:STDERR: fail_import_int_param_overflow_min.carbon:[[@LINE+8]]:11: error: integer value -2147483649 too large for type `i32` [IntTooLargeForType]
// CHECK:STDERR: Cpp.foo(-0x8000_0001);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_import_int_param_overflow_min.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_int_param_overflow_min.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./int_param.h:2:14: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(int a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(-0x8000_0001);
}
@@ -157,19 +163,25 @@ import Cpp library "unsigned_int_param.h";
fn F() {
Cpp.foo(0);
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE+5]]:11: error: negative integer value -1 converted to unsigned type `u32` [NegativeIntInUnsignedType]
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE+8]]:11: error: negative integer value -1 converted to unsigned type `u32` [NegativeIntInUnsignedType]
// CHECK:STDERR: Cpp.foo(-1);
// CHECK:STDERR: ^~
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE-8]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./unsigned_int_param.h:2:23: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(unsigned int a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(-1);
Cpp.foo(0x0_FFFF_FFFF);
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE+5]]:11: error: integer value 4294967296 too large for type `u32` [IntTooLargeForType]
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE+8]]:11: error: integer value 4294967296 too large for type `u32` [IntTooLargeForType]
// CHECK:STDERR: Cpp.foo(0x1_0000_0000);
// CHECK:STDERR: ^~~~~~~~~~~~~
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE-20]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./unsigned_int_param.h:2:23: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(unsigned int a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(0x1_0000_0000);
}
@@ -347,22 +347,28 @@ import Cpp library "plus_with_int_conversion.h";
fn F() {
let c1: Cpp.C = Cpp.C.C(4);
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+8]]:24: error: cannot implicitly convert expression of type `Core.IntLiteral` to `Cpp.C` [ConversionFailure]
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+11]]:24: error: cannot implicitly convert expression of type `Core.IntLiteral` to `Cpp.C` [ConversionFailure]
// CHECK:STDERR: let c2: Cpp.C = c1 + 5;
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+5]]:24: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(Cpp.C)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+8]]:24: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(Cpp.C)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: let c2: Cpp.C = c1 + 5;
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE-10]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./plus_with_int_conversion.h:6:25: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto operator+(C lhs, C rhs) -> C;
// CHECK:STDERR: ^
// CHECK:STDERR:
let c2: Cpp.C = c1 + 5;
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+8]]:19: error: cannot implicitly convert expression of type `Core.IntLiteral` to `Cpp.C` [ConversionFailure]
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+11]]:19: error: cannot implicitly convert expression of type `Core.IntLiteral` to `Cpp.C` [ConversionFailure]
// CHECK:STDERR: let c3: Cpp.C = 6 + c1;
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+5]]:19: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(Cpp.C)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE+8]]:19: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(Cpp.C)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: let c3: Cpp.C = 6 + c1;
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_todo_plus_with_int_conversion.carbon:[[@LINE-22]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./plus_with_int_conversion.h:6:18: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto operator+(C lhs, C rhs) -> C;
// CHECK:STDERR: ^
// CHECK:STDERR:
let c3: Cpp.C = 6 + c1;
}
@@ -126,10 +126,13 @@ library "[[@TEST_NAME]]";
import Cpp library "large_int_literal.h";
fn F() {
// CHECK:STDERR: fail_import_large_int_literal.carbon:[[@LINE+5]]:11: error: integer value 9223372036854775808 too large for type `i64` [IntTooLargeForType]
// CHECK:STDERR: fail_import_large_int_literal.carbon:[[@LINE+8]]:11: error: integer value 9223372036854775808 too large for type `i64` [IntTooLargeForType]
// CHECK:STDERR: Cpp.foo(0x8000_0000_0000_0000);
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_import_large_int_literal.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_large_int_literal.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./large_int_literal.h:2:15: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(long a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(0x8000_0000_0000_0000);
}
@@ -161,10 +164,13 @@ library "[[@TEST_NAME]]";
import Cpp library "negative_literal_passed_to_unsigned.h";
fn F() {
// CHECK:STDERR: fail_import_negative_literal_passed_to_unsigned.carbon:[[@LINE+5]]:11: error: negative integer value -1 converted to unsigned type `u32` [NegativeIntInUnsignedType]
// CHECK:STDERR: fail_import_negative_literal_passed_to_unsigned.carbon:[[@LINE+8]]:11: error: negative integer value -1 converted to unsigned type `u32` [NegativeIntInUnsignedType]
// CHECK:STDERR: Cpp.foo(-1);
// CHECK:STDERR: ^~
// CHECK:STDERR: fail_import_negative_literal_passed_to_unsigned.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_negative_literal_passed_to_unsigned.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./negative_literal_passed_to_unsigned.h:2:23: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(unsigned int a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(-1);
}
@@ -205,13 +211,16 @@ library "[[@TEST_NAME]]";
import Cpp library "upsizing_rejected.h";
fn F() {
// CHECK:STDERR: fail_import_upsizing_rejected.carbon:[[@LINE+8]]:11: error: cannot implicitly convert expression of type `i16` to `i32` [ConversionFailure]
// CHECK:STDERR: fail_import_upsizing_rejected.carbon:[[@LINE+11]]:11: error: cannot implicitly convert expression of type `i16` to `i32` [ConversionFailure]
// CHECK:STDERR: Cpp.foo(1 as i16);
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_import_upsizing_rejected.carbon:[[@LINE+5]]:11: note: type `i16` does not implement interface `Core.ImplicitAs(i32)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: fail_import_upsizing_rejected.carbon:[[@LINE+8]]:11: note: type `i16` does not implement interface `Core.ImplicitAs(i32)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: Cpp.foo(1 as i16);
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_import_upsizing_rejected.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_upsizing_rejected.carbon:[[@LINE-9]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./upsizing_rejected.h:2:14: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(int a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(1 as i16);
}
@@ -227,13 +236,16 @@ library "[[@TEST_NAME]]";
import Cpp library "downsizing_rejected.h";
fn F() {
// CHECK:STDERR: fail_import_downsizing_rejected.carbon:[[@LINE+8]]:11: error: cannot implicitly convert expression of type `i32` to `i16` [ConversionFailure]
// CHECK:STDERR: fail_import_downsizing_rejected.carbon:[[@LINE+11]]:11: error: cannot implicitly convert expression of type `i32` to `i16` [ConversionFailure]
// CHECK:STDERR: Cpp.foo(1 as i32);
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_import_downsizing_rejected.carbon:[[@LINE+5]]:11: note: type `i32` does not implement interface `Core.ImplicitAs(i16)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: fail_import_downsizing_rejected.carbon:[[@LINE+8]]:11: note: type `i32` does not implement interface `Core.ImplicitAs(i16)` [MissingImplInMemberAccessNote]
// CHECK:STDERR: Cpp.foo(1 as i32);
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_import_downsizing_rejected.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_import_downsizing_rejected.carbon:[[@LINE-9]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./downsizing_rejected.h:2:16: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto foo(short a) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.foo(1 as i32);
}
@@ -1159,13 +1171,13 @@ fn F() {
// CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value]
// CHECK:STDOUT: %int_9223372036854775808: Core.IntLiteral = int_value 9223372036854775808 [concrete = constants.%int_9223372036854775808.293]
// CHECK:STDOUT: %impl.elem0: %.35c = impl_witness_access constants.%ImplicitAs.impl_witness.830, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.719]
// CHECK:STDOUT: %bound_method.loc12_11.1: <bound method> = bound_method %int_9223372036854775808, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %bound_method.loc15_11.1: <bound method> = bound_method %int_9223372036854775808, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc12_11.2: <bound method> = bound_method %int_9223372036854775808, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i64 = call %bound_method.loc12_11.2(%int_9223372036854775808) [concrete = constants.%int_9223372036854775808.b10]
// CHECK:STDOUT: %.loc12_11.1: %i64 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_9223372036854775808.b10]
// CHECK:STDOUT: %.loc12_11.2: %i64 = converted %int_9223372036854775808, %.loc12_11.1 [concrete = constants.%int_9223372036854775808.b10]
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc12_11.2)
// CHECK:STDOUT: %bound_method.loc15_11.2: <bound method> = bound_method %int_9223372036854775808, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i64 = call %bound_method.loc15_11.2(%int_9223372036854775808) [concrete = constants.%int_9223372036854775808.b10]
// CHECK:STDOUT: %.loc15_11.1: %i64 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_9223372036854775808.b10]
// CHECK:STDOUT: %.loc15_11.2: %i64 = converted %int_9223372036854775808, %.loc15_11.1 [concrete = constants.%int_9223372036854775808.b10]
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc15_11.2)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -1380,18 +1392,18 @@ fn F() {
// CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
// CHECK:STDOUT: %impl.elem1: %.a96 = impl_witness_access constants.%Negate.impl_witness, element1 [concrete = constants.%Core.IntLiteral.as.Negate.impl.Op]
// CHECK:STDOUT: %bound_method.loc12_11.1: <bound method> = bound_method %int_1, %impl.elem1 [concrete = constants.%Core.IntLiteral.as.Negate.impl.Op.bound]
// CHECK:STDOUT: %Core.IntLiteral.as.Negate.impl.Op.call: init Core.IntLiteral = call %bound_method.loc12_11.1(%int_1) [concrete = constants.%int_-1.638]
// CHECK:STDOUT: %bound_method.loc15_11.1: <bound method> = bound_method %int_1, %impl.elem1 [concrete = constants.%Core.IntLiteral.as.Negate.impl.Op.bound]
// CHECK:STDOUT: %Core.IntLiteral.as.Negate.impl.Op.call: init Core.IntLiteral = call %bound_method.loc15_11.1(%int_1) [concrete = constants.%int_-1.638]
// CHECK:STDOUT: %impl.elem0: %.3db = impl_witness_access constants.%ImplicitAs.impl_witness.f1e, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.d2b]
// CHECK:STDOUT: %bound_method.loc12_11.2: <bound method> = bound_method %Core.IntLiteral.as.Negate.impl.Op.call, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %bound_method.loc15_11.2: <bound method> = bound_method %Core.IntLiteral.as.Negate.impl.Op.call, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc12_11.3: <bound method> = bound_method %Core.IntLiteral.as.Negate.impl.Op.call, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %.loc12_11.1: Core.IntLiteral = value_of_initializer %Core.IntLiteral.as.Negate.impl.Op.call [concrete = constants.%int_-1.638]
// CHECK:STDOUT: %.loc12_11.2: Core.IntLiteral = converted %Core.IntLiteral.as.Negate.impl.Op.call, %.loc12_11.1 [concrete = constants.%int_-1.638]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %u32 = call %bound_method.loc12_11.3(%.loc12_11.2) [concrete = constants.%int_-1.311]
// CHECK:STDOUT: %.loc12_11.3: %u32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_-1.311]
// CHECK:STDOUT: %.loc12_11.4: %u32 = converted %Core.IntLiteral.as.Negate.impl.Op.call, %.loc12_11.3 [concrete = constants.%int_-1.311]
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc12_11.4)
// CHECK:STDOUT: %bound_method.loc15_11.3: <bound method> = bound_method %Core.IntLiteral.as.Negate.impl.Op.call, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %.loc15_11.1: Core.IntLiteral = value_of_initializer %Core.IntLiteral.as.Negate.impl.Op.call [concrete = constants.%int_-1.638]
// CHECK:STDOUT: %.loc15_11.2: Core.IntLiteral = converted %Core.IntLiteral.as.Negate.impl.Op.call, %.loc15_11.1 [concrete = constants.%int_-1.638]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %u32 = call %bound_method.loc15_11.3(%.loc15_11.2) [concrete = constants.%int_-1.311]
// CHECK:STDOUT: %.loc15_11.3: %u32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_-1.311]
// CHECK:STDOUT: %.loc15_11.4: %u32 = converted %Core.IntLiteral.as.Negate.impl.Op.call, %.loc15_11.3 [concrete = constants.%int_-1.311]
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc15_11.4)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -1530,13 +1542,13 @@ fn F() {
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
// CHECK:STDOUT: %i16: type = class_type @Int, @Int(constants.%int_16) [concrete = constants.%i16]
// CHECK:STDOUT: %impl.elem0: %.026 = impl_witness_access constants.%As.impl_witness.2d2, element0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.97a]
// CHECK:STDOUT: %bound_method.loc15_13.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %bound_method.loc18_13.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.As.impl.Convert(constants.%int_16) [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc15_13.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.call: init %i16 = call %bound_method.loc15_13.2(%int_1) [concrete = constants.%int_1.f90]
// CHECK:STDOUT: %.loc15_13.1: %i16 = value_of_initializer %Core.IntLiteral.as.As.impl.Convert.call [concrete = constants.%int_1.f90]
// CHECK:STDOUT: %.loc15_13.2: %i16 = converted %int_1, %.loc15_13.1 [concrete = constants.%int_1.f90]
// CHECK:STDOUT: %.loc15_13.3: %i32 = converted %.loc15_13.2, <error> [concrete = <error>]
// CHECK:STDOUT: %bound_method.loc18_13.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.call: init %i16 = call %bound_method.loc18_13.2(%int_1) [concrete = constants.%int_1.f90]
// CHECK:STDOUT: %.loc18_13.1: %i16 = value_of_initializer %Core.IntLiteral.as.As.impl.Convert.call [concrete = constants.%int_1.f90]
// CHECK:STDOUT: %.loc18_13.2: %i16 = converted %int_1, %.loc18_13.1 [concrete = constants.%int_1.f90]
// CHECK:STDOUT: %.loc18_13.3: %i32 = converted %.loc18_13.2, <error> [concrete = <error>]
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(<error>)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -1634,13 +1646,13 @@ fn F() {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %impl.elem0: %.351 = impl_witness_access constants.%As.impl_witness.080, element0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.414]
// CHECK:STDOUT: %bound_method.loc15_13.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %bound_method.loc18_13.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.As.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc15_13.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.call: init %i32 = call %bound_method.loc15_13.2(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc15_13.1: %i32 = value_of_initializer %Core.IntLiteral.as.As.impl.Convert.call [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc15_13.2: %i32 = converted %int_1, %.loc15_13.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc15_13.3: %i16 = converted %.loc15_13.2, <error> [concrete = <error>]
// CHECK:STDOUT: %bound_method.loc18_13.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.As.impl.Convert.call: init %i32 = call %bound_method.loc18_13.2(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc18_13.1: %i32 = value_of_initializer %Core.IntLiteral.as.As.impl.Convert.call [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc18_13.2: %i32 = converted %int_1, %.loc18_13.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc18_13.3: %i16 = converted %.loc18_13.2, <error> [concrete = <error>]
// CHECK:STDOUT: %addr: %ptr = addr_of <error> [concrete = <error>]
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr)
// CHECK:STDOUT: return
@@ -199,18 +199,21 @@ fn F() {
// TODO: The diagnostic here is wrong; we're internally using `addr` but this
// is not `addr self`.
let s: Cpp.S = {};
// CHECK:STDERR: fail_param_const_lvalue_ref.carbon:[[@LINE+5]]:24: error: `addr self` method cannot be invoked on a value [AddrSelfIsNonRef]
// CHECK:STDERR: fail_param_const_lvalue_ref.carbon:[[@LINE+8]]:24: error: `addr self` method cannot be invoked on a value [AddrSelfIsNonRef]
// CHECK:STDERR: Cpp.TakesConstLValue(s);
// CHECK:STDERR: ^
// CHECK:STDERR: fail_param_const_lvalue_ref.carbon: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fail_param_const_lvalue_ref.carbon:[[@LINE-12]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./param_const_lvalue_ref.h:5:31: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: auto TakesConstLValue(const S&) -> void;
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.TakesConstLValue(s);
var t: Cpp.T;
// CHECK:STDERR: fail_param_const_lvalue_ref.carbon:[[@LINE+8]]:25: error: no matching function for call to 'TakesConstLValue' [CppInteropParseError]
// CHECK:STDERR: 29 | Cpp.TakesConstLValue(t);
// CHECK:STDERR: 32 | Cpp.TakesConstLValue(t);
// CHECK:STDERR: | ^
// CHECK:STDERR: fail_param_const_lvalue_ref.carbon:[[@LINE-20]]:10: in file included here [InCppInclude]
// CHECK:STDERR: fail_param_const_lvalue_ref.carbon:[[@LINE-23]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./param_const_lvalue_ref.h:5:6: note: candidate function not viable: no known conversion from 'T' to 'const S' for 1st argument [CppInteropParseNote]
// CHECK:STDERR: 5 | auto TakesConstLValue(const S&) -> void;
// CHECK:STDERR: | ^ ~~~~~~~~
@@ -826,32 +829,32 @@ fn F() {
// CHECK:STDOUT: %.loc12_19.5: ref %S = converted %.loc12_19.1, %.loc12_19.4
// CHECK:STDOUT: %.loc12_19.6: %S = bind_value %.loc12_19.5
// CHECK:STDOUT: %s: %S = bind_name s, %.loc12_19.6
// CHECK:STDOUT: %Cpp.ref.loc18: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesConstLValue.ref.loc18: %TakesConstLValue.cpp_overload_set.type = name_ref TakesConstLValue, imports.%TakesConstLValue.cpp_overload_set.value [concrete = constants.%TakesConstLValue.cpp_overload_set.value]
// CHECK:STDOUT: %Cpp.ref.loc21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesConstLValue.ref.loc21: %TakesConstLValue.cpp_overload_set.type = name_ref TakesConstLValue, imports.%TakesConstLValue.cpp_overload_set.value [concrete = constants.%TakesConstLValue.cpp_overload_set.value]
// CHECK:STDOUT: %s.ref: %S = name_ref s, %s
// CHECK:STDOUT: %.loc18_24.1: ref %S = temporary_storage
// CHECK:STDOUT: %addr.loc18: %ptr.5c7 = addr_of %.loc18_24.1
// CHECK:STDOUT: %.loc18_24.2: %ptr.ff5 = as_compatible %addr.loc18
// CHECK:STDOUT: %.loc18_24.3: %ptr.ff5 = converted %addr.loc18, %.loc18_24.2
// CHECK:STDOUT: %TakesConstLValue__carbon_thunk.call: init %empty_tuple.type = call imports.%TakesConstLValue__carbon_thunk.decl(%.loc18_24.3)
// CHECK:STDOUT: %.loc21_24.1: ref %S = temporary_storage
// CHECK:STDOUT: %addr.loc21: %ptr.5c7 = addr_of %.loc21_24.1
// CHECK:STDOUT: %.loc21_24.2: %ptr.ff5 = as_compatible %addr.loc21
// CHECK:STDOUT: %.loc21_24.3: %ptr.ff5 = converted %addr.loc21, %.loc21_24.2
// CHECK:STDOUT: %TakesConstLValue__carbon_thunk.call: init %empty_tuple.type = call imports.%TakesConstLValue__carbon_thunk.decl(%.loc21_24.3)
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %t.patt: %pattern_type.e6b = binding_pattern t [concrete]
// CHECK:STDOUT: %t.var_patt: %pattern_type.e6b = var_pattern %t.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %t.var: ref %T = var %t.var_patt
// CHECK:STDOUT: %.loc20: type = splice_block %T.ref [concrete = constants.%T] {
// CHECK:STDOUT: %Cpp.ref.loc20: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %.loc23: type = splice_block %T.ref [concrete = constants.%T] {
// CHECK:STDOUT: %Cpp.ref.loc23: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %T.ref: type = name_ref T, imports.%T.decl [concrete = constants.%T]
// CHECK:STDOUT: }
// CHECK:STDOUT: %t: ref %T = bind_name t, %t.var
// CHECK:STDOUT: %Cpp.ref.loc29: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesConstLValue.ref.loc29: %TakesConstLValue.cpp_overload_set.type = name_ref TakesConstLValue, imports.%TakesConstLValue.cpp_overload_set.value [concrete = constants.%TakesConstLValue.cpp_overload_set.value]
// CHECK:STDOUT: %Cpp.ref.loc32: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesConstLValue.ref.loc32: %TakesConstLValue.cpp_overload_set.type = name_ref TakesConstLValue, imports.%TakesConstLValue.cpp_overload_set.value [concrete = constants.%TakesConstLValue.cpp_overload_set.value]
// CHECK:STDOUT: %t.ref: ref %T = name_ref t, %t
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc20: <bound method> = bound_method %t.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.2f0
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc23: <bound method> = bound_method %t.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.2f0
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc20: <bound method> = bound_method %t.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1
// CHECK:STDOUT: %addr.loc20: %ptr.b04 = addr_of %t.var
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc20: init %empty_tuple.type = call %bound_method.loc20(%addr.loc20)
// CHECK:STDOUT: %bound_method.loc23: <bound method> = bound_method %t.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1
// CHECK:STDOUT: %addr.loc23: %ptr.b04 = addr_of %t.var
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc23: init %empty_tuple.type = call %bound_method.loc23(%addr.loc23)
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc12: <bound method> = bound_method %.loc12_19.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.016
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc12: <bound method> = bound_method %.loc12_19.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2