mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Support parse/check/lower for char (#5901)
toolchain/check/testdata/builtins/char/basics.carbon and toolchain/lower/testdata/builtins/char.carbon are probably the most interesting tests here. The parse tests is required because this adds a new node kind, and we need coverage of it; but the attached info is minor. There's a fair amount of test churn here because I'm adding the Core.Char and Core.CharLiteral types as new singletons. My intent here is that `CharId` is always a unicode code point, even when the type is a `Char` and thus must be a single UTF-8 code unit (single byte). This mainly means the stored value of a `CharValue` can be printed internally without knowing the type. --------- Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
josh11b
Richard Smith
parent
9c7e0f6bd5
commit
37d5046ceb
@@ -95,6 +95,26 @@ struct NoReturn {
|
||||
// Constraint that a type is `bool`.
|
||||
using Bool = BuiltinType<BoolType::TypeInstId>;
|
||||
|
||||
// Constraint that a type is `Core.CharLiteral`.
|
||||
using CharLiteral = BuiltinType<CharLiteralType::TypeInstId>;
|
||||
|
||||
// Constraint that a type is `u8` or an adapted type, including `Core.Char`.
|
||||
struct CharCompatible {
|
||||
static auto Check(const File& sem_ir, ValidateState& /*state*/,
|
||||
TypeId type_id) -> bool {
|
||||
auto int_info = sem_ir.types().TryGetIntTypeInfo(type_id);
|
||||
if (!int_info) {
|
||||
// Not an integer.
|
||||
return false;
|
||||
}
|
||||
if (!int_info->bit_width.has_value() || int_info->is_signed) {
|
||||
// Must be unsigned.
|
||||
return false;
|
||||
}
|
||||
return sem_ir.ints().Get(int_info->bit_width) == 8;
|
||||
}
|
||||
};
|
||||
|
||||
// Constraint that requires the type to be a sized integer type.
|
||||
struct AnySizedInt {
|
||||
static auto Check(const File& sem_ir, ValidateState& /*state*/,
|
||||
@@ -248,6 +268,10 @@ constexpr BuiltinInfo PrintInt = {
|
||||
constexpr BuiltinInfo ReadChar = {"read.char",
|
||||
ValidateSignature<auto()->AnySizedInt>};
|
||||
|
||||
// Returns the `Core.CharLiteral` type.
|
||||
constexpr BuiltinInfo CharLiteralMakeType = {"char_literal.make_type",
|
||||
ValidateSignature<auto()->Type>};
|
||||
|
||||
// Returns the `Core.IntLiteral` type.
|
||||
constexpr BuiltinInfo IntLiteralMakeType = {"int_literal.make_type",
|
||||
ValidateSignature<auto()->Type>};
|
||||
@@ -269,6 +293,11 @@ constexpr BuiltinInfo FloatMakeType = {"float.make_type",
|
||||
constexpr BuiltinInfo BoolMakeType = {"bool.make_type",
|
||||
ValidateSignature<auto()->Type>};
|
||||
|
||||
// Converts between char types, with a diagnostic if the value doesn't fit.
|
||||
constexpr BuiltinInfo CharConvertChecked = {
|
||||
"char.convert_checked",
|
||||
ValidateSignature<auto(CharLiteral)->CharCompatible>};
|
||||
|
||||
// Converts between integer types, truncating if necessary.
|
||||
constexpr BuiltinInfo IntConvert = {"int.convert",
|
||||
ValidateSignature<auto(AnyInt)->AnyInt>};
|
||||
@@ -578,8 +607,9 @@ auto BuiltinFunctionKind::IsCompTimeOnly(const File& sem_ir,
|
||||
llvm::ArrayRef<InstId> arg_ids,
|
||||
TypeId return_type_id) const -> bool {
|
||||
switch (*this) {
|
||||
case CharConvertChecked:
|
||||
case IntConvertChecked:
|
||||
// Checked integer conversions are compile-time only.
|
||||
// Checked conversions are compile-time only.
|
||||
return true;
|
||||
|
||||
case IntConvert:
|
||||
|
||||
Reference in New Issue
Block a user