diff --git a/src/check/test/type_checking_integration.zig b/src/check/test/type_checking_integration.zig index e0bd42d29b..19ea134a4c 100644 --- a/src/check/test/type_checking_integration.zig +++ b/src/check/test/type_checking_integration.zig @@ -2551,6 +2551,22 @@ test "check type - try return with match and error propagation should type-check try checkTypesModule(source, .{ .pass = .last_def }, "{ } -> Try(Str, [ListWasEmpty, Impossible, .._others2])"); } +test "check type - try operator on method call should apply to whole expression (#8646)" { + // Regression test for https://github.com/roc-lang/roc/issues/8646 + // The `?` suffix on `strings.first()` should apply to the entire method call expression, + // not just to the right side of the field access. Previously, the parser was attaching + // `?` to `first()` before creating the field_access node, causing a type mismatch error + // that expected `{ unknown: _field }`. + const source = + \\question_fail : List(Str) -> Try(Str, _) + \\question_fail = |strings| { + \\ first_str = strings.first()? + \\ Ok(first_str) + \\} + ; + try checkTypesModule(source, .{ .pass = .last_def }, "List(Str) -> Try(Str, [ListWasEmpty, ..others])"); +} + // record extension in type annotations // test "check type - record extension - basic open record annotation" { diff --git a/src/parse/Parser.zig b/src/parse/Parser.zig index 5b35a2f969..19d7614f67 100644 --- a/src/parse/Parser.zig +++ b/src/parse/Parser.zig @@ -2642,7 +2642,8 @@ pub fn parseExprWithBp(self: *Parser, min_bp: u8) Error!AST.Expr.Idx { .qualifiers = qual_result.qualifiers, } }); - const ident_suffixed = try self.parseExprSuffix(s, expr_node); + // Only parse function applications on the right side, not ? suffix + const ident_suffixed = try self.parseExprApplicationSuffix(s, expr_node); expression = try self.store.addExpr(.{ .local_dispatch = .{ .region = .{ .start = start, .end = self.pos }, .operator = s, @@ -2661,7 +2662,8 @@ pub fn parseExprWithBp(self: *Parser, min_bp: u8) Error!AST.Expr.Idx { .token = s, .qualifiers = empty_qualifiers, } }); - const ident_suffixed = try self.parseExprSuffix(s, ident); + // Only parse function applications on the right side, not ? suffix + const ident_suffixed = try self.parseExprApplicationSuffix(s, ident); expression = try self.store.addExpr(.{ .field_access = .{ .region = .{ .start = start, .end = self.pos }, .operator = start, @@ -2669,6 +2671,17 @@ pub fn parseExprWithBp(self: *Parser, min_bp: u8) Error!AST.Expr.Idx { .right = ident_suffixed, } }); } + + // Handle ? suffix on the entire field access / local dispatch expression. + // This ensures `a.b()?` is parsed as `(a.b())?` rather than `a.(b()?)`. + while (self.peek() == .NoSpaceOpQuestion) { + self.advance(); + expression = try self.store.addExpr(.{ .suffix_single_question = .{ + .expr = expression, + .operator = start, + .region = .{ .start = start, .end = self.pos }, + } }); + } } while (getTokenBP(self.peek())) |bp| { if (bp.left < min_bp) { @@ -2692,7 +2705,7 @@ pub fn parseExprWithBp(self: *Parser, min_bp: u8) Error!AST.Expr.Idx { return try self.store.addMalformed(AST.Expr.Idx, .expr_unexpected_token, .{ .start = start, .end = self.pos }); } -/// todo +/// Parse suffix operators (function application and question mark) on an expression. fn parseExprSuffix(self: *Parser, start: u32, e: AST.Expr.Idx) Error!AST.Expr.Idx { const trace = tracy.trace(@src()); defer trace.end(); @@ -2744,6 +2757,41 @@ fn parseExprSuffix(self: *Parser, start: u32, e: AST.Expr.Idx) Error!AST.Expr.Id return expression; } +/// Parse only function application suffixes (not question mark). +/// Used for the right side of field access where ? should apply to the whole expression. +fn parseExprApplicationSuffix(self: *Parser, start: u32, e: AST.Expr.Idx) Error!AST.Expr.Idx { + const trace = tracy.trace(@src()); + defer trace.end(); + + var expression = e; + + // Only handle function applications, not question marks + while (self.peek() == .NoSpaceOpenRound) { + self.advance(); + const scratch_top = self.store.scratchExprTop(); + self.parseCollectionSpan(AST.Expr.Idx, .CloseRound, NodeStore.addScratchExpr, parseExpr) catch |err| { + switch (err) { + error.ExpectedNotFound => { + self.store.clearScratchExprsFrom(scratch_top); + return try self.pushMalformed(AST.Expr.Idx, .expected_expr_apply_close_round, start); + }, + error.OutOfMemory => return error.OutOfMemory, + error.TooNested => return error.TooNested, + } + }; + const args = try self.store.exprSpanFrom(scratch_top); + + expression = try self.store.addExpr(.{ + .apply = .{ + .args = args, + .@"fn" = expression, + .region = .{ .start = start, .end = self.pos }, + }, + }); + } + return expression; +} + /// todo pub fn parseRecordField(self: *Parser) Error!AST.RecordField.Idx { const trace = tracy.trace(@src()); diff --git a/test/snapshots/fuzz_crash/fuzz_crash_019.md b/test/snapshots/fuzz_crash/fuzz_crash_019.md index e2f0ddd706..dbe276ad68 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_019.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_019.md @@ -1433,20 +1433,20 @@ EndOfFile, (e-binop (op "<=") (e-int (raw "12")) (e-int (raw "3"))))) - (e-field-access + (e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "e_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw "od"))))) (e-question-suffix - (e-apply - (e-ident (raw "ned"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "e_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw "od"))))) + (e-apply + (e-ident (raw "ned"))))) (e-ident (raw "recd")))) (e-apply (e-tag (raw "Stdo!")) @@ -1926,36 +1926,101 @@ expect { (e-num (value "12")) (e-num (value "3")))))) (s-expr - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err")))))))))))))))))) + (e-match + (match + (cond + (e-dot-access (field "recd") + (receiver + (e-match + (match + (cond + (e-dot-access (field "ned") + (receiver + (e-match + (match + (cond + (e-dot-access (field "od") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) (e-tag (name "Stdo!") (args (e-string diff --git a/test/snapshots/fuzz_crash/fuzz_crash_020.md b/test/snapshots/fuzz_crash/fuzz_crash_020.md index 2e37b15dcb..515d91240f 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_020.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_020.md @@ -1431,20 +1431,20 @@ EndOfFile, (e-binop (op "<=") (e-int (raw "12")) (e-int (raw "3"))))) - (e-field-access + (e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "e_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw "od"))))) (e-question-suffix - (e-apply - (e-ident (raw "ned"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "e_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw "od"))))) + (e-apply + (e-ident (raw "ned"))))) (e-ident (raw "recd")))) (e-apply (e-tag (raw "Stdo!")) @@ -1921,36 +1921,101 @@ expect { (e-num (value "12")) (e-num (value "3")))))) (s-expr - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err")))))))))))))))))) + (e-match + (match + (cond + (e-dot-access (field "recd") + (receiver + (e-match + (match + (cond + (e-dot-access (field "ned") + (receiver + (e-match + (match + (cond + (e-dot-access (field "od") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) (e-tag (name "Stdo!") (args (e-string diff --git a/test/snapshots/fuzz_crash/fuzz_crash_023.md b/test/snapshots/fuzz_crash/fuzz_crash_023.md index af69947bd9..baf66a0615 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_023.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_023.md @@ -1815,20 +1815,20 @@ EndOfFile, (e-int (raw "5"))))))) (s-decl (p-ident (raw "static_dispatch_style")) - (e-field-access + (e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "some_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw "static_dispatch_method"))))) (e-question-suffix - (e-apply - (e-ident (raw "next_static_dispatch_method"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "some_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw "static_dispatch_method"))))) + (e-apply + (e-ident (raw "next_static_dispatch_method"))))) (e-ident (raw "record_field"))))) (e-question-suffix (e-apply @@ -2518,36 +2518,101 @@ expect { (e-num (value "5"))))))) (s-let (p-assign (ident "static_dispatch_style")) - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err")))))))))))))))))) + (e-match + (match + (cond + (e-dot-access (field "record_field") + (receiver + (e-match + (match + (cond + (e-dot-access (field "next_static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-dot-access (field "static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) (s-expr (e-match (match diff --git a/test/snapshots/fuzz_crash/fuzz_crash_027.md b/test/snapshots/fuzz_crash/fuzz_crash_027.md index ef7f16d462..1139527d7e 100644 --- a/test/snapshots/fuzz_crash/fuzz_crash_027.md +++ b/test/snapshots/fuzz_crash/fuzz_crash_027.md @@ -1654,20 +1654,20 @@ EndOfFile, (e-int (raw "5"))))))) (s-decl (p-ident (raw "stale")) - (e-field-access + (e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "some_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw "statod"))))) (e-question-suffix - (e-apply - (e-ident (raw "ned"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "some_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw "statod"))))) + (e-apply + (e-ident (raw "ned"))))) (e-ident (raw "recd"))))) (e-apply (e-tag (raw "Stdoline!")) @@ -2249,36 +2249,101 @@ expect { (e-num (value "5"))))))) (s-let (p-assign (ident "stale")) - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err")))))))))))))))))) + (e-match + (match + (cond + (e-dot-access (field "recd") + (receiver + (e-match + (match + (cond + (e-dot-access (field "ned") + (receiver + (e-match + (match + (cond + (e-dot-access (field "statod") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) (e-tag (name "Stdoline!") (args (e-string diff --git a/test/snapshots/fuzz_crash/fuzz_crash_028.md b/test/snapshots/fuzz_crash/fuzz_crash_028.md index d6a9878acf..22311bee3d 100644 Binary files a/test/snapshots/fuzz_crash/fuzz_crash_028.md and b/test/snapshots/fuzz_crash/fuzz_crash_028.md differ diff --git a/test/snapshots/fuzz_crash/fuzz_crash_049.md b/test/snapshots/fuzz_crash/fuzz_crash_049.md index 3509c527cd..383c10895f 100644 Binary files a/test/snapshots/fuzz_crash/fuzz_crash_049.md and b/test/snapshots/fuzz_crash/fuzz_crash_049.md differ diff --git a/test/snapshots/record_access_multiline_formatting_1.md b/test/snapshots/record_access_multiline_formatting_1.md index db11babe84..4a75a78f42 100644 --- a/test/snapshots/record_access_multiline_formatting_1.md +++ b/test/snapshots/record_access_multiline_formatting_1.md @@ -46,20 +46,20 @@ EndOfFile, ~~~ # PARSE ~~~clojure -(e-field-access +(e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "some_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw ".static_dispatch_method"))))) (e-question-suffix - (e-apply - (e-ident (raw ".next_static_dispatch_method"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "some_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw ".static_dispatch_method"))))) + (e-apply + (e-ident (raw ".next_static_dispatch_method"))))) (e-ident (raw ".record_field")))) ~~~ # FORMATTED @@ -68,36 +68,101 @@ NO CHANGE ~~~ # CANONICALIZE ~~~clojure -(e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err"))))))))))))))))) +(e-match + (match + (cond + (e-dot-access (field "record_field") + (receiver + (e-match + (match + (cond + (e-dot-access (field "next_static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-dot-access (field "static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err"))))))))))) ~~~ # TYPES ~~~clojure diff --git a/test/snapshots/record_access_multiline_formatting_4.md b/test/snapshots/record_access_multiline_formatting_4.md index 4a07aee804..96e90a86e8 100644 --- a/test/snapshots/record_access_multiline_formatting_4.md +++ b/test/snapshots/record_access_multiline_formatting_4.md @@ -46,20 +46,20 @@ EndOfFile, ~~~ # PARSE ~~~clojure -(e-field-access +(e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "some_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw ".static_dispatch_method"))))) (e-question-suffix - (e-apply - (e-ident (raw ".next_static_dispatch_method"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "some_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw ".static_dispatch_method"))))) + (e-apply + (e-ident (raw ".next_static_dispatch_method"))))) (e-ident (raw ".record_field")))) ~~~ # FORMATTED @@ -68,36 +68,101 @@ NO CHANGE ~~~ # CANONICALIZE ~~~clojure -(e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err"))))))))))))))))) +(e-match + (match + (cond + (e-dot-access (field "record_field") + (receiver + (e-match + (match + (cond + (e-dot-access (field "next_static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-dot-access (field "static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err"))))))))))) ~~~ # TYPES ~~~clojure diff --git a/test/snapshots/static_dispatch_super_test.md b/test/snapshots/static_dispatch_super_test.md index eaa4013734..118698bc3e 100644 --- a/test/snapshots/static_dispatch_super_test.md +++ b/test/snapshots/static_dispatch_super_test.md @@ -40,20 +40,20 @@ EndOfFile, ~~~ # PARSE ~~~clojure -(e-field-access +(e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "some_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw "static_dispatch_method"))))) (e-question-suffix - (e-apply - (e-ident (raw "next_static_dispatch_method"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "some_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw "static_dispatch_method"))))) + (e-apply + (e-ident (raw "next_static_dispatch_method"))))) (e-ident (raw "record_field")))) ~~~ # FORMATTED @@ -62,36 +62,101 @@ NO CHANGE ~~~ # CANONICALIZE ~~~clojure -(e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err"))))))))))))))))) +(e-match + (match + (cond + (e-dot-access (field "record_field") + (receiver + (e-match + (match + (cond + (e-dot-access (field "next_static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-dot-access (field "static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err"))))))))))) ~~~ # TYPES ~~~clojure diff --git a/test/snapshots/syntax_grab_bag.md b/test/snapshots/syntax_grab_bag.md index 699b055fd4..76031a14bf 100644 --- a/test/snapshots/syntax_grab_bag.md +++ b/test/snapshots/syntax_grab_bag.md @@ -1702,20 +1702,20 @@ EndOfFile, (e-int (raw "5"))))))) (s-decl (p-ident (raw "static_dispatch_style")) - (e-field-access + (e-question-suffix (e-field-access - (e-field-access - (e-question-suffix - (e-apply - (e-ident (raw "some_fn")) - (e-ident (raw "arg1")))) - (e-question-suffix - (e-apply - (e-ident (raw "static_dispatch_method"))))) (e-question-suffix - (e-apply - (e-ident (raw "next_static_dispatch_method"))))) - (e-question-suffix + (e-field-access + (e-question-suffix + (e-field-access + (e-question-suffix + (e-apply + (e-ident (raw "some_fn")) + (e-ident (raw "arg1")))) + (e-apply + (e-ident (raw "static_dispatch_method"))))) + (e-apply + (e-ident (raw "next_static_dispatch_method"))))) (e-ident (raw "record_field"))))) (e-question-suffix (e-apply @@ -2404,36 +2404,101 @@ expect { (e-num (value "5"))))))) (s-let (p-assign (ident "static_dispatch_style")) - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-dot-access (field "unknown") - (receiver - (e-match - (match - (cond - (e-call - (e-runtime-error (tag "ident_not_in_scope")) - (e-runtime-error (tag "ident_not_in_scope")))) - (branches - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-lookup-local - (p-assign (ident "#ok"))))) - (branch - (patterns - (pattern (degenerate false) - (p-applied-tag))) - (value - (e-return - (e-tag (name "Err") - (args - (e-lookup-local - (p-assign (ident "#err")))))))))))))))))) + (e-match + (match + (cond + (e-dot-access (field "record_field") + (receiver + (e-match + (match + (cond + (e-dot-access (field "next_static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-dot-access (field "static_dispatch_method") + (receiver + (e-match + (match + (cond + (e-call + (e-runtime-error (tag "ident_not_in_scope")) + (e-runtime-error (tag "ident_not_in_scope")))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) + (args))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))))) + (branches + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-lookup-local + (p-assign (ident "#ok"))))) + (branch + (patterns + (pattern (degenerate false) + (p-applied-tag))) + (value + (e-return + (e-tag (name "Err") + (args + (e-lookup-local + (p-assign (ident "#err")))))))))))) (s-expr (e-match (match