| name | combining-chars-break-char-literals |
| description | A Devanagari, Gurmukhi, or other diacritic-marked letter that looks like one glyph in the editor fails to compile as a `'x'` character literal with "Too many characters in a character literal," because it is a base letter plus a separate combining mark — two `Char`s, not one. Use when a lookup table keyed by `Char` needs an entry for a marked or accented letter outside plain Latin, or when per-character text processing garbles exactly the words that carry an accent. |
Combining characters break Char literals
Kotlin's Char is documented, precisely, as "a 16-bit Unicode character" — one UTF-16 code unit. A
single letter a reader perceives as one character can need two of them: a base letter followed by
a separate combining mark that is rendered on top of it. क़ (Devanagari "qa") is क (KA) plus a
combining nukta sign — two code points, two Chars — and 'क़' does not compile as a character
literal at all. The same wall applies, for an unrelated reason, to any single code point outside the
Basic Multilingual Plane: it needs a surrogate pair to represent in UTF-16, so it is also two
Chars masquerading as one glyph — see kmp-html-entity-decoder for the worked branch that turns a
decoded code point above 0xFFFF back into that pair.
Traps
A map keyed by Char cannot hold an entry for a combining sequence — the literal itself fails to
compile. Perso-Arabic loanword sounds in Hindi are written as a base consonant plus a nukta; the
source here handles it not by trying 'क़' to "q" (which is rejected outright) but by keeping the
nukta as its own Char constant and treating it as a modifier the lookup consumes separately:
private const DEVANAGARI_NUKTA =
DEVANAGARI_NUKTA_FORMS: Map<, String> =
mapOf(
to , to , to , to ,
to , to , to ,
)