Skip to content

Implement language dependent casing support for std.uni - #11075

Open
rikkimax wants to merge 1 commit into
dlang:masterfrom
rikkimax:casing
Open

Implement language dependent casing support for std.uni#11075
rikkimax wants to merge 1 commit into
dlang:masterfrom
rikkimax:casing

Conversation

@rikkimax

@rikkimax rikkimax commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

@LightBender @atilaneves

Rationale

Casing support needs to handle the language specific rules of SpecialCasing.txt, this hurts our Turkish users not to have.

Feature request or issue tracking

I didn't spot a bug report, but this is a known issue that has been bugging me for ages.

Pre-review checklist

  • I have performed a self-review of my code.
  • If my PR fixes a bug or introduces a new feature, I have added thorough tests.
  • If my changes are non-trivial and do not concern a reported issue, I have added a changelog entry.

LLM/AI disclosure

This PR was written entirely by an LLM/AI.

MiMo V2.5

Casing support in std.uni is incomplete.
It only includes simple casing, not Special casing.

I have given you an updated unicode database file, for the table generator.

You will need to figure out how to build std.uni along with the tables to verify the implementation.

Craft a plan that is based upon the current state of casing support of std.uni and the table generator. You have the relevant specification.

Casing locality is a runtime variable.
Do not modify existing casing support, instead add new functions and tables for it.
I have given you access to another casing implementation in @documents/basic_memory

There are differences between ProjectSidero's tables approach and std.uni's. You should do it the way std.uni does it, since that is the target library.

Ignore build_v3.d it has nothing to do with PhobosV2 that you are working on.
Also change of plans, we'll go back to ucd-17, you don't need to update the directory.

Go

CasingLanguage needs to be public, with each entry in the enum to have a ddoc comment on it.
Move specialIsCaseIgnorable, specialIsCased, specialIsSoftDotted, specialGetCCC into the same block as specialTitleIndex_AzeriTrie and remove the private as it already is private.
Move toLowerSpecial, toUpperSpecial to a place above the private: area so that it is public along with their unittest. Include in their ddoc's why the special version exists.

SpecialCasingCondition and SpecialCasing should not be public, put them back behind private.

std/uni/package.d(10896): Error: none of the overloads of template std.utf.encode are callable using argument types !()(Appender!(char[]), dchar)
encode(result, mc);
std/utf.d(2324): Candidates are: encode(Flag useReplacementDchar = No.useReplacementDchar)(out char[4] buf, dchar c)
std/utf.d(2458): encode(Flag useReplacementDchar = No.useReplacementDchar)(out wchar[2] buf, dchar c)
std/utf.d(2511): encode(Flag useReplacementDchar = No.useReplacementDchar)(out dchar[1] buf, dchar c)
std/utf.d(2554): encode(Flag useReplacementDchar = No.useReplacementDchar)(ref scope char[] str, dchar c)
std/utf.d(2676): encode(Flag useReplacementDchar = No.useReplacementDchar)(ref scope wchar[] str, dchar c)
std/utf.d(2733): encode(Flag useReplacementDchar = No.useReplacementDchar)(ref scope dchar[] str, dchar c)

std/utf.d(2324): Candidates are: encode(Flag useReplacementDchar = No.useReplacementDchar)(out char[4] buf, dchar c)
std/utf.d(2458): encode(Flag useReplacementDchar = No.useReplacementDchar)(out wchar[2] buf, dchar c)
std/utf.d(2511): encode(Flag useReplacementDchar = No.useReplacementDchar)(out dchar[1] buf, dchar c)
std/utf.d(2554): encode(Flag useReplacementDchar = No.useReplacementDchar)(ref scope char[] str, dchar c)
std/utf.d(2676): encode(Flag useReplacementDchar = No.useReplacementDchar)(ref scope wchar[] str, dchar c)
std/utf.d(2733): encode(Flag useReplacementDchar = No.useReplacementDchar)(ref scope dchar[] str, dchar c)

Build std.uni to verify there are not more compiler errors.

std/uni/package.d(10834): Error: function toLowerTab is not callable using argument types ()
auto val = toLowerTab[idx];
std/uni/package.d(10834): too few arguments, expected 1, got 0
auto val = toLowerTab[idx];
std/uni/package.d(9154): std.uni.toLowerTab(ulong idx) declared here
dchar toLowerTab(size_t idx) { return toLowerTable[idx]; }
std/uni/package.d(11221): Error: function tryDir is not callable using argument types (immutable(Trie!(ushort, dchar, 1114112LU, sliceBits!(13LU, 21LU), sliceBits!(6LU, 13LU), sliceBits!(0LU, 6LU))), immutable(uint)[], immutable(ubyte)[])
tryDir(specialLowerIndex_LithuanianTrie(), specialLowerTable_Lithuanian(), specialLowerCond_Lithuanian());

Parameters cannot be typed as auto. It sounds like you wanted a template.
For tryDir.

std/uni/package.d(10849): Error: return value result.data() of type char[] does not match return type string, and cannot be implicitly converted
return result.data;
std/uni/package.d(10886): Error: undefined identifier decode, did you mean template decoder(C)(C[] s, size_t offset = 0) if (is(C : wchar) || is(C : char))?
dchar c = decode(s, i);
std/uni/package.d(10919): Error: return value result.data() of type char[] does not match return type string, and cannot be implicitly converted
return result.data;

core.exception.AssertError@generated/linux/debug/64/publictests/std_uni_package.d(10929): unittest failure

That doesn't make sense.
You need to build and run the unittests of std.uni. Patch whatever module you need so that it compiles.

mappingFromTable still contains your replacement for the len == 0 return null;

core.exception.AssertError@../dmd/druntime/import/core/internal/array/casting.d(68): immutable(char)[] of length 1 cannot be cast to const(dchar)[] as its length in bytes (1) is not a multiple of const(dchar).sizeof (4).
../dmd/druntime/import/core/internal/array/casting.d:68 [0x5b9f7f1e6d60]
../dmd/druntime/import/core/internal/array/casting.d:88 [0x5b9f7f22368d]
std/uni/package.d:10822 [0x5b9f7f217feb]
generated/linux/debug/64/publictests/std_uni_package.d:10931 [0x5b9f7f1c2acf]

std/uni/package.d(10811): Error: cannot implicitly convert expression s of type string to dstring
dstring ds = s;
std/uni/package.d(10886): Error: cannot implicitly convert expression s of type string to dstring
dstring ds = s;

@rikkimax rikkimax added the Review:AI Generated Code that is generated by an LLM AI — or suspected to be. label Aug 1, 2026
Comment thread std/uni/package.d Outdated
)

The existing $(LREF toLower) handles only the unconditional mappings from
SpecialCasing.txt. This function adds the conditional rules that require

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

where is this file? the changelog has lower casing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We don't ship the Unicode database in its original form, only in the generated table form.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OK, then please make it clear where it can be found

@rikkimax
rikkimax force-pushed the casing branch 6 times, most recently from e37b16b to 64663ad Compare August 1, 2026 03:52
@LightBender

Copy link
Copy Markdown
Contributor

It's frustrating that we have to do this, but it's a well-known problem in Turkic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review:AI Generated Code that is generated by an LLM AI — or suspected to be.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants