mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Merge pull request #8339 from roc-lang/dollars
Warn for `$` in the middle of idents
This commit is contained in:
commit
b8386e3e1a
23 changed files with 170 additions and 56 deletions
|
|
@ -618,7 +618,7 @@ fn assertNoParseProblems(self: *TestEnv) !void {
|
|||
defer report_buf.deinit();
|
||||
|
||||
for (self.parse_ast.tokenize_diagnostics.items) |tok_diag| {
|
||||
var report = try self.parse_ast.tokenizeDiagnosticToReport(tok_diag, self.gpa);
|
||||
var report = try self.parse_ast.tokenizeDiagnosticToReport(tok_diag, self.gpa, null);
|
||||
defer report.deinit();
|
||||
|
||||
try renderReportToMarkdownBuffer(&report_buf, &report);
|
||||
|
|
|
|||
|
|
@ -796,7 +796,7 @@ pub const BuildEnv = struct {
|
|||
const module_name = file_abs;
|
||||
|
||||
for (ast.tokenize_diagnostics.items) |diagnostic| {
|
||||
const report = try ast.tokenizeDiagnosticToReport(diagnostic, self.gpa);
|
||||
const report = try ast.tokenizeDiagnosticToReport(diagnostic, self.gpa, file_abs);
|
||||
self.sink.emitReport(pkg_name, module_name, report);
|
||||
}
|
||||
for (ast.parse_diagnostics.items) |diagnostic| {
|
||||
|
|
|
|||
|
|
@ -574,7 +574,7 @@ pub const PackageEnv = struct {
|
|||
|
||||
// Convert parse diagnostics to reports
|
||||
for (parse_ast.tokenize_diagnostics.items) |diagnostic| {
|
||||
const report = try parse_ast.tokenizeDiagnosticToReport(diagnostic, self.gpa);
|
||||
const report = try parse_ast.tokenizeDiagnosticToReport(diagnostic, self.gpa, st.path);
|
||||
try st.reports.append(self.gpa, report);
|
||||
}
|
||||
for (parse_ast.parse_diagnostics.items) |diagnostic| {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub fn deinit(self: *AST, gpa: std.mem.Allocator) void {
|
|||
}
|
||||
|
||||
/// Convert a tokenize diagnostic to a Report for rendering
|
||||
pub fn tokenizeDiagnosticToReport(self: *AST, diagnostic: tokenize.Diagnostic, allocator: std.mem.Allocator) !reporting.Report {
|
||||
pub fn tokenizeDiagnosticToReport(self: *AST, diagnostic: tokenize.Diagnostic, allocator: std.mem.Allocator, filename: ?[]const u8) !reporting.Report {
|
||||
const title = switch (diagnostic.tag) {
|
||||
.MisplacedCarriageReturn => "MISPLACED CARRIAGE RETURN",
|
||||
.AsciiControl => "ASCII CONTROL CHARACTER",
|
||||
|
|
@ -127,6 +127,7 @@ pub fn tokenizeDiagnosticToReport(self: *AST, diagnostic: tokenize.Diagnostic, a
|
|||
.UnclosedString => "UNCLOSED STRING",
|
||||
.NonPrintableUnicodeInStrLiteral => "NON-PRINTABLE UNICODE IN STRING-LIKE LITERAL",
|
||||
.InvalidUtf8InSource => "INVALID UTF-8",
|
||||
.DollarInMiddleOfIdentifier => "STRAY DOLLAR SIGN",
|
||||
};
|
||||
|
||||
const body = switch (diagnostic.tag) {
|
||||
|
|
@ -139,6 +140,7 @@ pub fn tokenizeDiagnosticToReport(self: *AST, diagnostic: tokenize.Diagnostic, a
|
|||
.UnclosedString => "This string is missing a closing quote.",
|
||||
.NonPrintableUnicodeInStrLiteral => "Non-printable Unicode characters are not allowed in string-like literals.",
|
||||
.InvalidUtf8InSource => "Invalid UTF-8 encoding found in source code. Roc source files must be valid UTF-8.",
|
||||
.DollarInMiddleOfIdentifier => "Dollar sign ($) is only allowed at the very beginning of a name, not in the middle or at the end.",
|
||||
};
|
||||
|
||||
var report = reporting.Report.init(allocator, title, .runtime_error);
|
||||
|
|
@ -170,7 +172,7 @@ pub fn tokenizeDiagnosticToReport(self: *AST, diagnostic: tokenize.Diagnostic, a
|
|||
try report.document.addSourceRegion(
|
||||
region_info,
|
||||
.error_highlight,
|
||||
null, // No filename available for tokenize diagnostics
|
||||
filename,
|
||||
self.env.source,
|
||||
env.line_starts.items.items,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -484,6 +484,7 @@ pub const Diagnostic = struct {
|
|||
UnclosedString,
|
||||
NonPrintableUnicodeInStrLiteral,
|
||||
InvalidUtf8InSource,
|
||||
DollarInMiddleOfIdentifier,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -823,9 +824,16 @@ pub const Cursor = struct {
|
|||
/// Returns whether the chomped identifier was valid - i.e. didn't contain any non-ascii characters.
|
||||
pub fn chompIdentGeneral(self: *Cursor) bool {
|
||||
var valid = true;
|
||||
const start_pos = self.pos;
|
||||
while (self.pos < self.buf.len) {
|
||||
const c = self.buf[self.pos];
|
||||
if ((c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c >= '0' and c <= '9') or c == '_' or c == '!') {
|
||||
if ((c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c >= '0' and c <= '9') or c == '_' or c == '!' or c == '$') {
|
||||
// Allow $ as a valid identifier character
|
||||
if (c == '$' and self.pos > start_pos) {
|
||||
// But warn if it's not at the start (pos > start_pos means we've moved)
|
||||
// Use pushMessage to specify the exact location of the $ character
|
||||
self.pushMessage(.DollarInMiddleOfIdentifier, self.pos, self.pos + 1);
|
||||
}
|
||||
self.pos += 1;
|
||||
} else if (c >= 0x80) {
|
||||
valid = false;
|
||||
|
|
@ -2476,3 +2484,89 @@ test "non-printable characters in string literal" {
|
|||
try std.testing.expect(messages.len == 0);
|
||||
}
|
||||
}
|
||||
|
||||
test "dollar sign in middle of identifier" {
|
||||
const gpa = std.testing.allocator;
|
||||
|
||||
// Dollar sign in the middle of an identifier - foo$bar
|
||||
{
|
||||
const source = "foo$bar";
|
||||
var diagnostics: [10]Diagnostic = undefined;
|
||||
|
||||
var env = try CommonEnv.init(gpa, try gpa.dupe(u8, ""));
|
||||
defer env.deinit(gpa);
|
||||
|
||||
var tokenizer = try Tokenizer.init(&env, gpa, source, &diagnostics);
|
||||
defer tokenizer.deinit(gpa);
|
||||
try tokenizer.tokenize(gpa);
|
||||
|
||||
// Should have reported DollarInMiddleOfIdentifier
|
||||
const messages = tokenizer.cursor.messages[0..tokenizer.cursor.message_count];
|
||||
try std.testing.expect(messages.len > 0);
|
||||
try std.testing.expectEqual(Diagnostic.Tag.DollarInMiddleOfIdentifier, messages[0].tag);
|
||||
|
||||
// Should tokenize as a valid LowerIdent (but with a warning)
|
||||
const token_tags = tokenizer.output.tokens.items(.tag);
|
||||
try std.testing.expect(token_tags.len >= 2); // At least the identifier and EOF
|
||||
try std.testing.expectEqual(Token.Tag.LowerIdent, token_tags[0]);
|
||||
}
|
||||
|
||||
// Dollar sign at the end of an identifier - foo$
|
||||
{
|
||||
const source = "foo$";
|
||||
var diagnostics: [10]Diagnostic = undefined;
|
||||
|
||||
var env = try CommonEnv.init(gpa, try gpa.dupe(u8, ""));
|
||||
defer env.deinit(gpa);
|
||||
|
||||
var tokenizer = try Tokenizer.init(&env, gpa, source, &diagnostics);
|
||||
defer tokenizer.deinit(gpa);
|
||||
try tokenizer.tokenize(gpa);
|
||||
|
||||
// Should have reported DollarInMiddleOfIdentifier
|
||||
const messages = tokenizer.cursor.messages[0..tokenizer.cursor.message_count];
|
||||
try std.testing.expect(messages.len > 0);
|
||||
try std.testing.expectEqual(Diagnostic.Tag.DollarInMiddleOfIdentifier, messages[0].tag);
|
||||
}
|
||||
|
||||
// Multiple dollar signs in identifier - foo$bar$baz
|
||||
{
|
||||
const source = "foo$bar$baz";
|
||||
var diagnostics: [10]Diagnostic = undefined;
|
||||
|
||||
var env = try CommonEnv.init(gpa, try gpa.dupe(u8, ""));
|
||||
defer env.deinit(gpa);
|
||||
|
||||
var tokenizer = try Tokenizer.init(&env, gpa, source, &diagnostics);
|
||||
defer tokenizer.deinit(gpa);
|
||||
try tokenizer.tokenize(gpa);
|
||||
|
||||
// Should have reported multiple DollarInMiddleOfIdentifier warnings
|
||||
const messages = tokenizer.cursor.messages[0..tokenizer.cursor.message_count];
|
||||
try std.testing.expect(messages.len >= 2);
|
||||
try std.testing.expectEqual(Diagnostic.Tag.DollarInMiddleOfIdentifier, messages[0].tag);
|
||||
try std.testing.expectEqual(Diagnostic.Tag.DollarInMiddleOfIdentifier, messages[1].tag);
|
||||
}
|
||||
|
||||
// Dollar at the start is OK - no warning
|
||||
{
|
||||
const source = "$foo";
|
||||
var diagnostics: [10]Diagnostic = undefined;
|
||||
|
||||
var env = try CommonEnv.init(gpa, try gpa.dupe(u8, ""));
|
||||
defer env.deinit(gpa);
|
||||
|
||||
var tokenizer = try Tokenizer.init(&env, gpa, source, &diagnostics);
|
||||
defer tokenizer.deinit(gpa);
|
||||
try tokenizer.tokenize(gpa);
|
||||
|
||||
// Should NOT have any warnings
|
||||
const messages = tokenizer.cursor.messages[0..tokenizer.cursor.message_count];
|
||||
try std.testing.expect(messages.len == 0);
|
||||
|
||||
// Should tokenize as a valid LowerIdent
|
||||
const token_tags = tokenizer.output.tokens.items(.tag);
|
||||
try std.testing.expect(token_tags.len >= 2);
|
||||
try std.testing.expectEqual(Token.Tag.LowerIdent, token_tags[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -885,7 +885,7 @@ fn compileSource(source: []const u8) !CompilerStageData {
|
|||
|
||||
// Collect tokenize diagnostics with additional error handling
|
||||
for (parse_ast.tokenize_diagnostics.items) |diagnostic| {
|
||||
const report = parse_ast.tokenizeDiagnosticToReport(diagnostic, allocator) catch {
|
||||
const report = parse_ast.tokenizeDiagnosticToReport(diagnostic, allocator, null) catch {
|
||||
// Log the error and continue processing other diagnostics
|
||||
// This prevents crashes on malformed diagnostics or empty input
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ fn generateAllReports(
|
|||
|
||||
// Generate tokenize reports
|
||||
for (parse_ast.tokenize_diagnostics.items) |diagnostic| {
|
||||
const report = parse_ast.tokenizeDiagnosticToReport(diagnostic, allocator) catch |err| {
|
||||
const report = parse_ast.tokenizeDiagnosticToReport(diagnostic, allocator, snapshot_path) catch |err| {
|
||||
std.debug.panic("Failed to create tokenize report for snapshot {s}: {s}", .{ snapshot_path, @errorName(err) });
|
||||
};
|
||||
try reports.append(report);
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ type=expr
|
|||
"abc\u(zzzz)def"
|
||||
~~~
|
||||
# EXPECTED
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - unicode_not_hex.md:1:5:1:13
|
||||
# PROBLEMS
|
||||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**unicode_not_hex.md:1:5:1:13:**
|
||||
```roc
|
||||
"abc\u(zzzz)def"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ type=expr
|
|||
"abc\qdef"
|
||||
~~~
|
||||
# EXPECTED
|
||||
INVALID ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID ESCAPE SEQUENCE - weird_escape.md:1:5:1:7
|
||||
# PROBLEMS
|
||||
**INVALID ESCAPE SEQUENCE**
|
||||
This escape sequence is not recognized.
|
||||
|
||||
**weird_escape.md:1:5:1:7:**
|
||||
```roc
|
||||
"abc\qdef"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ type=file
|
|||
= "te
|
||||
~~~
|
||||
# EXPECTED
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_003.md:1:3:1:6
|
||||
PARSE ERROR - fuzz_crash_003.md:1:1:1:2
|
||||
PARSE ERROR - fuzz_crash_003.md:1:3:1:4
|
||||
PARSE ERROR - fuzz_crash_003.md:1:4:1:6
|
||||
|
|
@ -18,6 +18,7 @@ MISSING MAIN! FUNCTION - fuzz_crash_003.md:1:1:1:6
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_003.md:1:3:1:6:**
|
||||
```roc
|
||||
= "te
|
||||
```
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ foo =
|
|||
"onmo %
|
||||
~~~
|
||||
# EXPECTED
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_009.md:6:5:6:12
|
||||
PARSE ERROR - fuzz_crash_009.md:1:2:1:3
|
||||
PARSE ERROR - fuzz_crash_009.md:1:3:1:4
|
||||
PARSE ERROR - fuzz_crash_009.md:1:4:1:5
|
||||
|
|
@ -24,6 +24,7 @@ MISSING MAIN! FUNCTION - fuzz_crash_009.md:1:2:6:12
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_009.md:6:5:6:12:**
|
||||
```roc
|
||||
"onmo %
|
||||
```
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ foo =
|
|||
~~~
|
||||
# EXPECTED
|
||||
ASCII CONTROL CHARACTER - :0:0:0:0
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_010.md:5:5:5:35
|
||||
PARSE ERROR - fuzz_crash_010.md:1:2:1:3
|
||||
PARSE ERROR - fuzz_crash_010.md:1:3:1:4
|
||||
PARSE ERROR - fuzz_crash_010.md:1:4:1:5
|
||||
|
|
@ -28,6 +28,7 @@ ASCII control characters are not allowed in Roc source code.
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_010.md:5:5:5:35:**
|
||||
```roc
|
||||
"on (string 'onmo %')))
|
||||
```
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Fli/main.roc" }
|
|||
Pair(a, b+ : (
|
||||
~~~
|
||||
# EXPECTED
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_021.md:1:13:1:16
|
||||
PARSE ERROR - fuzz_crash_021.md:1:4:1:5
|
||||
PARSE ERROR - fuzz_crash_021.md:1:5:1:9
|
||||
PARSE ERROR - fuzz_crash_021.md:1:9:1:13
|
||||
|
|
@ -25,6 +25,7 @@ TYPE MODULE MISSING MATCHING TYPE - fuzz_crash_021.md:1:1:3:15
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_021.md:1:13:1:16:**
|
||||
```roc
|
||||
Fli/main.roc" }
|
||||
```
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -167,7 +167,7 @@ expect {
|
|||
~~~
|
||||
# EXPECTED
|
||||
LEADING ZERO - :0:0:0:0
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_027.md:118:8:118:22
|
||||
PARSE ERROR - fuzz_crash_027.md:40:5:40:6
|
||||
PARSE ERROR - fuzz_crash_027.md:40:7:40:8
|
||||
PARSE ERROR - fuzz_crash_027.md:40:9:40:10
|
||||
|
|
@ -239,6 +239,7 @@ Numbers cannot have leading zeros.
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_027.md:118:8:118:22:**
|
||||
```roc
|
||||
crash "Unreachtement
|
||||
```
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -9,11 +9,12 @@ app[]{f:platform"",r:"
|
|||
}
|
||||
~~~
|
||||
# EXPECTED
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_058.md:1:22:1:23
|
||||
# PROBLEMS
|
||||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_058.md:1:22:1:23:**
|
||||
```roc
|
||||
app[]{f:platform"",r:"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ type=snippet
|
|||
}
|
||||
~~~
|
||||
# EXPECTED
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_060.md:1:2:1:3
|
||||
PARSE ERROR - fuzz_crash_060.md:1:1:1:2
|
||||
PARSE ERROR - fuzz_crash_060.md:1:2:1:3
|
||||
PARSE ERROR - fuzz_crash_060.md:1:3:1:3
|
||||
|
|
@ -19,6 +19,7 @@ PARSE ERROR - fuzz_crash_060.md:2:1:2:2
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_060.md:1:2:1:3:**
|
||||
```roc
|
||||
0"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ platform"
|
|||
requires{}{n:0[import S exposing[
|
||||
~~~
|
||||
# EXPECTED
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
UNCLOSED STRING - fuzz_crash_061.md:1:9:1:10
|
||||
UNEXPECTED TOKEN IN TYPE ANNOTATION - fuzz_crash_061.md:2:14:2:15
|
||||
PARSE ERROR - fuzz_crash_061.md:2:11:2:12
|
||||
PARSE ERROR - fuzz_crash_061.md:2:16:2:22
|
||||
|
|
@ -17,6 +17,7 @@ PARSE ERROR - fuzz_crash_061.md:2:16:2:22
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**fuzz_crash_061.md:1:9:1:10:**
|
||||
```roc
|
||||
platform"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ type=expr
|
|||
}
|
||||
~~~
|
||||
# EXPECTED
|
||||
STRAY DOLLAR SIGN - record_different_fields_error.md:6:10:6:11
|
||||
UNEXPECTED TOKEN IN TYPE ANNOTATION - record_different_fields_error.md:2:20:2:21
|
||||
UNEXPECTED TOKEN IN EXPRESSION - record_different_fields_error.md:2:21:2:39
|
||||
UNEXPECTED TOKEN IN EXPRESSION - record_different_fields_error.md:2:39:2:40
|
||||
|
|
@ -48,7 +49,6 @@ UNDEFINED VARIABLE - record_different_fields_error.md:5:5:5:10
|
|||
UNDEFINED VARIABLE - record_different_fields_error.md:5:11:5:15
|
||||
UNRECOGNIZED SYNTAX - record_different_fields_error.md:5:15:5:16
|
||||
UNRECOGNIZED SYNTAX - record_different_fields_error.md:5:24:5:25
|
||||
UNDEFINED VARIABLE - record_different_fields_error.md:6:5:6:10
|
||||
MALFORMED TYPE - record_different_fields_error.md:6:20:6:21
|
||||
UNRECOGNIZED SYNTAX - record_different_fields_error.md:6:21:6:27
|
||||
UNRECOGNIZED SYNTAX - record_different_fields_error.md:6:27:6:28
|
||||
|
|
@ -58,12 +58,22 @@ UNRECOGNIZED SYNTAX - record_different_fields_error.md:7:10:7:17
|
|||
UNRECOGNIZED SYNTAX - record_different_fields_error.md:7:17:7:18
|
||||
UNRECOGNIZED SYNTAX - record_different_fields_error.md:7:30:7:31
|
||||
UNUSED VARIABLE - record_different_fields_error.md:3:5:3:14
|
||||
UNUSED VARIABLE - record_different_fields_error.md:6:10:6:21
|
||||
UNUSED VARIABLE - record_different_fields_error.md:6:5:6:21
|
||||
UNUSED VALUE - record_different_fields_error.md:4:5:4:15
|
||||
UNUSED VALUE - record_different_fields_error.md:4:17:4:25
|
||||
UNUSED VALUE - record_different_fields_error.md:5:17:5:24
|
||||
UNUSED VALUE - record_different_fields_error.md:7:19:7:30
|
||||
# PROBLEMS
|
||||
**STRAY DOLLAR SIGN**
|
||||
Dollar sign ($) is only allowed at the very beginning of a name, not in the middle or at the end.
|
||||
|
||||
**record_different_fields_error.md:6:10:6:11:**
|
||||
```roc
|
||||
field$special: "dollar",
|
||||
```
|
||||
^
|
||||
|
||||
|
||||
**UNEXPECTED TOKEN IN TYPE ANNOTATION**
|
||||
The token **"** is not expected in a type annotation.
|
||||
Type annotations should contain types like _Str_, _Num a_, or _List U64_.
|
||||
|
|
@ -425,17 +435,6 @@ I don't recognize this syntax.
|
|||
|
||||
This might be a syntax error, an unsupported language feature, or a typo.
|
||||
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `field` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
||||
**record_different_fields_error.md:6:5:6:10:**
|
||||
```roc
|
||||
field$special: "dollar",
|
||||
```
|
||||
^^^^^
|
||||
|
||||
|
||||
**MALFORMED TYPE**
|
||||
This type annotation is malformed or contains invalid syntax.
|
||||
|
||||
|
|
@ -536,15 +535,15 @@ The unused variable is declared here:
|
|||
|
||||
|
||||
**UNUSED VARIABLE**
|
||||
Variable `$special` is not used anywhere in your code.
|
||||
Variable `field$special` is not used anywhere in your code.
|
||||
|
||||
If you don't need this variable, prefix it with an underscore like `_$special` to suppress this warning.
|
||||
If you don't need this variable, prefix it with an underscore like `_field$special` to suppress this warning.
|
||||
The unused variable is declared here:
|
||||
**record_different_fields_error.md:6:10:6:21:**
|
||||
**record_different_fields_error.md:6:5:6:21:**
|
||||
```roc
|
||||
field$special: "dollar",
|
||||
```
|
||||
^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
**UNUSED VALUE**
|
||||
|
|
@ -598,7 +597,7 @@ NamedUnderscore,OpColon,StringStart,StringPart,StringEnd,Comma,
|
|||
LowerIdent,OpColon,StringStart,StringPart,StringEnd,Comma,
|
||||
UpperIdent,OpColon,StringStart,StringPart,StringEnd,Comma,
|
||||
LowerIdent,OpUnaryMinus,LowerIdent,OpColon,StringStart,StringPart,StringEnd,Comma,
|
||||
LowerIdent,LowerIdent,OpColon,StringStart,StringPart,StringEnd,Comma,
|
||||
LowerIdent,OpColon,StringStart,StringPart,StringEnd,Comma,
|
||||
LowerIdent,OpaqueName,OpColon,StringStart,StringPart,StringEnd,Comma,
|
||||
CloseCurly,
|
||||
EndOfFile,
|
||||
|
|
@ -629,8 +628,7 @@ EndOfFile,
|
|||
(e-string
|
||||
(e-string-part (raw "kebab")))
|
||||
(e-malformed (reason "expr_unexpected_token"))
|
||||
(e-ident (raw "field"))
|
||||
(s-type-anno (name "$special")
|
||||
(s-type-anno (name "field$special")
|
||||
(ty-malformed (tag "ty_anno_unexpected_token")))
|
||||
(e-malformed (reason "expr_unexpected_token"))
|
||||
(e-malformed (reason "expr_unexpected_token"))
|
||||
|
|
@ -656,8 +654,7 @@ EndOfFile,
|
|||
-case
|
||||
"kebab"
|
||||
|
||||
field
|
||||
$special :
|
||||
field$special :
|
||||
|
||||
field
|
||||
"at symbol"
|
||||
|
|
@ -706,10 +703,8 @@ EndOfFile,
|
|||
(e-literal (string "kebab"))))
|
||||
(s-expr
|
||||
(e-runtime-error (tag "expr_not_canonicalized")))
|
||||
(s-expr
|
||||
(e-runtime-error (tag "ident_not_in_scope")))
|
||||
(s-let
|
||||
(p-assign (ident "$special"))
|
||||
(p-assign (ident "field$special"))
|
||||
(e-anno-only))
|
||||
(s-expr
|
||||
(e-runtime-error (tag "expr_not_canonicalized")))
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ x = (
|
|||
"\
|
||||
~~~
|
||||
# EXPECTED
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID ESCAPE SEQUENCE - :0:0:0:0
|
||||
UNCLOSED STRING - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - string.md:4:3:4:5
|
||||
INVALID UNICODE ESCAPE SEQUENCE - string.md:5:3:5:5
|
||||
INVALID UNICODE ESCAPE SEQUENCE - string.md:6:3:6:6
|
||||
INVALID UNICODE ESCAPE SEQUENCE - string.md:7:3:7:7
|
||||
INVALID UNICODE ESCAPE SEQUENCE - string.md:8:3:8:8
|
||||
INVALID ESCAPE SEQUENCE - string.md:13:2:14:1
|
||||
UNCLOSED STRING - string.md:13:1:13:3
|
||||
PARSE ERROR - string.md:13:1:13:2
|
||||
PARSE ERROR - string.md:13:2:13:3
|
||||
PARSE ERROR - string.md:13:3:13:3
|
||||
|
|
@ -34,6 +34,7 @@ PARSE ERROR - string.md:13:3:13:3
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**string.md:4:3:4:5:**
|
||||
```roc
|
||||
"\u",
|
||||
```
|
||||
|
|
@ -43,6 +44,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**string.md:5:3:5:5:**
|
||||
```roc
|
||||
"\u)",
|
||||
```
|
||||
|
|
@ -52,6 +54,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**string.md:6:3:6:6:**
|
||||
```roc
|
||||
"\u(",
|
||||
```
|
||||
|
|
@ -61,6 +64,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**string.md:7:3:7:7:**
|
||||
```roc
|
||||
"\u()",
|
||||
```
|
||||
|
|
@ -70,6 +74,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**string.md:8:3:8:8:**
|
||||
```roc
|
||||
"\u(K)",
|
||||
```
|
||||
|
|
@ -79,6 +84,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID ESCAPE SEQUENCE**
|
||||
This escape sequence is not recognized.
|
||||
|
||||
**string.md:13:2:14:1:**
|
||||
```roc
|
||||
"\
|
||||
|
||||
|
|
@ -88,6 +94,7 @@ This escape sequence is not recognized.
|
|||
**UNCLOSED STRING**
|
||||
This string is missing a closing quote.
|
||||
|
||||
**string.md:13:1:13:3:**
|
||||
```roc
|
||||
"\
|
||||
```
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ y = 'u
|
|||
'\
|
||||
~~~
|
||||
# EXPECTED
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID ESCAPE SEQUENCE - :0:0:0:0
|
||||
INVALID UNICODE ESCAPE SEQUENCE - unicode_single_quotes.md:5:6:5:8
|
||||
INVALID UNICODE ESCAPE SEQUENCE - unicode_single_quotes.md:6:6:6:8
|
||||
INVALID UNICODE ESCAPE SEQUENCE - unicode_single_quotes.md:7:6:7:9
|
||||
INVALID UNICODE ESCAPE SEQUENCE - unicode_single_quotes.md:8:6:8:10
|
||||
INVALID UNICODE ESCAPE SEQUENCE - unicode_single_quotes.md:10:6:10:11
|
||||
INVALID ESCAPE SEQUENCE - unicode_single_quotes.md:21:2:22:1
|
||||
UNEXPECTED TOKEN IN EXPRESSION - unicode_single_quotes.md:5:5:5:9
|
||||
UNEXPECTED TOKEN IN EXPRESSION - unicode_single_quotes.md:6:5:6:10
|
||||
UNEXPECTED TOKEN IN EXPRESSION - unicode_single_quotes.md:7:5:7:10
|
||||
|
|
@ -57,6 +57,7 @@ UNRECOGNIZED SYNTAX - unicode_single_quotes.md:18:5:18:7
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**unicode_single_quotes.md:5:6:5:8:**
|
||||
```roc
|
||||
'\u',
|
||||
```
|
||||
|
|
@ -66,6 +67,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**unicode_single_quotes.md:6:6:6:8:**
|
||||
```roc
|
||||
'\u)',
|
||||
```
|
||||
|
|
@ -75,6 +77,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**unicode_single_quotes.md:7:6:7:9:**
|
||||
```roc
|
||||
'\u(',
|
||||
```
|
||||
|
|
@ -84,6 +87,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**unicode_single_quotes.md:8:6:8:10:**
|
||||
```roc
|
||||
'\u()',
|
||||
```
|
||||
|
|
@ -93,6 +97,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID UNICODE ESCAPE SEQUENCE**
|
||||
This Unicode escape sequence is not valid.
|
||||
|
||||
**unicode_single_quotes.md:10:6:10:11:**
|
||||
```roc
|
||||
'\u(K)',
|
||||
```
|
||||
|
|
@ -102,6 +107,7 @@ This Unicode escape sequence is not valid.
|
|||
**INVALID ESCAPE SEQUENCE**
|
||||
This escape sequence is not recognized.
|
||||
|
||||
**unicode_single_quotes.md:21:2:22:1:**
|
||||
```roc
|
||||
'\
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue