From 2a96b5278008e3d408dabc919a04f55f6ea8b530 Mon Sep 17 00:00:00 2001 From: Ivana Ivanovska Date: Thu, 16 Oct 2025 18:24:28 +0200 Subject: [PATCH] Remove big float literals TODO (#6220) A Carbon floating-point literal passed as a call argument to a C++ function is mapped to `double`. If the value is too large to fit in `double`, an error is reported. This follows the C++ rules for assigning types to floating-point literals, as discussed in the [interop meeting](https://docs.google.com/document/d/1YlxEOJ0r-o19o19TCJbFl4Ln1U88yn_Vj23y1Hr5vTk/edit?tab=t.0#heading=h.9zzqn7n3o8lm) and documented in this [design doc](https://docs.google.com/document/d/18u8z9UEuGH73XzXlDynTgyNK76q1Efl8YYWbpM5LX7o/edit?tab=t.0#heading=h.6hkga1yq1f3o). Added missing tests for this as well. Part of #5915 --- toolchain/check/cpp/type_mapping.cpp | 1 - .../interop/cpp/function/overloads.carbon | 323 ++++++++++++++++++ 2 files changed, 323 insertions(+), 1 deletion(-) diff --git a/toolchain/check/cpp/type_mapping.cpp b/toolchain/check/cpp/type_mapping.cpp index 71235f5aaf67..e1a7f173610a 100644 --- a/toolchain/check/cpp/type_mapping.cpp +++ b/toolchain/check/cpp/type_mapping.cpp @@ -171,7 +171,6 @@ static auto MapNonWrapperType(Context& context, SemIR::InstId inst_id, return context.ast_context().getIntTypeForBitwidth(bit_width_id.AsValue(), true); } - // TODO: What if the value doesn't fit to f64? case SemIR::FloatLiteralType::Kind: { return context.ast_context().DoubleTy; } diff --git a/toolchain/check/testdata/interop/cpp/function/overloads.carbon b/toolchain/check/testdata/interop/cpp/function/overloads.carbon index 71f43020ff28..a43ba819695c 100644 --- a/toolchain/check/testdata/interop/cpp/function/overloads.carbon +++ b/toolchain/check/testdata/interop/cpp/function/overloads.carbon @@ -175,6 +175,39 @@ fn F() { Cpp.foo(-1); } +// --- floating_point_literal.h + +auto foo(float a) -> float; +auto foo(double a) -> double; + +// --- import_floating_point_literal.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "floating_point_literal.h"; + +fn F() { + let d: f64 = Cpp.foo(1.0); +} + +// --- fail_import_large_floating_point_literal.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "floating_point_literal.h"; + +fn F() { + // CHECK:STDERR: fail_import_large_floating_point_literal.carbon:[[@LINE+8]]:11: error: value 18*10^307 too large for floating-point type `f64` [FloatLiteralTooLargeForType] + // CHECK:STDERR: Cpp.foo(1.8e+308); + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: fail_import_large_floating_point_literal.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./floating_point_literal.h:3:17: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: auto foo(double a) -> double; + // CHECK:STDERR: ^ + // CHECK:STDERR: + Cpp.foo(1.8e+308); +} + // --- struct_literal_call_arg.h struct S {}; @@ -1409,6 +1442,296 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: fn @foo(%a.param: %u32); // CHECK:STDOUT: +// CHECK:STDOUT: --- import_floating_point_literal.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete] +// CHECK:STDOUT: %Float.type: type = generic_class_type @Float [concrete] +// CHECK:STDOUT: %Float.generic: %Float.type = struct_value () [concrete] +// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic] +// CHECK:STDOUT: %f64.d77: type = class_type @Float, @Float(%int_64) [concrete] +// CHECK:STDOUT: %pattern_type.0ae: type = pattern_type %f64.d77 [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] +// CHECK:STDOUT: %float.674: Core.FloatLiteral = float_literal_value 10e-1 [concrete] +// CHECK:STDOUT: %ptr.bcc: type = ptr_type %f64.d77 [concrete] +// CHECK:STDOUT: %pattern_type.0ce: type = pattern_type %ptr.bcc [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.73d: type = facet_type <@ImplicitAs, @ImplicitAs(%f64.d77)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.726: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%f64.d77) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.265: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.34c: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.265 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.be7: = impl_witness imports.%ImplicitAs.impl_witness_table, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.4d3: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.4d3 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.73d = facet_value Core.FloatLiteral, (%ImplicitAs.impl_witness.be7) [concrete] +// CHECK:STDOUT: %.4b9: type = fn_type_with_self_type %ImplicitAs.Convert.type.726, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound: = bound_method %float.674, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7 [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_64) [concrete] +// CHECK:STDOUT: %bound_method.8e3: = bound_method %float.674, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %float.d20: %f64.d77 = float_value 1 [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.type.89d: type = fn_type @Float.as.Copy.impl.Op, @Float.as.Copy.impl(%N) [symbolic] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.b4c: %Float.as.Copy.impl.Op.type.89d = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.911: = impl_witness imports.%Copy.impl_witness_table.3b9, @Float.as.Copy.impl(%int_64) [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.type.f9e: type = fn_type @Float.as.Copy.impl.Op, @Float.as.Copy.impl(%int_64) [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.5b0: %Float.as.Copy.impl.Op.type.f9e = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %f64.d77, (%Copy.impl_witness.911) [concrete] +// CHECK:STDOUT: %.5d7: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.bound: = bound_method %float.d20, %Float.as.Copy.impl.Op.5b0 [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.specific_fn: = specific_function %Float.as.Copy.impl.Op.5b0, @Float.as.Copy.impl.Op(%int_64) [concrete] +// CHECK:STDOUT: %bound_method.40a: = bound_method %float.d20, %Float.as.Copy.impl.Op.specific_fn [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %type_where: type = facet_type > [concrete] +// CHECK:STDOUT: %facet_value: %type_where = facet_value %f64.d77, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.a4c: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.b46: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.a4c = struct_value () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.b46, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Float = %Core.Float +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Copy = %Core.Copy +// CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Float: %Float.type = import_ref Core//prelude/parts/float, Float, loaded [concrete = constants.%Float.generic] +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: %a.patt: %pattern_type.0ce = binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.0ce = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.0ce = binding_pattern r#return [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.0ce = value_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %a.param: %ptr.bcc = value_param call_param0 +// CHECK:STDOUT: %.1: type = splice_block constants.%ptr.bcc [concrete = constants.%ptr.bcc] { +// CHECK:STDOUT: %int_64.2: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] +// CHECK:STDOUT: %f64.2: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a: %ptr.bcc = bind_name a, %a.param +// CHECK:STDOUT: %return.param: %ptr.bcc = value_param call_param1 +// CHECK:STDOUT: %.2: type = splice_block constants.%ptr.bcc [concrete = constants.%ptr.bcc] { +// CHECK:STDOUT: %int_64.1: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] +// CHECK:STDOUT: %f64.1: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77] +// CHECK:STDOUT: } +// CHECK:STDOUT: %return: %ptr.bcc = bind_name r#return, %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.import_ref.5a0: @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type (%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.265) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert (constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.34c)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (%Core.import_ref.5a0), @Core.FloatLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] +// CHECK:STDOUT: %Core.import_ref.6cc: @Float.as.Copy.impl.%Float.as.Copy.impl.Op.type (%Float.as.Copy.impl.Op.type.89d) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Float.as.Copy.impl.%Float.as.Copy.impl.Op (constants.%Float.as.Copy.impl.Op.b4c)] +// CHECK:STDOUT: %Copy.impl_witness_table.3b9 = impl_witness_table (%Core.import_ref.6cc), @Float.as.Copy.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "floating_point_literal.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %d.patt: %pattern_type.0ae = binding_pattern d [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// 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: %float: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.674] +// CHECK:STDOUT: %impl.elem0.loc7_24.1: %.4b9 = impl_witness_access constants.%ImplicitAs.impl_witness.be7, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7] +// CHECK:STDOUT: %bound_method.loc7_24.1: = bound_method %float, %impl.elem0.loc7_24.1 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %specific_fn.loc7_24.1: = specific_function %impl.elem0.loc7_24.1, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc7_24.2: = bound_method %float, %specific_fn.loc7_24.1 [concrete = constants.%bound_method.8e3] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call: init %f64.d77 = call %bound_method.loc7_24.2(%float) [concrete = constants.%float.d20] +// CHECK:STDOUT: %.loc7_24.1: %f64.d77 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%float.d20] +// CHECK:STDOUT: %.loc7_24.2: %f64.d77 = converted %float, %.loc7_24.1 [concrete = constants.%float.d20] +// CHECK:STDOUT: %.loc7_24.3: ref %f64.d77 = temporary_storage +// CHECK:STDOUT: %impl.elem0.loc7_24.2: %.5d7 = impl_witness_access constants.%Copy.impl_witness.911, element0 [concrete = constants.%Float.as.Copy.impl.Op.5b0] +// CHECK:STDOUT: %bound_method.loc7_24.3: = bound_method %.loc7_24.2, %impl.elem0.loc7_24.2 [concrete = constants.%Float.as.Copy.impl.Op.bound] +// CHECK:STDOUT: %specific_fn.loc7_24.2: = specific_function %impl.elem0.loc7_24.2, @Float.as.Copy.impl.Op(constants.%int_64) [concrete = constants.%Float.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc7_24.4: = bound_method %.loc7_24.2, %specific_fn.loc7_24.2 [concrete = constants.%bound_method.40a] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.call: init %f64.d77 = call %bound_method.loc7_24.4(%.loc7_24.2) [concrete = constants.%float.d20] +// CHECK:STDOUT: %.loc7_24.4: ref %f64.d77 = temporary %.loc7_24.3, %Float.as.Copy.impl.Op.call +// CHECK:STDOUT: %addr.loc7_27.1: %ptr.bcc = addr_of %.loc7_24.4 +// CHECK:STDOUT: %.loc7_27.1: ref %f64.d77 = temporary_storage +// CHECK:STDOUT: %addr.loc7_27.2: %ptr.bcc = addr_of %.loc7_27.1 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc7_27.1, %addr.loc7_27.2) +// CHECK:STDOUT: %.loc7_27.2: init %f64.d77 = in_place_init %foo__carbon_thunk.call, %.loc7_27.1 +// CHECK:STDOUT: %.loc7_10: type = splice_block %f64 [concrete = constants.%f64.d77] { +// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] +// CHECK:STDOUT: %f64: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc7_27.3: %f64.d77 = value_of_initializer %.loc7_27.2 +// CHECK:STDOUT: %.loc7_27.4: %f64.d77 = converted %.loc7_27.2, %.loc7_27.3 +// CHECK:STDOUT: %d: %f64.d77 = bind_name d, %.loc7_27.4 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %.loc7_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.b46 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.b46, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc7_24.5: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr.loc7_24: %ptr.bcc = addr_of %.loc7_24.4 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc7_24.5(%addr.loc7_24) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @foo(%a.param: %f64.d77) -> %f64.d77; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @foo__carbon_thunk(%a.param: %ptr.bcc, %return.param: %ptr.bcc); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_import_large_floating_point_literal.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] +// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 18e307 [concrete] +// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete] +// CHECK:STDOUT: %Float.type: type = generic_class_type @Float [concrete] +// CHECK:STDOUT: %Float.generic: %Float.type = struct_value () [concrete] +// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic] +// CHECK:STDOUT: %f64.d77: type = class_type @Float, @Float(%int_64) [concrete] +// CHECK:STDOUT: %ptr.bcc: type = ptr_type %f64.d77 [concrete] +// CHECK:STDOUT: %pattern_type.0ce: type = pattern_type %ptr.bcc [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.73d: type = facet_type <@ImplicitAs, @ImplicitAs(%f64.d77)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.726: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%f64.d77) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.265: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.34c: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.265 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.be7: = impl_witness imports.%ImplicitAs.impl_witness_table, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.4d3: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.4d3 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.73d = facet_value Core.FloatLiteral, (%ImplicitAs.impl_witness.be7) [concrete] +// CHECK:STDOUT: %.4b9: type = fn_type_with_self_type %ImplicitAs.Convert.type.726, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound: = bound_method %float, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7 [concrete] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_64) [concrete] +// CHECK:STDOUT: %bound_method: = bound_method %float, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.type.89d: type = fn_type @Float.as.Copy.impl.Op, @Float.as.Copy.impl(%N) [symbolic] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.b4c: %Float.as.Copy.impl.Op.type.89d = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.911: = impl_witness imports.%Copy.impl_witness_table.3b9, @Float.as.Copy.impl(%int_64) [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.type.f9e: type = fn_type @Float.as.Copy.impl.Op, @Float.as.Copy.impl(%int_64) [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.5b0: %Float.as.Copy.impl.Op.type.f9e = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %f64.d77, (%Copy.impl_witness.911) [concrete] +// CHECK:STDOUT: %.5d7: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.specific_fn: = specific_function %Float.as.Copy.impl.Op.5b0, @Float.as.Copy.impl.Op(%int_64) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Float = %Core.Float +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Copy = %Core.Copy +// CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %Core.Float: %Float.type = import_ref Core//prelude/parts/float, Float, loaded [concrete = constants.%Float.generic] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: %a.patt: %pattern_type.0ce = binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.0ce = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.0ce = binding_pattern r#return [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.0ce = value_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %a.param: %ptr.bcc = value_param call_param0 +// CHECK:STDOUT: %.1: type = splice_block constants.%ptr.bcc [concrete = constants.%ptr.bcc] { +// CHECK:STDOUT: %int_64.2: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] +// CHECK:STDOUT: %f64.2: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a: %ptr.bcc = bind_name a, %a.param +// CHECK:STDOUT: %return.param: %ptr.bcc = value_param call_param1 +// CHECK:STDOUT: %.2: type = splice_block constants.%ptr.bcc [concrete = constants.%ptr.bcc] { +// CHECK:STDOUT: %int_64.1: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] +// CHECK:STDOUT: %f64.1: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77] +// CHECK:STDOUT: } +// CHECK:STDOUT: %return: %ptr.bcc = bind_name r#return, %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.import_ref.5a0: @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type (%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.265) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert (constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.34c)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (%Core.import_ref.5a0), @Core.FloatLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] +// CHECK:STDOUT: %Core.import_ref.6cc: @Float.as.Copy.impl.%Float.as.Copy.impl.Op.type (%Float.as.Copy.impl.Op.type.89d) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Float.as.Copy.impl.%Float.as.Copy.impl.Op (constants.%Float.as.Copy.impl.Op.b4c)] +// CHECK:STDOUT: %Copy.impl_witness_table.3b9 = impl_witness_table (%Core.import_ref.6cc), @Float.as.Copy.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Cpp = imports.%Cpp +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Cpp.import_cpp = import_cpp { +// CHECK:STDOUT: import Cpp "floating_point_literal.h" +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// 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: %float: Core.FloatLiteral = float_literal_value 18e307 [concrete = constants.%float] +// CHECK:STDOUT: %impl.elem0.loc15_11.1: %.4b9 = impl_witness_access constants.%ImplicitAs.impl_witness.be7, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.8b7] +// CHECK:STDOUT: %bound_method.loc15_11.1: = bound_method %float, %impl.elem0.loc15_11.1 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %specific_fn.loc15_11.1: = specific_function %impl.elem0.loc15_11.1, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc15_11.2: = bound_method %float, %specific_fn.loc15_11.1 [concrete = constants.%bound_method] +// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call: init %f64.d77 = call %bound_method.loc15_11.2(%float) [concrete = ] +// CHECK:STDOUT: %.loc15_11.1: %f64.d77 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call [concrete = ] +// CHECK:STDOUT: %.loc15_11.2: %f64.d77 = converted %float, %.loc15_11.1 [concrete = ] +// CHECK:STDOUT: %.loc15_11.3: ref %f64.d77 = temporary_storage +// CHECK:STDOUT: %impl.elem0.loc15_11.2: %.5d7 = impl_witness_access constants.%Copy.impl_witness.911, element0 [concrete = constants.%Float.as.Copy.impl.Op.5b0] +// CHECK:STDOUT: %bound_method.loc15_11.3: = bound_method %.loc15_11.2, %impl.elem0.loc15_11.2 [concrete = ] +// CHECK:STDOUT: %specific_fn.loc15_11.2: = specific_function %impl.elem0.loc15_11.2, @Float.as.Copy.impl.Op(constants.%int_64) [concrete = constants.%Float.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc15_11.4: = bound_method %.loc15_11.2, %specific_fn.loc15_11.2 [concrete = ] +// CHECK:STDOUT: %Float.as.Copy.impl.Op.call: init %f64.d77 = call %bound_method.loc15_11.4(%.loc15_11.2) [concrete = ] +// CHECK:STDOUT: %.loc15_11.4: ref %f64.d77 = temporary %.loc15_11.3, %Float.as.Copy.impl.Op.call [concrete = ] +// CHECK:STDOUT: %addr.loc15_19.1: %ptr.bcc = addr_of %.loc15_11.4 [concrete = ] +// CHECK:STDOUT: %.loc15_19.1: ref %f64.d77 = temporary_storage +// CHECK:STDOUT: %addr.loc15_19.2: %ptr.bcc = addr_of %.loc15_19.1 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc15_19.1, %addr.loc15_19.2) +// CHECK:STDOUT: %.loc15_19.2: init %f64.d77 = in_place_init %foo__carbon_thunk.call, %.loc15_19.1 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @foo(%a.param: %f64.d77) -> %f64.d77; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @foo__carbon_thunk(%a.param: %ptr.bcc, %return.param: %ptr.bcc); +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_import_struct_literal_call_arg.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants {