From 74abc7db390be68875e380eeb598de1e2f799294 Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Mon, 24 Nov 2025 08:37:49 -0300 Subject: [PATCH 01/11] Adding support for i32-to-char conversion --- core/prelude/types/char.carbon | 4 ++ toolchain/check/eval.cpp | 57 +++++++++++++++++++--- toolchain/lower/handle_call.cpp | 1 + toolchain/sem_ir/builtin_function_kind.cpp | 6 +++ toolchain/sem_ir/builtin_function_kind.def | 1 + 5 files changed, 61 insertions(+), 8 deletions(-) diff --git a/core/prelude/types/char.carbon b/core/prelude/types/char.carbon index 4268755274666..7799d6210e40f 100644 --- a/core/prelude/types/char.carbon +++ b/core/prelude/types/char.carbon @@ -27,3 +27,7 @@ impl CharLiteral() as ImplicitAs(Char) { impl CharLiteral() as As(Char) { fn Convert[self: Self]() -> Char = "char.convert_checked"; } + +impl Int(32) as As(Char) { + fn Convert[self: Self]() -> Char = "int.convert_char"; +} \ No newline at end of file diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 5e08925158f3c..a4e54c8df25d5 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -867,14 +867,6 @@ static auto ResolveSpecificDeclForInst(EvalContext& eval_context, for (const auto& interface : info.self_impls_constraints) { ResolveSpecificDeclForSpecificId(eval_context, interface.specific_id); } - for (const auto& constraint : info.extend_named_constraints) { - ResolveSpecificDeclForSpecificId(eval_context, - constraint.specific_id); - } - for (const auto& constraint : info.self_impls_named_constraints) { - ResolveSpecificDeclForSpecificId(eval_context, - constraint.specific_id); - } break; } case CARBON_KIND(SemIR::SpecificId specific_id): { @@ -991,6 +983,7 @@ static auto PerformCheckedCharConvert(Context& context, SemIR::LocId loc_id, SemIR::InstId arg_id, SemIR::TypeId dest_type_id) -> SemIR::ConstantId { + auto arg = context.insts().GetAs(arg_id); // Values over 0x80 require multiple code units in UTF-8. @@ -1035,6 +1028,48 @@ static auto MakeFloatTypeResult(Context& context, SemIR::LocId loc_id, return MakeConstantResult(context, result, phase); } +//// Performs a conversion from integer to character type. +// Performs a conversion between character types, diagnosing if the value +// doesn't fit in the destination type. +static auto PerformCharConvert(Context& context, SemIR::LocId loc_id, + SemIR::InstId arg_id, + SemIR::TypeId dest_type_id) + -> SemIR::ConstantId { + + auto arg = context.insts().GetAs(arg_id); + auto arg_val = context.ints().Get(arg.int_id); + + auto [is_signed, bit_width_id] = + context.sem_ir().types().GetIntTypeInfo(dest_type_id); + + if (!is_signed && arg_val.isNegative()) { + CARBON_DIAGNOSTIC( + NegativeIntInUnsignedType, Error, + "negative integer value {0} converted to unsigned type {1}", TypedInt, + SemIR::TypeId); + context.emitter().Emit(loc_id, NegativeIntInUnsignedType, + {.type = arg.type_id, .value = arg_val}, + dest_type_id); + } + + int64_t value = arg_val.getSExtValue(); + + // Values over 0x80 require multiple code units in UTF-8. + if (value >= 0x80) { + CARBON_DIAGNOSTIC( + NegativeIntInUnsignedType, Error, + "character value {0} too large for type {1}", TypedInt, + SemIR::TypeId); + context.emitter().Emit(loc_id, NegativeIntInUnsignedType, + {.type = arg.type_id, .value = arg_val}, + dest_type_id); + return SemIR::ErrorInst::ConstantId; + } + + llvm::APInt int_val(8, value, /*isSigned=*/false); + return MakeIntResult(context, dest_type_id, /*is_signed=*/false, int_val); +} + // Performs a conversion between integer types, truncating if the value doesn't // fit in the destination type. static auto PerformIntConvert(Context& context, SemIR::InstId arg_id, @@ -1820,6 +1855,12 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, } // Integer conversions. + case SemIR::BuiltinFunctionKind::IntConvertChar: { + if (phase != Phase::Concrete) { + return MakeConstantResult(context, call, phase); + } + return PerformCharConvert(context, loc_id, arg_ids[0], call.type_id); + } case SemIR::BuiltinFunctionKind::IntConvert: { if (phase != Phase::Concrete) { return MakeConstantResult(context, call, phase); diff --git a/toolchain/lower/handle_call.cpp b/toolchain/lower/handle_call.cpp index 381e0f31df654..e09e1cab14761 100644 --- a/toolchain/lower/handle_call.cpp +++ b/toolchain/lower/handle_call.cpp @@ -331,6 +331,7 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id, context.SetLocal(inst_id, context.GetTypeAsValue()); return; + case SemIR::BuiltinFunctionKind::IntConvertChar: case SemIR::BuiltinFunctionKind::IntConvert: { context.SetLocal(inst_id, CreateExtOrTrunc(context, context.GetValue(arg_ids[0]), diff --git a/toolchain/sem_ir/builtin_function_kind.cpp b/toolchain/sem_ir/builtin_function_kind.cpp index 5d773937d46a0..6e34e21f51fc9 100644 --- a/toolchain/sem_ir/builtin_function_kind.cpp +++ b/toolchain/sem_ir/builtin_function_kind.cpp @@ -373,6 +373,7 @@ constexpr BuiltinInfo PrintInt = { constexpr BuiltinInfo ReadChar = {"read.char", ValidateSignatureAnySizedInt>}; + // Returns the `Core.CharLiteral` type. constexpr BuiltinInfo CharLiteralMakeType = {"char_literal.make_type", ValidateSignatureType>}; @@ -411,6 +412,10 @@ constexpr BuiltinInfo CharConvertChecked = { "char.convert_checked", ValidateSignatureCharCompatible>}; +// Converts from an integer type to a char-compatible type (u8/adapted Char). +constexpr BuiltinInfo IntConvertChar = {"int.convert_char", + ValidateSignatureCharCompatible>}; + // Converts between integer types, truncating if necessary. constexpr BuiltinInfo IntConvert = {"int.convert", ValidateSignatureAnyInt>}; @@ -784,6 +789,7 @@ auto BuiltinFunctionKind::IsCompTimeOnly(const File& sem_ir, // Checked conversions are compile-time only. return true; + case IntConvertChar: case IntConvert: case IntSNegate: case IntComplement: diff --git a/toolchain/sem_ir/builtin_function_kind.def b/toolchain/sem_ir/builtin_function_kind.def index d0b1306fffd5a..e868085232b2d 100644 --- a/toolchain/sem_ir/builtin_function_kind.def +++ b/toolchain/sem_ir/builtin_function_kind.def @@ -45,6 +45,7 @@ CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(MaybeUnformedMakeType) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(CharConvertChecked) // Integer conversion. +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvertChar) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvert) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvertChecked) From c7c60a7eaefba03127f4ba832155f4065111a276 Mon Sep 17 00:00:00 2001 From: Vinicius Silva Date: Mon, 24 Nov 2025 13:07:03 -0300 Subject: [PATCH 02/11] Update toolchain/check/eval.cpp Co-authored-by: Dana Jansens --- toolchain/check/eval.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index a4e54c8df25d5..3a49fc41d000d 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -983,7 +983,6 @@ static auto PerformCheckedCharConvert(Context& context, SemIR::LocId loc_id, SemIR::InstId arg_id, SemIR::TypeId dest_type_id) -> SemIR::ConstantId { - auto arg = context.insts().GetAs(arg_id); // Values over 0x80 require multiple code units in UTF-8. From 6efd96c7ae207dacb63c9e96cbb7588fea2a0371 Mon Sep 17 00:00:00 2001 From: Vinicius Silva Date: Mon, 24 Nov 2025 13:16:54 -0300 Subject: [PATCH 03/11] Update toolchain/check/eval.cpp Co-authored-by: Dana Jansens --- toolchain/check/eval.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 3a49fc41d000d..e03bd5a67bc2c 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -1030,7 +1030,7 @@ static auto MakeFloatTypeResult(Context& context, SemIR::LocId loc_id, //// Performs a conversion from integer to character type. // Performs a conversion between character types, diagnosing if the value // doesn't fit in the destination type. -static auto PerformCharConvert(Context& context, SemIR::LocId loc_id, +static auto PerformIntToCharConvert(Context& context, SemIR::LocId loc_id, SemIR::InstId arg_id, SemIR::TypeId dest_type_id) -> SemIR::ConstantId { From 4423c5cea4d573b7005a64d7143dff1f5fcc2d6b Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Mon, 24 Nov 2025 16:43:07 -0300 Subject: [PATCH 04/11] Implementing support i8, i32, and i64 to char --- core/prelude/types/char.carbon | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/prelude/types/char.carbon b/core/prelude/types/char.carbon index 7799d6210e40f..ef698d915ea58 100644 --- a/core/prelude/types/char.carbon +++ b/core/prelude/types/char.carbon @@ -8,6 +8,8 @@ import library "prelude/copy"; import library "prelude/destroy"; import library "prelude/operators"; import library "prelude/types/uint"; +import library "prelude/types/int"; +import library "prelude/types/int_literal"; fn CharLiteral() -> type = "char_literal.make_type"; @@ -28,6 +30,14 @@ impl CharLiteral() as As(Char) { fn Convert[self: Self]() -> Char = "char.convert_checked"; } +impl Int(8) as As(Char) { + fn Convert[self: Self]() -> Char = "int.convert_char"; +} + impl Int(32) as As(Char) { - fn Convert[self: Self]() -> Char = "int.convert_char"; + fn Convert[self: Self]() -> Char = "int.convert_char"; +} + +impl Int(64) as As(Char) { + fn Convert[self: Self]() -> Char = "int.convert_char"; } \ No newline at end of file From 088d9767a0b76917adb43f42478101c776f46c22 Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Mon, 24 Nov 2025 16:44:09 -0300 Subject: [PATCH 05/11] Applying suggestions from PR #6425 --- toolchain/sem_ir/builtin_function_kind.cpp | 2 +- toolchain/sem_ir/builtin_function_kind.def | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/toolchain/sem_ir/builtin_function_kind.cpp b/toolchain/sem_ir/builtin_function_kind.cpp index 6e34e21f51fc9..fe0feaf0212f2 100644 --- a/toolchain/sem_ir/builtin_function_kind.cpp +++ b/toolchain/sem_ir/builtin_function_kind.cpp @@ -789,8 +789,8 @@ auto BuiltinFunctionKind::IsCompTimeOnly(const File& sem_ir, // Checked conversions are compile-time only. return true; - case IntConvertChar: case IntConvert: + case IntConvertChar: case IntSNegate: case IntComplement: case IntSAdd: diff --git a/toolchain/sem_ir/builtin_function_kind.def b/toolchain/sem_ir/builtin_function_kind.def index e868085232b2d..5562eb2180775 100644 --- a/toolchain/sem_ir/builtin_function_kind.def +++ b/toolchain/sem_ir/builtin_function_kind.def @@ -45,8 +45,8 @@ CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(MaybeUnformedMakeType) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(CharConvertChecked) // Integer conversion. -CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvertChar) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvert) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvertChar) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvertChecked) // Integer arithmetic. From 0f722b6c6d059a79e1377605d8915da22e58ebaa Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Mon, 24 Nov 2025 16:45:08 -0300 Subject: [PATCH 06/11] Inserting a section mistakenly removed from eval.cpp --- toolchain/check/eval.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index e03bd5a67bc2c..2518ba2d2badb 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -854,10 +854,10 @@ static auto ResolveSpecificDeclForSpecificId(EvalContext& eval_context, static auto ResolveSpecificDeclForInst(EvalContext& eval_context, const SemIR::Inst& inst) -> void { for (auto arg_and_kind : {inst.arg0_and_kind(), inst.arg1_and_kind()}) { - // This switch must handle any field type that has a GetConstantValue() - // overload which canonicalizes a specific (and thus potentially forms a new - // specific) as part of forming its constant value. - CARBON_KIND_SWITCH(arg_and_kind) { + // This switch must handle any field type that has a GetConstantValue() + // overload which canonicalizes a specific (and thus potentially forms a new + // specific) as part of forming its constant value. + CARBON_KIND_SWITCH(arg_and_kind) { case CARBON_KIND(SemIR::FacetTypeId facet_type_id): { const auto& info = eval_context.context().facet_types().Get(facet_type_id); @@ -867,6 +867,14 @@ static auto ResolveSpecificDeclForInst(EvalContext& eval_context, for (const auto& interface : info.self_impls_constraints) { ResolveSpecificDeclForSpecificId(eval_context, interface.specific_id); } + for (const auto& constraint : info.extend_named_constraints) { + ResolveSpecificDeclForSpecificId(eval_context, + constraint.specific_id); + } + for (const auto& constraint : info.self_impls_named_constraints) { + ResolveSpecificDeclForSpecificId(eval_context, + constraint.specific_id); + } break; } case CARBON_KIND(SemIR::SpecificId specific_id): { @@ -1858,7 +1866,7 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, if (phase != Phase::Concrete) { return MakeConstantResult(context, call, phase); } - return PerformCharConvert(context, loc_id, arg_ids[0], call.type_id); + return PerformIntToCharConvert(context, loc_id, arg_ids[0], call.type_id); } case SemIR::BuiltinFunctionKind::IntConvert: { if (phase != Phase::Concrete) { From c17f6ad5e383b820384dd6e4283a243247444f97 Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Mon, 24 Nov 2025 23:03:54 -0300 Subject: [PATCH 07/11] Removing restriction for greater equal than 128 integer --- toolchain/check/eval.cpp | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 2518ba2d2badb..bd954d66bbb4e 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -854,10 +854,10 @@ static auto ResolveSpecificDeclForSpecificId(EvalContext& eval_context, static auto ResolveSpecificDeclForInst(EvalContext& eval_context, const SemIR::Inst& inst) -> void { for (auto arg_and_kind : {inst.arg0_and_kind(), inst.arg1_and_kind()}) { - // This switch must handle any field type that has a GetConstantValue() - // overload which canonicalizes a specific (and thus potentially forms a new - // specific) as part of forming its constant value. - CARBON_KIND_SWITCH(arg_and_kind) { + // This switch must handle any field type that has a GetConstantValue() + // overload which canonicalizes a specific (and thus potentially forms a new + // specific) as part of forming its constant value. + CARBON_KIND_SWITCH(arg_and_kind) { case CARBON_KIND(SemIR::FacetTypeId facet_type_id): { const auto& info = eval_context.context().facet_types().Get(facet_type_id); @@ -1036,36 +1036,22 @@ static auto MakeFloatTypeResult(Context& context, SemIR::LocId loc_id, } //// Performs a conversion from integer to character type. -// Performs a conversion between character types, diagnosing if the value -// doesn't fit in the destination type. static auto PerformIntToCharConvert(Context& context, SemIR::LocId loc_id, - SemIR::InstId arg_id, - SemIR::TypeId dest_type_id) + SemIR::InstId arg_id, + SemIR::TypeId dest_type_id) -> SemIR::ConstantId { - auto arg = context.insts().GetAs(arg_id); auto arg_val = context.ints().Get(arg.int_id); auto [is_signed, bit_width_id] = context.sem_ir().types().GetIntTypeInfo(dest_type_id); - - if (!is_signed && arg_val.isNegative()) { - CARBON_DIAGNOSTIC( - NegativeIntInUnsignedType, Error, - "negative integer value {0} converted to unsigned type {1}", TypedInt, - SemIR::TypeId); - context.emitter().Emit(loc_id, NegativeIntInUnsignedType, - {.type = arg.type_id, .value = arg_val}, - dest_type_id); - } - + int64_t value = arg_val.getSExtValue(); - // Values over 0x80 require multiple code units in UTF-8. - if (value >= 0x80) { + if (!is_signed && value < 0) { CARBON_DIAGNOSTIC( NegativeIntInUnsignedType, Error, - "character value {0} too large for type {1}", TypedInt, + "negative integer value {0} converted to unsigned type {1}", TypedInt, SemIR::TypeId); context.emitter().Emit(loc_id, NegativeIntInUnsignedType, {.type = arg.type_id, .value = arg_val}, @@ -1863,7 +1849,7 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, // Integer conversions. case SemIR::BuiltinFunctionKind::IntConvertChar: { - if (phase != Phase::Concrete) { + if (phase != Phase::Concrete) { return MakeConstantResult(context, call, phase); } return PerformIntToCharConvert(context, loc_id, arg_ids[0], call.type_id); From 7366715672cbdf777d11993afea1f146904b3aa0 Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Mon, 24 Nov 2025 23:05:43 -0300 Subject: [PATCH 08/11] pre-commit changes applied --- core/prelude/types/char.carbon | 2 +- toolchain/sem_ir/builtin_function_kind.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/prelude/types/char.carbon b/core/prelude/types/char.carbon index ef698d915ea58..ea3a04c6576e5 100644 --- a/core/prelude/types/char.carbon +++ b/core/prelude/types/char.carbon @@ -40,4 +40,4 @@ impl Int(32) as As(Char) { impl Int(64) as As(Char) { fn Convert[self: Self]() -> Char = "int.convert_char"; -} \ No newline at end of file +} diff --git a/toolchain/sem_ir/builtin_function_kind.cpp b/toolchain/sem_ir/builtin_function_kind.cpp index fe0feaf0212f2..dfb721166c3a8 100644 --- a/toolchain/sem_ir/builtin_function_kind.cpp +++ b/toolchain/sem_ir/builtin_function_kind.cpp @@ -373,7 +373,6 @@ constexpr BuiltinInfo PrintInt = { constexpr BuiltinInfo ReadChar = {"read.char", ValidateSignatureAnySizedInt>}; - // Returns the `Core.CharLiteral` type. constexpr BuiltinInfo CharLiteralMakeType = {"char_literal.make_type", ValidateSignatureType>}; @@ -413,8 +412,8 @@ constexpr BuiltinInfo CharConvertChecked = { ValidateSignatureCharCompatible>}; // Converts from an integer type to a char-compatible type (u8/adapted Char). -constexpr BuiltinInfo IntConvertChar = {"int.convert_char", - ValidateSignatureCharCompatible>}; +constexpr BuiltinInfo IntConvertChar = { + "int.convert_char", ValidateSignatureCharCompatible>}; // Converts between integer types, truncating if necessary. constexpr BuiltinInfo IntConvert = {"int.convert", From 0b49ba98f62ad4421e4913a1d9b480e60d1cfd83 Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Tue, 25 Nov 2025 16:06:48 -0300 Subject: [PATCH 09/11] Creating tests --- .../testdata/builtins/int/convert.carbon | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/toolchain/check/testdata/builtins/int/convert.carbon b/toolchain/check/testdata/builtins/int/convert.carbon index 64ae546a701d8..61ae3c483220a 100644 --- a/toolchain/check/testdata/builtins/int/convert.carbon +++ b/toolchain/check/testdata/builtins/int/convert.carbon @@ -297,3 +297,47 @@ let convert_not_constant: i16 = IntLiteralToInt16(not_constant); // CHECK:STDOUT: return %Int32ToInt64.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: + +// --- int_to_char_basic.carbon + +library "[[@TEST_NAME]]"; +import library "int_ops"; + +fn F() { + // Basic ASCII range + Test(Int32ToChar(0)) as Expect(0 as char); + Test(Int32ToChar(10)) as Expect(10 as char); + Test(Int32ToChar(32)) as Expect(32 as char); + Test(Int32ToChar(65)) as Expect(65 as char); + Test(Int32ToChar(97)) as Expect(97 as char); + Test(Int32ToChar(0x7F)) as Expect(0x7F as char); + + // UTF-8 single-byte values (128–255) + Test(Int32ToChar(0x80)) as Expect(0x80 as char); + Test(Int32ToChar(0x90)) as Expect(0x90 as char); + Test(Int32ToChar(0xA0)) as Expect(0xA0 as char); + Test(Int32ToChar(0xC0)) as Expect(0xC0 as char); + Test(Int32ToChar(0xE0)) as Expect(0xE0 as char); + Test(Int32ToChar(0xFF)) as Expect(0xFF as char); + + // Negative values → must error (same style as sign_extend test) + // CHECK:STDERR: int_to_char_basic.carbon:[[@LINE+3]]:30: error: cannot convert negative integer to `char` [InvalidIntToChar] + // CHECK:STDERR: var bad1: char = (-1 as char); + // CHECK:STDERR: ^~~ + var bad1: char = (-1 as char); + + // CHECK:STDERR: int_to_char_basic.carbon:[[@LINE+3]]:30: error: cannot convert negative integer to `char` [InvalidIntToChar] + // CHECK:STDERR: var bad2: char = (-10 as char); + // CHECK:STDERR: ^~~ + var bad2: char = (-10 as char); + + // CHECK:STDERR: int_to_char_basic.carbon:[[@LINE+3]]:30: error: cannot convert negative integer to `char` [InvalidIntToChar] + // CHECK:STDERR: var bad3: char = (-255 as char); + // CHECK:STDERR: ^~~ + var bad3: char = (-255 as char); + + // CHECK:STDERR: int_to_char_basic.carbon:[[@LINE+3]]:30: error: cannot convert negative integer to `char` [InvalidIntToChar] + // CHECK:STDERR: var bad4: char = (-2147483648 as char); + // CHECK:STDERR: ^~~ + var bad4: char = (-2147483648 as char); +} \ No newline at end of file From 6da16ea40508e702b8bb9cf12421a798ae358c4e Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Tue, 25 Nov 2025 16:08:13 -0300 Subject: [PATCH 10/11] Formating test file --- toolchain/check/testdata/builtins/int/convert.carbon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/testdata/builtins/int/convert.carbon b/toolchain/check/testdata/builtins/int/convert.carbon index 61ae3c483220a..67ca12b40ce07 100644 --- a/toolchain/check/testdata/builtins/int/convert.carbon +++ b/toolchain/check/testdata/builtins/int/convert.carbon @@ -340,4 +340,4 @@ fn F() { // CHECK:STDERR: var bad4: char = (-2147483648 as char); // CHECK:STDERR: ^~~ var bad4: char = (-2147483648 as char); -} \ No newline at end of file +} From edefca7dee5f62cfe75d8475ef34d81b3e6c71e6 Mon Sep 17 00:00:00 2001 From: Vinicius da Silva Date: Tue, 25 Nov 2025 16:25:56 -0300 Subject: [PATCH 11/11] Adding NegativeIntInUnsignedTypeInCast diagnostic name --- toolchain/check/eval.cpp | 4 ++-- toolchain/diagnostics/diagnostic_kind.def | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index bd954d66bbb4e..b9580febf2376 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -1050,10 +1050,10 @@ static auto PerformIntToCharConvert(Context& context, SemIR::LocId loc_id, if (!is_signed && value < 0) { CARBON_DIAGNOSTIC( - NegativeIntInUnsignedType, Error, + NegativeIntInUnsignedTypeInCast, Error, "negative integer value {0} converted to unsigned type {1}", TypedInt, SemIR::TypeId); - context.emitter().Emit(loc_id, NegativeIntInUnsignedType, + context.emitter().Emit(loc_id, NegativeIntInUnsignedTypeInCast, {.type = arg.type_id, .value = arg_val}, dest_type_id); return SemIR::ErrorInst::ConstantId; diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 377d24857c305..2f04a0a2fbcaf 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -448,6 +448,7 @@ CARBON_DIAGNOSTIC_KIND(IntWidthNotPositive) CARBON_DIAGNOSTIC_KIND(IntWidthTooLarge) CARBON_DIAGNOSTIC_KIND(InvalidArrayExpr) CARBON_DIAGNOSTIC_KIND(NegativeIntInUnsignedType) +CARBON_DIAGNOSTIC_KIND(NegativeIntInUnsignedTypeInCast) CARBON_DIAGNOSTIC_KIND(NonConstantCallToCompTimeOnlyFunction) CARBON_DIAGNOSTIC_KIND(CompTimeOnlyFunctionHere) CARBON_DIAGNOSTIC_KIND(SelfOutsideImplicitParamList)