From 04076c39f7a94cade9c5a42036d024ab8ab79220 Mon Sep 17 00:00:00 2001 From: Mindy Batek Date: Tue, 26 May 2026 02:25:55 +0200 Subject: [PATCH 1/2] Implement trait `getBuiltIn` --- compiler/src/dmd/frontend.h | 1 + compiler/src/dmd/id.d | 1 + compiler/src/dmd/traits.d | 38 ++++++++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index dbdc758be9..9d0dbeabef 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -8844,6 +8844,7 @@ struct Id final static Identifier* outp; static Identifier* outpl; static Identifier* outpw; + static Identifier* getBuiltIn; static Identifier* isAbstractClass; static Identifier* isArithmetic; static Identifier* isAssociativeArray; diff --git a/compiler/src/dmd/id.d b/compiler/src/dmd/id.d index 51d850fa6d..cf62f2cabb 100644 --- a/compiler/src/dmd/id.d +++ b/compiler/src/dmd/id.d @@ -456,6 +456,7 @@ immutable Msgtable[] msgtable = { "outpw"}, // Traits + { "getBuiltIn" }, { "isAbstractClass" }, { "isArithmetic" }, { "isAssociativeArray" }, diff --git a/compiler/src/dmd/traits.d b/compiler/src/dmd/traits.d index cd49e51189..358fe4092f 100644 --- a/compiler/src/dmd/traits.d +++ b/compiler/src/dmd/traits.d @@ -440,6 +440,41 @@ Expression semanticTraits(TraitsExp e, Scope* sc) }); } + if (e.ident == Id.getBuiltIn) + { + if (dim != 1) + return dimError(1); + + auto exNeedle = isExpression((*e.args)[0]); + if (!exNeedle) + { + error(e.loc, "expression expected as first argument of __traits `%s`", e.ident.toChars()); + return ErrorExp.get(); + } + exNeedle = exNeedle.ctfeInterpret(); + + StringExp seNeedle = exNeedle.toStringExp(); + if (!seNeedle || seNeedle.len == 0) + { + error(e.loc, "string expected as first argument of __traits `%s` instead of `%s`", e.ident.toChars(), exNeedle.toChars()); + return ErrorExp.get(); + } + seNeedle = seNeedle.toUTF8(sc); + + if (seNeedle.sz != 1) + { + error(e.loc, "string must be chars"); + return ErrorExp.get(); + } + const builtInName = seNeedle.peekString(); + + switch(builtInName) + { + default: + error(e.loc, "`%.*s` is not a retrievable built-in", cast(int) builtInName.length, builtInName.ptr); + return ErrorExp.get(); + } + } if (e.ident == Id.isArithmetic) { return isTypeX(t => t.isintegral() || t.isfloating()); @@ -2499,7 +2534,7 @@ private void traitNotFound(TraitsExp e) @system initialized = true; // lazy initialization // All possible traits - __gshared Identifier*[62] idents = + __gshared Identifier*[63] idents = [ &Id.allMembers, &Id.child, @@ -2510,6 +2545,7 @@ private void traitNotFound(TraitsExp e) @system &Id.fullyQualifiedName, &Id.getAliasThis, &Id.getAttributes, + &Id.getBuiltIn, &Id.getFunctionAttributes, &Id.getFunctionVariadicStyle, &Id.getLinkage, From 86b813b7c9655d4e3bfd0ee664c2518ec0345e22 Mon Sep 17 00:00:00 2001 From: Mindy Batek Date: Tue, 26 May 2026 03:29:44 +0200 Subject: [PATCH 2/2] Add integer types to trait `getBuiltIn` --- compiler/src/dmd/traits.d | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/compiler/src/dmd/traits.d b/compiler/src/dmd/traits.d index 358fe4092f..a07af5c145 100644 --- a/compiler/src/dmd/traits.d +++ b/compiler/src/dmd/traits.d @@ -467,13 +467,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) return ErrorExp.get(); } const builtInName = seNeedle.peekString(); - - switch(builtInName) - { - default: - error(e.loc, "`%.*s` is not a retrievable built-in", cast(int) builtInName.length, builtInName.ptr); - return ErrorExp.get(); - } + return resolveGetBuiltIn(builtInName, e.loc); } if (e.ident == Id.isArithmetic) { @@ -2626,3 +2620,33 @@ private void traitNotFound(TraitsExp e) @system else error(e.loc, "unrecognized trait `%s`", e.ident.toChars()); } + +private Expression resolveGetBuiltIn(const(char)[] name, Loc loc) +{ + // Signed integer types + if (name.iequals("int8")) + return new TypeExp(loc, Type.tint8); + if (name.iequals("int16")) + return new TypeExp(loc, Type.tint16); + if (name.iequals("int32")) + return new TypeExp(loc, Type.tint32); + if (name.iequals("int64")) + return new TypeExp(loc, Type.tint64); + if (name.iequals("int128")) + return new TypeExp(loc, Type.tint128); + + // Unsigned integer types + if (name.iequals("uint8")) + return new TypeExp(loc, Type.tuns8); + if (name.iequals("uint16")) + return new TypeExp(loc, Type.tuns16); + if (name.iequals("uint32")) + return new TypeExp(loc, Type.tuns32); + if (name.iequals("uint64")) + return new TypeExp(loc, Type.tuns64); + if (name.iequals("uint128")) + return new TypeExp(loc, Type.tuns128); + + error(loc, "`%.*s` is not a retrievable built-in", cast(int) name.length, name.ptr); + return ErrorExp.get(); +}