From c4eeaabde241decdfaa1fbd9babb9ef98d74f1da Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Sun, 5 Jan 2025 21:31:09 +0100 Subject: [PATCH] Fix -verrors=context handling of tabs --- compiler/src/dmd/errors.d | 33 ++++++++++++++++--- .../fail_compilation/fail_pretty_errors.d | 18 ++++++---- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/compiler/src/dmd/errors.d b/compiler/src/dmd/errors.d index 793e0ca3f2c..ce8f86bfc3c 100644 --- a/compiler/src/dmd/errors.d +++ b/compiler/src/dmd/errors.d @@ -744,19 +744,42 @@ private void verrorPrint(const(char)* format, va_list ap, ref ErrorInfo info) continue; if (loc.charnum < line.length) { - fprintf(stderr, "%.*s\n", cast(int)line.length, line.ptr); + enum tabWidth = 4; // The number of column bytes and the number of display columns // occupied by a character are not the same for non-ASCII charaters. // https://issues.dlang.org/show_bug.cgi?id=21849 - size_t col = 0; - while (col < loc.charnum - 1) + size_t index = 0; + size_t column = 0; + size_t caretColumn = 0; + while (index < line.length) { import dmd.root.utf : utf_decodeChar; dchar u; - const msg = utf_decodeChar(line, col, u); + const start = index; + const msg = utf_decodeChar(line, index, u); assert(msg is null, msg); - fputc(' ', stderr); + if (u == '\t') + { + // How many spaces until column is the next multiple of tabWidth + const equivalentSpaces = tabWidth - (column % tabWidth); + foreach (i; 0 .. equivalentSpaces) + fputc(' ', stderr); + column += equivalentSpaces; + } + else + { + fprintf(stderr, "%.*s", cast(int) (index - start), &line[start]); + column++; + } + if (index < loc.charnum) + caretColumn = column; + } + fputc('\n', stderr); + + foreach (i; 0 .. caretColumn) + fputc(' ', stderr); + fputc('^', stderr); fputc('\n', stderr); } diff --git a/compiler/test/fail_compilation/fail_pretty_errors.d b/compiler/test/fail_compilation/fail_pretty_errors.d index e9533c04c69..2016a501751 100644 --- a/compiler/test/fail_compilation/fail_pretty_errors.d +++ b/compiler/test/fail_compilation/fail_pretty_errors.d @@ -2,20 +2,23 @@ REQUIRED_ARGS: -verrors=context TEST_OUTPUT: --- -fail_compilation/fail_pretty_errors.d(24): Error: undefined identifier `a` +fail_compilation/fail_pretty_errors.d(27): Error: undefined identifier `a` a = 1; ^ -fail_compilation/fail_pretty_errors.d-mixin-29(29): Error: undefined identifier `b` -fail_compilation/fail_pretty_errors.d(34): Error: cannot implicitly convert expression `5` of type `int` to `string` +fail_compilation/fail_pretty_errors.d-mixin-32(32): Error: undefined identifier `b` +fail_compilation/fail_pretty_errors.d(37): Error: cannot implicitly convert expression `5` of type `int` to `string` string x = 5; ^ -fail_compilation/fail_pretty_errors.d(39): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating +fail_compilation/fail_pretty_errors.d(42): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating mixin mixinTemplate; ^ -fail_compilation/fail_pretty_errors.d(45): Error: invalid array operation `"" + ""` (possible missing []) +fail_compilation/fail_pretty_errors.d(48): Error: invalid array operation `"" + ""` (possible missing []) auto x = ""+""; ^ -fail_compilation/fail_pretty_errors.d(45): did you mean to concatenate (`"" ~ ""`) instead ? +fail_compilation/fail_pretty_errors.d(48): did you mean to concatenate (`"" ~ ""`) instead ? +fail_compilation/fail_pretty_errors.d(51): Error: cannot implicitly convert expression `1111` of type `int` to `byte` + byte ɑ = 1111; + ^ --- */ @@ -43,4 +46,7 @@ void f() { // check supplemental error doesn't show context auto x = ""+""; + + // Check correct spacing with the presence of unicode characters and tabs + byte ɑ = 1111; }