Skip to content

Conversation

@ivanaivanovska
Copy link
Contributor

Following the C++ standard rules for assigning a type to a decimal integer literal, when a Carbon integer literal is passed as a call argument to a C++ function and it is too big to fit to int, long or long long, it is assigned an extended integer type (_int128). Discussed in the interop meeting and documented in this design doc.

Part of #5915

@ivanaivanovska ivanaivanovska requested a review from a team as a code owner October 16, 2025 10:04
@ivanaivanovska ivanaivanovska requested review from danakj and removed request for a team October 16, 2025 10:04
unsigned arg_non_sign_bits =
context.ints().Get(arg.int_id).getSignificantBits() - 1;
llvm::APInt arg_val = context.ints().Get(arg.int_id);
unsigned arg_non_sign_bits = arg_val.getSignificantBits() - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unsigned arg_non_sign_bits = arg_val.getSignificantBits() - 1;
int arg_non_sign_bits = arg_val.getSignificantBits() - 1;

nit: I think the google style guide wants use to use int here since the value is clearly in range.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Thanks.

Comment on lines 56 to 57
"integer value {0} too large to be fitted in any "
"supported signed C++ type, max supported _int128",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about something like this:

Suggested change
"integer value {0} too large to be fitted in any "
"supported signed C++ type, max supported _int128",
"integer value {0} too large to fit in a signed C++ integer type; requires {1} bits, but max is 128",

where {1} is arg_non_sign_bits + 1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sg, done.

TypedInt);
context.emitter().Emit(arg_id, IntTooLargeForCppType,
{.type = arg.type_id, .value = arg_val});
return IntId::MakeRaw(128);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally we want to turn anything where we diagnosed an error into an ErrorInst, which we then use as a signal to avoid diagnosing more errors against the same piece of code.

There is no IntId::Error though, so I understand why you'd make this choice here. The result is that we might diagnose multiple errors against this same integer though.

It's also a little inconsistent with the choice for arg_const_id == SemIR::ErrorInst::ConstantId where if we saw an error we return None, but if we generate an error we return 128.

I think the latter looks the most odd to me. What do you think of returning None here when we make an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sg. As you say it's more consistent with the other error cases, and also I find it good that it doesn't continue with the type i128 to look for the best overload.

How do you find the follow-up message in the test fail_import_large_int_literal.carbon though - call argument of type ``Core.IntLiteral`` is not supported? Shall we add the bit width as well, or the previous message contains enough information about the size?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want two errors for the same piece of code, and we use ErrorInst to signal that something was diagnosed normally. Maybe we need to turn a None into an ErrorInst later, or we need to return an extra bit (an optional maybe?) to signify the difference of returning an error vs returning None in other cases, if nothing was diagnosed (like when it's symbolic?).

For now, we can put a TODO on the second error in the test , saying that we want to get rid of it. And we can follow up to do that in another PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks!

Copy link
Contributor

@danakj danakj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (assuming this is ready for review again, though the re-review button wasn't triggered)

@ivanaivanovska ivanaivanovska added this pull request to the merge queue Oct 28, 2025
Merged via the queue into carbon-language:trunk with commit 5e0201e Oct 28, 2025
8 checks passed
@ivanaivanovska ivanaivanovska deleted the big_integer_literals branch October 28, 2025 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants