From 7a84dcd39c4331c540562fcce1e4f5bdbf1418eb Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Tue, 16 Apr 2024 16:25:20 +1000 Subject: [PATCH 01/72] don't unwrap intermediate answer if not required --- crates/compiler/can/src/suffixed.rs | 30 ++++++++++++++++++++- crates/compiler/can/tests/test_suffixed.rs | 31 ++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 3de1564b66..f81cb006b2 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -192,7 +192,9 @@ pub fn unwrap_suffixed_expression<'a>( // KEEP THIS HERE FOR DEBUGGING // USEFUL TO SEE THE UNWRAPPING // OF AST NODES AS THEY DESCEND - // dbg!(&loc_expr, &unwrapped_expression); + // if is_loc_expr_suffixed(loc_expr) { + // dbg!(&loc_expr, &unwrapped_expression); + // } unwrapped_expression } @@ -768,6 +770,10 @@ pub fn apply_task_await<'a>( return loc_arg; } + if is_intermediate_answer_with_same_ident(loc_pat, loc_new) { + return loc_arg; + } + let mut task_await_apply_args: Vec<&'a Loc>> = Vec::new_in(arena); // apply the unwrapped suffixed expression @@ -828,3 +834,25 @@ fn is_expr_task_ok<'a>(loc_expr: &'a Loc>) -> bool { _ => false, } } + +/// Detect when we are applying an identical Pattern and Ident +/// e.g. `Task.await foo \#a!0 -> #a!0` is the same as `foo` +fn is_intermediate_answer_with_same_ident<'a>( + loc_pat: &'a Loc>, + loc_expr: &'a Loc>, +) -> bool { + let pat_ident = match loc_pat.value { + Pattern::Identifier { ident, .. } => Some(ident), + _ => None, + }; + let exp_ident = match loc_expr.value { + Expr::Var { + module_name, ident, .. + } if module_name == "" => Some(ident), + _ => None, + }; + match (pat_ident, exp_ident) { + (Some(a), Some(b)) => a.starts_with("#") && a == b, + _ => false, + } +} diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index 4e3a6cb628..f80daeeed2 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -638,4 +638,35 @@ mod suffixed_tests { r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "isTrue", suffixed: 1 })], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-218 Var { module_name: "", ident: "line", suffixed: 1 }, [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-295 Var { module_name: "", ident: "isFalsey", suffixed: 1 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-343 Var { module_name: "", ident: "line", suffixed: 1 }, [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-435 Var { module_name: "", ident: "line", suffixed: 1 }, [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "isTrue", suffixed: 0 }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line", suffixed: 0 }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "isFalsey", suffixed: 0 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1", suffixed: 0 }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line", suffixed: 0 }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@430-445 Apply(@430-445 Var { module_name: "", ident: "line", suffixed: 0 }, [@436-445 Str(PlainLine("success"))], Space), @430-445 Closure([@430-445 Identifier { ident: "#!a2", suffixed: 0 }], @143-445 Apply(@143-445 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@430-445 Var { module_name: "", ident: "#!a2", suffixed: 0 }], BangSuffix))], BangSuffix)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg", suffixed: 0 }))] }"##, ); } + + /** + * Unwrap a trailing binops + ```roc + copy = \a,b -> + Task.await line "FOO" \{} -> + CMD.new "cp" + |> mapErr! ERR + + copy = \a,b -> + Task.await line "FOO" \{} -> + Task.await (CMD.new "cp" |> mapErr ERR) \#!a0 -> #!a0 + + copy = \a,b -> + Task.await line "FOO" \{} -> + CMD.new "cp" |> mapErr ERR + ``` + */ + #[test] + fn trailing_binops() { + run_test( + r#" + copy = \a,b -> + line! "FOO" + + CMD.new "cp" + |> mapErr! ERR + "#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-103], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "copy", suffixed: 0 }, @7-103 Closure([@8-9 Identifier { ident: "a", suffixed: 0 }, @10-11 Identifier { ident: "b", suffixed: 0 }], @36-42 Apply(@36-42 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@36-42 Apply(@36-42 Var { module_name: "", ident: "line", suffixed: 0 }, [@37-42 Str(PlainLine("FOO"))], Space), @36-42 Closure([@36-42 RecordDestructure([])], @60-103 Apply(@60-103 Var { module_name: "", ident: "mapErr", suffixed: 0 }, [@60-72 Apply(@60-67 Var { module_name: "CMD", ident: "new", suffixed: 0 }, [@68-72 Str(PlainLine("cp"))], Space), @100-103 Tag("ERR")], BinOp(Pizza)))], BangSuffix)))] }"#, + ); + } } From 0198a683c7ca69bcd3cd0147b700c8c2fb330854 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Wed, 17 Apr 2024 09:54:29 +1000 Subject: [PATCH 02/72] fix unwrapping of trailing expr --- crates/compiler/can/src/desugar.rs | 47 +++----- crates/compiler/can/src/suffixed.rs | 121 ++++++++------------- crates/compiler/can/tests/test_suffixed.rs | 14 +-- crates/compiler/parse/src/ast.rs | 19 ++++ 4 files changed, 89 insertions(+), 112 deletions(-) diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index 555deb765d..ad31f42502 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -9,8 +9,8 @@ use roc_module::called_via::{BinOp, CalledVia}; use roc_module::ident::ModuleName; use roc_parse::ast::Expr::{self, *}; use roc_parse::ast::{ - AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, StrSegment, ValueDef, - WhenBranch, + wrap_in_task_ok, AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, + StrSegment, ValueDef, WhenBranch, }; use roc_region::all::{LineInfo, Loc, Region}; @@ -189,33 +189,16 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>) sub_arg, sub_pat, sub_new, - }) => { - let ok_wrapped_return = arena.alloc(Loc::at( + }) => Body( + loc_pattern, + apply_task_await( + arena, loc_expr.region, - Expr::Apply( - arena.alloc(Loc::at( - loc_expr.region, - Expr::Var { - module_name: ModuleName::TASK, - ident: "ok", - suffixed: 0, - }, - )), - arena.alloc([sub_new]), - CalledVia::BangSuffix, - ), - )); - Body( - loc_pattern, - apply_task_await( - arena, - loc_expr.region, - sub_arg, - sub_pat, - ok_wrapped_return, - ), - ) - } + sub_arg, + sub_pat, + wrap_in_task_ok(arena, sub_new), + ), + ), Err(..) => Body( loc_pattern, arena.alloc(Loc::at(loc_expr.region, MalformedSuffixed(loc_expr))), @@ -248,7 +231,13 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>) ann_type, comment, body_pattern, - body_expr: apply_task_await(arena, body_expr.region, sub_arg, sub_pat, sub_new), + body_expr: apply_task_await( + arena, + body_expr.region, + sub_arg, + sub_pat, + wrap_in_task_ok(arena, sub_new), + ), }, Err(..) => AnnotatedBody { ann_pattern, diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index f81cb006b2..9edeb3adcf 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -6,7 +6,7 @@ use roc_error_macros::internal_error; use roc_module::called_via::CalledVia; use roc_module::ident::ModuleName; use roc_parse::ast::Expr::{self, *}; -use roc_parse::ast::{is_loc_expr_suffixed, Pattern, ValueDef}; +use roc_parse::ast::{is_loc_expr_suffixed, wrap_in_task_ok, Pattern, ValueDef}; use roc_region::all::{Loc, Region}; use std::cell::Cell; @@ -398,28 +398,12 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( sub_pat, sub_new, }) => { - let ok_wrapped_return = arena.alloc(Loc::at( - loc_expr.region, - Expr::Apply( - arena.alloc(Loc::at( - loc_expr.region, - Expr::Var { - module_name: ModuleName::TASK, - ident: "ok", - suffixed: 0, - }, - )), - arena.alloc([sub_new]), - CalledVia::BangSuffix, - ), - )); - let unwrapped_expression = apply_task_await( arena, sub_arg.region, sub_arg, sub_pat, - ok_wrapped_return, + wrap_in_task_ok(arena, sub_new), ); let mut new_if_thens = Vec::new_in(arena); @@ -557,28 +541,12 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( sub_pat, sub_new, }) => { - let ok_wrapped_return = arena.alloc(Loc::at( - loc_expr.region, - Expr::Apply( - arena.alloc(Loc::at( - loc_expr.region, - Expr::Var { - module_name: ModuleName::TASK, - ident: "ok", - suffixed: 0, - }, - )), - arena.alloc([sub_new]), - CalledVia::BangSuffix, - ), - )); - let unwrapped_final_else = apply_task_await( arena, sub_arg.region, sub_arg, sub_pat, - ok_wrapped_return, + wrap_in_task_ok(arena, sub_new), ); let new_if = arena.alloc(Loc::at( @@ -651,7 +619,8 @@ pub fn unwrap_suffixed_expression_defs_help<'a>( let next_expr = match unwrap_suffixed_expression(arena,loc_ret,maybe_def_pat) { Ok(next_expr) => next_expr, Err(EUnwrapped::UnwrappedSubExpr { sub_arg, sub_pat, sub_new }) => { - apply_task_await(arena,def_expr.region,sub_arg,sub_pat,sub_new) + // We need to apply Task.ok here as the defs final expression was unwrapped + apply_task_await(arena,def_expr.region,sub_arg,sub_pat,wrap_in_task_ok(arena, sub_new)) } Err(EUnwrapped::UnwrappedDefExpr(..)) | Err(EUnwrapped::Malformed) => { // TODO handle case when we have maybe_def_pat so can return an unwrapped up @@ -766,11 +735,13 @@ pub fn apply_task_await<'a>( ) -> &'a Loc> { // If the pattern and the new are the same then we don't need to unwrap anything // e.g. `Task.await foo \{} -> Task.ok {}` is the same as `foo` - if is_pattern_empty_record(loc_pat) && is_expr_task_ok(loc_new) { + if is_matching_empty_record(loc_pat, loc_new) { return loc_arg; } - if is_intermediate_answer_with_same_ident(loc_pat, loc_new) { + // If the pattern and the new are matching answers then we don't need to unwrap anything + // e.g. `Task.await foo \#!a1 -> Task.ok #!a1` is the same as `foo` + if is_matching_intermediate_answer(loc_pat, loc_new) { return loc_arg; } @@ -804,40 +775,39 @@ pub fn apply_task_await<'a>( )) } -fn is_pattern_empty_record<'a>(loc_pat: &'a Loc>) -> bool { - match loc_pat.value { +fn extract_wrapped_task_ok_value<'a>(loc_expr: &'a Loc>) -> Option<&'a Loc>> { + match loc_expr.value { + Expr::Apply(function, arguments, _) => match function.value { + Var { + module_name, ident, .. + } if module_name == ModuleName::TASK && ident == "ok" => arguments.first().copied(), + _ => None, + }, + _ => None, + } +} + +fn is_matching_empty_record<'a>( + loc_pat: &'a Loc>, + loc_expr: &'a Loc>, +) -> bool { + let is_empty_record = match extract_wrapped_task_ok_value(loc_expr) { + Some(task_expr) => match task_expr.value { + Expr::Record(collection) => collection.is_empty(), + _ => false, + }, + None => false, + }; + + let is_pattern_empty_record = match loc_pat.value { Pattern::RecordDestructure(collection) => collection.is_empty(), _ => false, - } + }; + + is_empty_record && is_pattern_empty_record } -fn is_expr_task_ok<'a>(loc_expr: &'a Loc>) -> bool { - match loc_expr.value { - Expr::Apply(function, arguments, _) => { - let is_task_ok = match function.value { - Var { - module_name, ident, .. - } => module_name == ModuleName::TASK && ident == "ok", - _ => false, - }; - - let is_arg_empty_record = arguments - .first() - .map(|arg_loc_expr| match arg_loc_expr.value { - Expr::Record(collection) => collection.is_empty(), - _ => false, - }) - .unwrap_or(false); - - is_task_ok && is_arg_empty_record - } - _ => false, - } -} - -/// Detect when we are applying an identical Pattern and Ident -/// e.g. `Task.await foo \#a!0 -> #a!0` is the same as `foo` -fn is_intermediate_answer_with_same_ident<'a>( +fn is_matching_intermediate_answer<'a>( loc_pat: &'a Loc>, loc_expr: &'a Loc>, ) -> bool { @@ -845,14 +815,17 @@ fn is_intermediate_answer_with_same_ident<'a>( Pattern::Identifier { ident, .. } => Some(ident), _ => None, }; - let exp_ident = match loc_expr.value { - Expr::Var { - module_name, ident, .. - } if module_name == "" => Some(ident), - _ => None, + let exp_ident = match extract_wrapped_task_ok_value(loc_expr) { + Some(task_expr) => match task_expr.value { + Expr::Var { + module_name, ident, .. + } if module_name.is_empty() && ident.starts_with('#') => Some(ident), + _ => None, + }, + None => None, }; match (pat_ident, exp_ident) { - (Some(a), Some(b)) => a.starts_with("#") && a == b, + (Some(a), Some(b)) => a == b, _ => false, } } diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index f80daeeed2..d911fafd35 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -84,8 +84,7 @@ mod suffixed_tests { ```roc main = foo! "bar" {} "baz" - main = - Task.await [foo "bar" {} "baz"] \#!a0 -> Task.ok #!a0 + main = foo "bar" {} "baz" ``` */ #[test] @@ -94,7 +93,7 @@ mod suffixed_tests { r#" main = foo! "bar" {} "baz" "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-26], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-26 Apply(@0-26 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@0-26 Apply(@0-26 Var { module_name: "", ident: "foo", suffixed: 0 }, [@12-17 Str(PlainLine("bar")), @18-20 Record([]), @21-26 Str(PlainLine("baz"))], Space), @0-26 Closure([@0-26 Identifier { ident: "#!a0", suffixed: 0 }], @0-26 Apply(@0-26 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@0-26 Var { module_name: "", ident: "#!a0", suffixed: 0 }], BangSuffix))], BangSuffix))] }"##, + r#"Defs { tags: [Index(2147483648)], regions: [@0-26], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-26 Apply(@0-26 Var { module_name: "", ident: "foo", suffixed: 0 }, [@12-17 Str(PlainLine("bar")), @18-20 Record([]), @21-26 Str(PlainLine("baz"))], Space))] }"#, ); } @@ -606,13 +605,10 @@ mod suffixed_tests { Task.await line "fail" \{} -> err 1 else Task.await isFalsey Bool.false \#!a1 -> - if (#!a0) then + if (#!a1) then Task.await line "nope" \{} -> ok {} else - # note the unwrapping here doesn't use {} - # as the parsed Defs is unwrapped earlier to - # an Apply - Task.await line "success" \#!a2 -> Task.ok #!a2 + line "success" ``` */ #[test] @@ -635,7 +631,7 @@ mod suffixed_tests { msg "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "isTrue", suffixed: 1 })], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-218 Var { module_name: "", ident: "line", suffixed: 1 }, [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-295 Var { module_name: "", ident: "isFalsey", suffixed: 1 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-343 Var { module_name: "", ident: "line", suffixed: 1 }, [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-435 Var { module_name: "", ident: "line", suffixed: 1 }, [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "isTrue", suffixed: 0 }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line", suffixed: 0 }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "isFalsey", suffixed: 0 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1", suffixed: 0 }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line", suffixed: 0 }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@430-445 Apply(@430-445 Var { module_name: "", ident: "line", suffixed: 0 }, [@436-445 Str(PlainLine("success"))], Space), @430-445 Closure([@430-445 Identifier { ident: "#!a2", suffixed: 0 }], @143-445 Apply(@143-445 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@430-445 Var { module_name: "", ident: "#!a2", suffixed: 0 }], BangSuffix))], BangSuffix)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg", suffixed: 0 }))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "isTrue", suffixed: 1 })], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-218 Var { module_name: "", ident: "line", suffixed: 1 }, [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-295 Var { module_name: "", ident: "isFalsey", suffixed: 1 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-343 Var { module_name: "", ident: "line", suffixed: 1 }, [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-435 Var { module_name: "", ident: "line", suffixed: 1 }, [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "isTrue", suffixed: 0 }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line", suffixed: 0 }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "isFalsey", suffixed: 0 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1", suffixed: 0 }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line", suffixed: 0 }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "", ident: "line", suffixed: 0 }, [@436-445 Str(PlainLine("success"))], Space)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg", suffixed: 0 }))] }"##, ); } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index d575211c37..0cde720fb1 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -9,6 +9,7 @@ use bumpalo::Bump; use roc_collections::soa::{EitherIndex, Index, Slice}; use roc_error_macros::internal_error; use roc_module::called_via::{BinOp, CalledVia, UnaryOp}; +use roc_module::ident::ModuleName; use roc_region::all::{Loc, Position, Region}; #[derive(Debug, Clone, PartialEq, Eq)] @@ -450,6 +451,24 @@ pub fn is_loc_expr_suffixed(loc_expr: &Loc) -> bool { } } +pub fn wrap_in_task_ok<'a>(arena: &'a Bump, loc_expr: &'a Loc>) -> &'a Loc> { + arena.alloc(Loc::at( + loc_expr.region, + Expr::Apply( + arena.alloc(Loc::at( + loc_expr.region, + Expr::Var { + module_name: ModuleName::TASK, + ident: "ok", + suffixed: 0, + }, + )), + arena.alloc([loc_expr]), + CalledVia::BangSuffix, + ), + )) +} + pub fn split_around(items: &[T], target: usize) -> (&[T], &[T]) { let (before, rest) = items.split_at(target); let after = &rest[1..]; From a889810dfd4af0db2beab834e34a1e28a9a7843c Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Thu, 18 Apr 2024 09:44:57 +1000 Subject: [PATCH 03/72] unwrap suffixed when condition --- crates/compiler/can/src/suffixed.rs | 26 ++++++++++++++++++-- crates/compiler/can/tests/test_suffixed.rs | 28 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 9edeb3adcf..169ef113c3 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -564,11 +564,33 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( } pub fn unwrap_suffixed_expression_when_help<'a>( - _arena: &'a Bump, + arena: &'a Bump, loc_expr: &'a Loc>, _maybe_def_pat: Option<&'a Loc>>, ) -> Result<&'a Loc>, EUnwrapped<'a>> { - Ok(loc_expr) + match loc_expr.value { + Expr::When(condition, branches) => { + + // TODO first unwrap any when branches values + + // then unwrap the when condition + match unwrap_suffixed_expression(arena, condition, None) { + Ok(unwrapped_condition) => { + let new_when = arena.alloc(Loc::at(loc_expr.region, Expr::When(unwrapped_condition, branches))); + Ok(new_when) + } + Err(EUnwrapped::UnwrappedSubExpr { sub_arg, sub_pat, sub_new }) => { + let new_when = arena.alloc(Loc::at(loc_expr.region, Expr::When(sub_new, branches))); + let applied_task_await = apply_task_await(arena,loc_expr.region,sub_arg,sub_pat,new_when); + Ok(applied_task_await) + } + Err(EUnwrapped::UnwrappedDefExpr(..)) + | Err(EUnwrapped::Malformed) => Err(EUnwrapped::Malformed) + } + + } + _ => internal_error!("unreachable, expected a When node to be passed into unwrap_suffixed_expression_defs_help"), + } } pub fn unwrap_suffixed_expression_defs_help<'a>( diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index d911fafd35..166c2be5e5 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -665,4 +665,32 @@ mod suffixed_tests { r#"Defs { tags: [Index(2147483648)], regions: [@0-103], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "copy", suffixed: 0 }, @7-103 Closure([@8-9 Identifier { ident: "a", suffixed: 0 }, @10-11 Identifier { ident: "b", suffixed: 0 }], @36-42 Apply(@36-42 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@36-42 Apply(@36-42 Var { module_name: "", ident: "line", suffixed: 0 }, [@37-42 Str(PlainLine("FOO"))], Space), @36-42 Closure([@36-42 RecordDestructure([])], @60-103 Apply(@60-103 Var { module_name: "", ident: "mapErr", suffixed: 0 }, [@60-72 Apply(@60-67 Var { module_name: "CMD", ident: "new", suffixed: 0 }, [@68-72 Str(PlainLine("cp"))], Space), @100-103 Tag("ERR")], BinOp(Pizza)))], BangSuffix)))] }"#, ); } + + /** + * Unwrap a when expression + ```roc + list = + when getList! is + [] -> "empty" + _ -> "non-empty" + + list = + Task.await getList \#!a0 -> + when #!a0 is + [] -> "empty" + _ -> "non-empty" + ``` + */ + #[test] + fn when_simple() { + run_test( + r#" + list = + when getList! is + [] -> "empty" + _ -> "non-empty" + "#, + r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @24-111 Apply(@24-111 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @24-111 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @24-111 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, + ); + } } From ae908f89a969b2a287481a610f089cf085633b1f Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Thu, 18 Apr 2024 12:47:11 +1000 Subject: [PATCH 04/72] suffixed when branches --- crates/compiler/can/src/suffixed.rs | 34 ++++++++++++++-- crates/compiler/can/tests/test_suffixed.rs | 45 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 169ef113c3..86fef367ca 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -6,7 +6,7 @@ use roc_error_macros::internal_error; use roc_module::called_via::CalledVia; use roc_module::ident::ModuleName; use roc_parse::ast::Expr::{self, *}; -use roc_parse::ast::{is_loc_expr_suffixed, wrap_in_task_ok, Pattern, ValueDef}; +use roc_parse::ast::{is_loc_expr_suffixed, wrap_in_task_ok, Pattern, ValueDef, WhenBranch}; use roc_region::all::{Loc, Region}; use std::cell::Cell; @@ -566,12 +566,40 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( pub fn unwrap_suffixed_expression_when_help<'a>( arena: &'a Bump, loc_expr: &'a Loc>, - _maybe_def_pat: Option<&'a Loc>>, + maybe_def_pat: Option<&'a Loc>>, ) -> Result<&'a Loc>, EUnwrapped<'a>> { match loc_expr.value { Expr::When(condition, branches) => { - // TODO first unwrap any when branches values + // first unwrap any when branches values + // e.g. + // when foo is + // [] -> line! "bar" + // _ -> line! "baz" + for (branch_index, WhenBranch{value: branch_loc_expr,patterns, guard}) in branches.iter().enumerate() { + + // if the branch isn't suffixed we can leave it alone + if is_loc_expr_suffixed(branch_loc_expr) { + let unwrapped_branch_value = match unwrap_suffixed_expression(arena, branch_loc_expr, None) { + Ok(unwrapped_branch_value) => unwrapped_branch_value, + Err(EUnwrapped::UnwrappedSubExpr { sub_arg, sub_pat, sub_new }) => apply_task_await(arena, branch_loc_expr.region, sub_arg, sub_pat, sub_new), + Err(..) => return Err(EUnwrapped::Malformed), + }; + + let new_branch = WhenBranch{value: *unwrapped_branch_value, patterns, guard: *guard}; + let mut new_branches = Vec::new_in(arena); + let (before, rest) = branches.split_at(branch_index); + let after = &rest[1..]; + + new_branches.extend_from_slice(before); + new_branches.push(arena.alloc(new_branch)); + new_branches.extend_from_slice(after); + + let new_when = arena.alloc(Loc::at(loc_expr.region, Expr::When(condition, arena.alloc_slice_copy(new_branches.as_slice())))); + + return unwrap_suffixed_expression(arena, new_when, maybe_def_pat); + } + } // then unwrap the when condition match unwrap_suffixed_expression(arena, condition, None) { diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index 166c2be5e5..e294aaa242 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -693,4 +693,49 @@ mod suffixed_tests { r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @24-111 Apply(@24-111 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @24-111 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @24-111 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, ); } + + /** + * Unwrap a when expression + ```roc + list = + when getList! is + [] -> + line! "foo" + line! "bar" + _ -> + ok {} + + list = + Task.await getList \#!a0 -> + when getList is + [] -> + line! "foo" + line! "bar" + _ -> + ok {} + + list = + Task.await getList \#!a0 -> + when getList is + [] -> + Task.await line "foo" \{} -> line! "bar" + _ -> + ok {} + ``` + */ + #[test] + fn when_branches() { + run_test( + r#" + list = + when getList! is + [] -> + line! "foo" + line! "bar" + _ -> + ok {} + "#, + r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @24-195 Apply(@24-195 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @24-195 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @24-195 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line", suffixed: 0 }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line", suffixed: 0 }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok", suffixed: 0 }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, + ); + } } From 02689de79742ab0d759fce4ed729d21c8faeb9c2 Mon Sep 17 00:00:00 2001 From: Nathaniel Knight Date: Wed, 17 Apr 2024 20:50:17 -0700 Subject: [PATCH 05/72] Minor fix to the docstring of `Num.shiftLeftBy` --- crates/compiler/builtins/roc/Num.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index ea1845dbba..a72be1f798 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -1001,7 +1001,7 @@ bitwiseNot = \n -> ## ```roc ## shiftLeftBy 0b0000_0011 2 == 0b0000_1100 ## -## 0b0000_0101 |> shiftLeftBy 2 == 0b0000_1100 +## 0b0000_0101 |> shiftLeftBy 2 == 0b0001_0100 ## ``` ## In some languages `shiftLeftBy` is implemented as a binary operator `<<`. shiftLeftBy : Int a, U8 -> Int a From 5e738a4ab50a1b86d853dd0d13e3256e954956dd Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Fri, 19 Apr 2024 10:31:20 +1000 Subject: [PATCH 06/72] fix recursion in top-level def --- crates/compiler/can/src/desugar.rs | 48 ++++++++++++---------- crates/compiler/can/tests/test_suffixed.rs | 23 ++++++++++- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index ad31f42502..fb36715300 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -189,14 +189,17 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>) sub_arg, sub_pat, sub_new, - }) => Body( - loc_pattern, - apply_task_await( - arena, - loc_expr.region, - sub_arg, - sub_pat, - wrap_in_task_ok(arena, sub_new), + }) => desugar_value_def_suffixed( + arena, + Body( + loc_pattern, + apply_task_await( + arena, + loc_expr.region, + sub_arg, + sub_pat, + wrap_in_task_ok(arena, sub_new), + ), ), ), Err(..) => Body( @@ -226,19 +229,22 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>) sub_arg, sub_pat, sub_new, - }) => AnnotatedBody { - ann_pattern, - ann_type, - comment, - body_pattern, - body_expr: apply_task_await( - arena, - body_expr.region, - sub_arg, - sub_pat, - wrap_in_task_ok(arena, sub_new), - ), - }, + }) => desugar_value_def_suffixed( + arena, + AnnotatedBody { + ann_pattern, + ann_type, + comment, + body_pattern, + body_expr: apply_task_await( + arena, + body_expr.region, + sub_arg, + sub_pat, + wrap_in_task_ok(arena, sub_new), + ), + }, + ), Err(..) => AnnotatedBody { ann_pattern, ann_type, diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index d911fafd35..8d0ba49847 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -420,6 +420,26 @@ mod suffixed_tests { ); } + /** + * Nested suffixed expressions + ```roc + run = line! (nextMsg!) + + run = Task.await nextMsg \#!a0 -> line! (#!a0) + + run = Task.await nextMsg \#!a0 -> line (#!a0) + ``` + */ + #[test] + fn nested_simple() { + run_test( + r#" + run = line! (nextMsg!) + "#, + r##"Defs { tags: [Index(2147483648)], regions: [@0-22], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-3 Identifier { ident: "run", suffixed: 0 }, @0-22 Apply(@0-22 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "nextMsg", suffixed: 0 }, @0-22 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @0-22 Apply(@0-22 Var { module_name: "", ident: "line", suffixed: 0 }, [@13-21 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space))], BangSuffix))] }"##, + ); + } + /** * Nested suffixed expressions ```roc @@ -437,9 +457,8 @@ mod suffixed_tests { Task.await [foo (#!a0) (blah stuff)] \z -> doSomething z ``` */ - #[test] - fn nested_suffixed() { + fn nested_complex() { run_test( r#" main = From 83e723dfd11830fe3f13a81fd36bfab592fbcb5b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:01:13 +0000 Subject: [PATCH 07/72] Bump rustls from 0.21.7 to 0.21.11 Bumps [rustls](https://github.com/rustls/rustls) from 0.21.7 to 0.21.11. - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustls/rustls/compare/v/0.21.7...v/0.21.11) --- updated-dependencies: - dependency-name: rustls dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c7c59334c..ffd0d19e7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2216,12 +2216,27 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + [[package]] name = "rlimit" version = "0.9.1" @@ -3229,12 +3244,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", - "ring", + "ring 0.17.8", "rustls-webpki", "sct", ] @@ -3250,12 +3265,12 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -3370,8 +3385,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3600,6 +3615,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -4278,6 +4299,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.4.1" From 50d2111919825bd0189807a953557e0b32b10b11 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 18 Apr 2024 14:51:19 -1000 Subject: [PATCH 08/72] Remove unnecessary arg to check_indent Quick refactoring / follow-up to #6634 --- crates/compiler/parse/src/blankspace.rs | 9 ++------- crates/compiler/parse/src/expr.rs | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/crates/compiler/parse/src/blankspace.rs b/crates/compiler/parse/src/blankspace.rs index 85a4fd53bd..be518b62aa 100644 --- a/crates/compiler/parse/src/blankspace.rs +++ b/crates/compiler/parse/src/blankspace.rs @@ -197,17 +197,12 @@ where ) } -pub fn check_indent<'a, E>( - indent_problem: fn(Position) -> E, - inside_suffixed_statement: bool, -) -> impl Parser<'a, (), E> +pub fn check_indent<'a, E>(indent_problem: fn(Position) -> E) -> impl Parser<'a, (), E> where E: 'a, { - let extra_spaces = if inside_suffixed_statement { 1 } else { 0 }; - move |_, state: State<'a>, min_indent: u32| { - if state.column() >= (min_indent + extra_spaces) { + if state.column() >= min_indent { Ok((NoProgress, (), state)) } else { Err((NoProgress, indent_problem(state.pos()))) diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 53738a6010..c98168247d 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1638,11 +1638,13 @@ fn finish_parsing_ability_def_help<'a>( Ok((MadeProgress, (type_def, def_region), state)) } +#[allow(clippy::too_many_arguments)] fn parse_expr_operator<'a>( min_indent: u32, options: ExprParseOptions, mut expr_state: ExprState<'a>, loc_op: Loc, + line_indent: u32, arena: &'a Bump, state: State<'a>, initial_state: State<'a>, @@ -1687,7 +1689,8 @@ fn parse_expr_operator<'a>( } BinOp::Assignment => { let expr_region = expr_state.expr.region; - let indented_more = min_indent + 1; + + let indented_more = line_indent + 1; let call = expr_state .validate_assignment_or_backpassing(arena, loc_op, EExpr::ElmStyleFunction) @@ -1894,12 +1897,18 @@ fn parse_expr_end<'a>( state: State<'a>, initial_state: State<'a>, ) -> ParseResult<'a, Expr<'a>, EExpr<'a>> { + let inner_min_indent = if options.suffixed_found { + min_indent + 1 + } else { + min_indent + }; + let parser = skip_first!( - crate::blankspace::check_indent(EExpr::IndentEnd, options.suffixed_found), + crate::blankspace::check_indent(EExpr::IndentEnd), loc_term_or_underscore(options) ); - match parser.parse(arena, state.clone(), min_indent) { + match parser.parse(arena, state.clone(), inner_min_indent) { Err((MadeProgress, f)) => Err((MadeProgress, f)), Ok(( _, @@ -2001,6 +2010,7 @@ fn parse_expr_end<'a>( Err((NoProgress, _)) => { let before_op = state.clone(); // try an operator + let line_indent = state.line_indent(); match loc!(operator()).parse(arena, state.clone(), min_indent) { Err((MadeProgress, f)) => Err((MadeProgress, f)), Ok((_, loc_op, state)) => { @@ -2011,6 +2021,7 @@ fn parse_expr_end<'a>( options, expr_state, loc_op, + line_indent, arena, state, initial_state, From a24daeaa57775277476ee3c39b5cee954fdbadfc Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Sat, 20 Apr 2024 11:20:10 -0700 Subject: [PATCH 09/72] Fix syntax fuzzer cargo config --- crates/compiler/test_syntax/fuzz/Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/compiler/test_syntax/fuzz/Cargo.toml b/crates/compiler/test_syntax/fuzz/Cargo.toml index 26a786ff2a..b1389d04d7 100644 --- a/crates/compiler/test_syntax/fuzz/Cargo.toml +++ b/crates/compiler/test_syntax/fuzz/Cargo.toml @@ -2,9 +2,9 @@ name = "test_syntax-fuzz" publish = false -authors.workspace = true -edition.workspace = true -version.workspace = true +version = "0.0.0" +authors = ["Automatically generated"] +edition = "2021" [package.metadata] cargo-fuzz = true @@ -12,8 +12,8 @@ cargo-fuzz = true [dependencies] test_syntax = { path = "../../test_syntax" } -bumpalo.workspace = true -libfuzzer-sys.workspace = true +bumpalo = { version = "3.12.0", features = ["collections"] } +libfuzzer-sys = "0.4" # Prevent this from interfering with workspaces [workspace] From 6844df6c376acf0e5cd7b411aa899972d66c2083 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sun, 21 Apr 2024 13:27:50 +1000 Subject: [PATCH 10/72] fix parsing lists in tag patterns --- crates/compiler/parse/src/pattern.rs | 1 + .../pass/when_result_list.expr.result-ast | 54 +++++++++++++++++++ .../snapshots/pass/when_result_list.expr.roc | 3 ++ .../test_syntax/tests/test_snapshots.rs | 1 + 4 files changed, 59 insertions(+) create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.result-ast create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.roc diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index 00cdb5faad..3f5db773ec 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -205,6 +205,7 @@ fn loc_parse_tag_pattern_arg<'a>() -> impl Parser<'a, Loc>, EPattern crate::pattern::record_pattern_help() )), loc!(string_like_pattern_help()), + loc!(specialize_err(EPattern::List, list_pattern_help())), loc!(number_pattern_help()) ) } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.result-ast new file mode 100644 index 0000000000..95c72ad9b5 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.result-ast @@ -0,0 +1,54 @@ +When( + @5-10 Apply( + @5-7 Tag( + "Ok", + ), + [ + @8-10 List( + [], + ), + ], + Space, + ), + [ + WhenBranch { + patterns: [ + @18-23 SpaceBefore( + Apply( + @18-20 Tag( + "Ok", + ), + [ + @21-23 List( + [], + ), + ], + ), + [ + Newline, + ], + ), + ], + value: @27-29 Record( + [], + ), + guard: None, + }, + WhenBranch { + patterns: [ + @34-35 SpaceBefore( + Underscore( + "", + ), + [ + Newline, + ], + ), + ], + value: @39-41 Record( + [], + ), + guard: None, + }, + ], +) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.roc new file mode 100644 index 0000000000..d15158314c --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_result_list.expr.roc @@ -0,0 +1,3 @@ +when Ok [] is + Ok [] -> {} + _ -> {} \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs index 38b22321a7..4cefbbe3dc 100644 --- a/crates/compiler/test_syntax/tests/test_snapshots.rs +++ b/crates/compiler/test_syntax/tests/test_snapshots.rs @@ -482,6 +482,7 @@ mod test_snapshots { pass/when_in_function_python_style_indent.expr, pass/when_in_parens.expr, pass/when_in_parens_indented.expr, + pass/when_result_list.expr, pass/when_with_alternative_patterns.expr, pass/when_with_function_application.expr, pass/when_with_negative_numbers.expr, From 9ad6d9248c7003df1e372a09f8b58cf70ea17afb Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sun, 21 Apr 2024 13:32:38 +1000 Subject: [PATCH 11/72] converge loc_pattern_help_help and loc_parse_tag_pattern_arg --- crates/compiler/parse/src/pattern.rs | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index 3f5db773ec..1dadd9890a 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -46,7 +46,7 @@ pub fn closure_param<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { move |arena, state: State<'a>, min_indent| { - let (_, pattern, state) = loc_pattern_help_help().parse(arena, state, min_indent)?; + let (_, pattern, state) = loc_pattern_help_help(true).parse(arena, state, min_indent)?; let pattern_state = state.clone(); @@ -82,11 +82,13 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> } } -fn loc_pattern_help_help<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { +fn loc_pattern_help_help<'a>( + can_have_arguments: bool, +) -> impl Parser<'a, Loc>, EPattern<'a>> { one_of!( specialize_err(EPattern::PInParens, loc_pattern_in_parens_help()), loc!(underscore_pattern_help()), - loc_ident_pattern_help(true), + loc_ident_pattern_help(can_have_arguments), loc!(specialize_err( EPattern::Record, crate::pattern::record_pattern_help() @@ -143,7 +145,7 @@ fn loc_tag_pattern_arg<'a>( min_indent, )?; - let (_, loc_pat, state) = loc_parse_tag_pattern_arg().parse(arena, state, min_indent)?; + let (_, loc_pat, state) = loc_pattern_help_help(false).parse(arena, state, min_indent)?; let Loc { region, value } = loc_pat; @@ -194,22 +196,6 @@ pub fn loc_implements_parser<'a>() -> impl Parser<'a, Loc>, EPatt ) } -fn loc_parse_tag_pattern_arg<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { - one_of!( - specialize_err(EPattern::PInParens, loc_pattern_in_parens_help()), - loc!(underscore_pattern_help()), - // Make sure `Foo Bar 1` is parsed as `Foo (Bar) 1`, and not `Foo (Bar 1)` - loc_ident_pattern_help(false), - loc!(specialize_err( - EPattern::Record, - crate::pattern::record_pattern_help() - )), - loc!(string_like_pattern_help()), - loc!(specialize_err(EPattern::List, list_pattern_help())), - loc!(number_pattern_help()) - ) -} - fn loc_pattern_in_parens_help<'a>() -> impl Parser<'a, Loc>, PInParens<'a>> { then( loc!(collection_trailing_sep_e!( From d69d2ee940151a0f3019fcae413e290677c5b6d9 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sun, 21 Apr 2024 13:45:04 +1000 Subject: [PATCH 12/72] replace removed comment --- crates/compiler/parse/src/pattern.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index 1dadd9890a..65319495c5 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -145,6 +145,7 @@ fn loc_tag_pattern_arg<'a>( min_indent, )?; + // Cannot have arguments here, pass `false` to make sure `Foo Bar 1` is parsed as `Foo (Bar) 1`, and not `Foo (Bar 1)` let (_, loc_pat, state) = loc_pattern_help_help(false).parse(arena, state, min_indent)?; let Loc { region, value } = loc_pat; From 2c480dda549b16ac73f9c37e57b744a06ce7e74d Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 21 Apr 2024 15:16:59 -0400 Subject: [PATCH 13/72] Fix some missing HTML tags --- www/content/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/www/content/index.md b/www/content/index.md index 465def9a0d..d996a2eede 100644 --- a/www/content/index.md +++ b/www/content/index.md @@ -146,12 +146,12 @@ If you would like your organization to become an official sponsor of Roc's devel We'd also like to express our gratitude to our generous [individual sponsors](https://github.com/sponsors/roc-lang/)! A special thanks to those sponsoring $25/month or more:
    -
  • Krzysztof G. -
  • Sam Mohr -
  • Steven Chen -
  • Drew Lazzeri -
  • Alex Binaei -
  • Jono Mallanyk +
  • Krzysztof G.
  • +
  • Sam Mohr
  • +
  • Steven Chen
  • +
  • Drew Lazzeri
  • +
  • Alex Binaei
  • +
  • Jono Mallanyk
  • Chris Packett
  • James Birtles
  • Ivo Balbaert
  • From 839cf0ca45f6457802fa3f6b615875c571f26079 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 21 Apr 2024 15:17:22 -0400 Subject: [PATCH 14/72] =?UTF-8?q?Add=20@noverby=20to=20sponsors=20-=20than?= =?UTF-8?q?k=20you=20so=20much!=20=F0=9F=92=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + www/content/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 08eb5f8a82..2ce3787c79 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ If you would like your company to become a corporate sponsor of Roc's developmen We'd also like to express our gratitude to our generous [individual sponsors](https://github.com/sponsors/roc-lang/)! A special thanks to those sponsoring $25/month or more: +* [Niclas Overby](https://github.com/noverby) * [Krzysztof G.](https://github.com/krzysztofgb) * [Sam Mohr](https://github.com/smores56) * [Steven Chen](https://github.com/megakilo) diff --git a/www/content/index.md b/www/content/index.md index d996a2eede..2edff5cf97 100644 --- a/www/content/index.md +++ b/www/content/index.md @@ -146,6 +146,7 @@ If you would like your organization to become an official sponsor of Roc's devel We'd also like to express our gratitude to our generous [individual sponsors](https://github.com/sponsors/roc-lang/)! A special thanks to those sponsoring $25/month or more:
      +
    • Niclas Overby
    • Krzysztof G.
    • Sam Mohr
    • Steven Chen
    • From e9a4335cc23aaed675deab49db571f4009bba312 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 21 Apr 2024 15:17:41 -0400 Subject: [PATCH 15/72] =?UTF-8?q?Add=20@AngeloChecked=20to=20sponsors=20-?= =?UTF-8?q?=20thank=20you=20so=20much!=20=F0=9F=92=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + www/content/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 2ce3787c79..5fb6a139e9 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ If you would like your company to become a corporate sponsor of Roc's developmen We'd also like to express our gratitude to our generous [individual sponsors](https://github.com/sponsors/roc-lang/)! A special thanks to those sponsoring $25/month or more: +* [Angelo Ceccato](https://github.com/AngeloChecked) * [Niclas Overby](https://github.com/noverby) * [Krzysztof G.](https://github.com/krzysztofgb) * [Sam Mohr](https://github.com/smores56) diff --git a/www/content/index.md b/www/content/index.md index 2edff5cf97..3e72cf3e21 100644 --- a/www/content/index.md +++ b/www/content/index.md @@ -146,6 +146,7 @@ If you would like your organization to become an official sponsor of Roc's devel We'd also like to express our gratitude to our generous [individual sponsors](https://github.com/sponsors/roc-lang/)! A special thanks to those sponsoring $25/month or more:
        +
      • Angelo Ceccato
      • Niclas Overby
      • Krzysztof G.
      • Sam Mohr
      • From 88c4a3af4e23d00aaf95c8f79bbf8d9e1056f363 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 21 Apr 2024 18:03:56 -0500 Subject: [PATCH 16/72] Rename lang_srv to language_server --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- crates/{lang_srv => language_server}/Cargo.toml | 2 +- crates/{lang_srv => language_server}/README.md | 0 crates/{lang_srv => language_server}/TODO.md | 0 crates/{lang_srv => language_server}/debug_server.sh | 0 crates/{lang_srv => language_server}/src/analysis.rs | 0 .../src/analysis/analysed_doc.rs | 0 .../{lang_srv => language_server}/src/analysis/completion.rs | 0 .../src/analysis/completion/formatting.rs | 0 .../src/analysis/completion/visitor.rs | 0 .../{lang_srv => language_server}/src/analysis/parse_ast.rs | 0 .../src/analysis/parse_ast/format.rs | 0 .../src/analysis/semantic_tokens.rs | 0 crates/{lang_srv => language_server}/src/analysis/tokens.rs | 0 crates/{lang_srv => language_server}/src/analysis/utils.rs | 0 crates/{lang_srv => language_server}/src/convert.rs | 0 crates/{lang_srv => language_server}/src/registry.rs | 0 crates/{lang_srv => language_server}/src/server.rs | 0 19 files changed, 4 insertions(+), 4 deletions(-) rename crates/{lang_srv => language_server}/Cargo.toml (97%) rename crates/{lang_srv => language_server}/README.md (100%) rename crates/{lang_srv => language_server}/TODO.md (100%) rename crates/{lang_srv => language_server}/debug_server.sh (100%) rename crates/{lang_srv => language_server}/src/analysis.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/analysed_doc.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/completion.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/completion/formatting.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/completion/visitor.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/parse_ast.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/parse_ast/format.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/semantic_tokens.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/tokens.rs (100%) rename crates/{lang_srv => language_server}/src/analysis/utils.rs (100%) rename crates/{lang_srv => language_server}/src/convert.rs (100%) rename crates/{lang_srv => language_server}/src/registry.rs (100%) rename crates/{lang_srv => language_server}/src/server.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index ffd0d19e7a..f8728080e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2665,7 +2665,7 @@ name = "roc_ident" version = "0.0.1" [[package]] -name = "roc_lang_srv" +name = "roc_language_server" version = "0.0.1" dependencies = [ "bumpalo", diff --git a/Cargo.toml b/Cargo.toml index f937797e27..b7ce6437ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ members = [ "crates/wasi-libc-sys", "crates/wasm_module", "crates/wasm_interp", - "crates/lang_srv", + "crates/language_server", ] exclude = [ @@ -195,4 +195,4 @@ lto = "thin" # TODO: We could consider full here since this is only used for pac [profile.debug-full] inherits = "dev" -debug = true \ No newline at end of file +debug = true diff --git a/crates/lang_srv/Cargo.toml b/crates/language_server/Cargo.toml similarity index 97% rename from crates/lang_srv/Cargo.toml rename to crates/language_server/Cargo.toml index 2e5c853337..a2b0394ded 100644 --- a/crates/lang_srv/Cargo.toml +++ b/crates/language_server/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "roc_lang_srv" +name = "roc_language_server" version = "0.0.1" edition = "2021" diff --git a/crates/lang_srv/README.md b/crates/language_server/README.md similarity index 100% rename from crates/lang_srv/README.md rename to crates/language_server/README.md diff --git a/crates/lang_srv/TODO.md b/crates/language_server/TODO.md similarity index 100% rename from crates/lang_srv/TODO.md rename to crates/language_server/TODO.md diff --git a/crates/lang_srv/debug_server.sh b/crates/language_server/debug_server.sh similarity index 100% rename from crates/lang_srv/debug_server.sh rename to crates/language_server/debug_server.sh diff --git a/crates/lang_srv/src/analysis.rs b/crates/language_server/src/analysis.rs similarity index 100% rename from crates/lang_srv/src/analysis.rs rename to crates/language_server/src/analysis.rs diff --git a/crates/lang_srv/src/analysis/analysed_doc.rs b/crates/language_server/src/analysis/analysed_doc.rs similarity index 100% rename from crates/lang_srv/src/analysis/analysed_doc.rs rename to crates/language_server/src/analysis/analysed_doc.rs diff --git a/crates/lang_srv/src/analysis/completion.rs b/crates/language_server/src/analysis/completion.rs similarity index 100% rename from crates/lang_srv/src/analysis/completion.rs rename to crates/language_server/src/analysis/completion.rs diff --git a/crates/lang_srv/src/analysis/completion/formatting.rs b/crates/language_server/src/analysis/completion/formatting.rs similarity index 100% rename from crates/lang_srv/src/analysis/completion/formatting.rs rename to crates/language_server/src/analysis/completion/formatting.rs diff --git a/crates/lang_srv/src/analysis/completion/visitor.rs b/crates/language_server/src/analysis/completion/visitor.rs similarity index 100% rename from crates/lang_srv/src/analysis/completion/visitor.rs rename to crates/language_server/src/analysis/completion/visitor.rs diff --git a/crates/lang_srv/src/analysis/parse_ast.rs b/crates/language_server/src/analysis/parse_ast.rs similarity index 100% rename from crates/lang_srv/src/analysis/parse_ast.rs rename to crates/language_server/src/analysis/parse_ast.rs diff --git a/crates/lang_srv/src/analysis/parse_ast/format.rs b/crates/language_server/src/analysis/parse_ast/format.rs similarity index 100% rename from crates/lang_srv/src/analysis/parse_ast/format.rs rename to crates/language_server/src/analysis/parse_ast/format.rs diff --git a/crates/lang_srv/src/analysis/semantic_tokens.rs b/crates/language_server/src/analysis/semantic_tokens.rs similarity index 100% rename from crates/lang_srv/src/analysis/semantic_tokens.rs rename to crates/language_server/src/analysis/semantic_tokens.rs diff --git a/crates/lang_srv/src/analysis/tokens.rs b/crates/language_server/src/analysis/tokens.rs similarity index 100% rename from crates/lang_srv/src/analysis/tokens.rs rename to crates/language_server/src/analysis/tokens.rs diff --git a/crates/lang_srv/src/analysis/utils.rs b/crates/language_server/src/analysis/utils.rs similarity index 100% rename from crates/lang_srv/src/analysis/utils.rs rename to crates/language_server/src/analysis/utils.rs diff --git a/crates/lang_srv/src/convert.rs b/crates/language_server/src/convert.rs similarity index 100% rename from crates/lang_srv/src/convert.rs rename to crates/language_server/src/convert.rs diff --git a/crates/lang_srv/src/registry.rs b/crates/language_server/src/registry.rs similarity index 100% rename from crates/lang_srv/src/registry.rs rename to crates/language_server/src/registry.rs diff --git a/crates/lang_srv/src/server.rs b/crates/language_server/src/server.rs similarity index 100% rename from crates/lang_srv/src/server.rs rename to crates/language_server/src/server.rs From 2763bc57cbd0ad2699dd61496abd671b43640833 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 21 Apr 2024 18:19:59 -0500 Subject: [PATCH 17/72] Some minor cleanup in language_server --- crates/language_server/src/analysis.rs | 62 +++++++++---------- .../src/analysis/analysed_doc.rs | 16 +++-- .../src/analysis/completion.rs | 4 +- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/crates/language_server/src/analysis.rs b/crates/language_server/src/analysis.rs index fc8ce27d10..1214bbe589 100644 --- a/crates/language_server/src/analysis.rs +++ b/crates/language_server/src/analysis.rs @@ -33,50 +33,49 @@ use self::{analysed_doc::ModuleIdToUrl, tokens::Token}; pub const HIGHLIGHT_TOKENS_LEGEND: &[SemanticTokenType] = Token::LEGEND; -/// Contains hashmaps of info about all modules that were analyzed #[derive(Debug)] -pub(super) struct ModulesInfo { - subs: Mutex>, - exposed: HashMap>>, - docs: VecMap, +struct ModulesInfo { + subs_by_module: HashMap>, + exposed_by_module: HashMap>>, + docs_by_module: HashMap, } impl ModulesInfo { - fn with_subs(&self, mod_id: &ModuleId, f: F) -> Option + fn with_subs(&self, module_id: &ModuleId, f: F) -> Option where F: FnOnce(&mut Subs) -> A, { - self.subs.lock().get_mut(mod_id).map(f) + let subs = self.subs_by_module.get(module_id)?; + Some(f(&mut subs.lock())) } - /// Transforms some of the raw data from the analysis into a state that is - /// more useful during processes like completion. - fn from_analysis( + + fn get_docs(&self, module_id: &ModuleId) -> Option<&ModuleDocumentation> { + self.docs_by_module.get(module_id) + } + + fn from_loaded_module( exposes: MutMap>, typechecked: &MutMap, docs_by_module: VecMap, ) -> ModulesInfo { - // We wrap this in Arc because later we will go through each module's imports and - // store the full list of symbols that each imported module exposes. - // example: A imports B. B exposes [add, multiply, divide] and A will store a reference to that list. - let exposed = exposes + let exposed_by_module = exposes .into_iter() .map(|(module_id, symbols)| (module_id, Arc::new(symbols))) .collect::>(); - // Combine the subs from all modules - let all_subs = Mutex::new( - typechecked - .iter() - .map(|(module_id, checked_module)| { - (*module_id, checked_module.solved_subs.0.clone()) - }) - .collect::>(), - ); + let subs_by_module = typechecked + .iter() + .map(|(module_id, checked_module)| { + (*module_id, checked_module.solved_subs.0.clone().into()) + }) + .collect::>(); + + let docs_by_module = docs_by_module.into_iter().collect(); ModulesInfo { - subs: all_subs, - exposed, - docs: docs_by_module, + subs_by_module, + exposed_by_module, + docs_by_module, } } } @@ -84,15 +83,14 @@ impl ModulesInfo { #[derive(Debug, Clone)] pub(super) struct AnalyzedModule { exposed_imports: Vec<(Symbol, Variable)>, - /// imports are grouped by which module they come from - imports: HashMap>>, + imports_by_module: HashMap>>, module_id: ModuleId, interns: Interns, subs: Subs, abilities: AbilitiesStore, declarations: Declarations, modules_info: Arc, - // We need this because ModuleIds are not stable between compilations, so a ModuleId visible to + // ModuleIds are not stable between compilations, so a ModuleId visible to // one module may not be true global to the language server. module_id_to_url: ModuleIdToUrl, } @@ -164,7 +162,7 @@ pub(crate) fn global_analysis(doc_info: DocInfo) -> Vec { let exposed_imports = resolve_exposed_imports(exposed_imports, &exposes); - let modules_info = Arc::new(ModulesInfo::from_analysis( + let modules_info = Arc::new(ModulesInfo::from_loaded_module( exposes, &typechecked, docs_by_module, @@ -304,7 +302,7 @@ impl<'a> AnalyzedDocumentBuilder<'a> { let analyzed_module = AnalyzedModule { exposed_imports, - imports, + imports_by_module: imports, subs, abilities, declarations, @@ -342,7 +340,7 @@ impl<'a> AnalyzedDocumentBuilder<'a> { ( id, self.modules_info - .exposed + .exposed_by_module .get(&id) .unwrap_or(&Arc::new(vec![])) .clone(), diff --git a/crates/language_server/src/analysis/analysed_doc.rs b/crates/language_server/src/analysis/analysed_doc.rs index b97e355d1e..29431b9f83 100644 --- a/crates/language_server/src/analysis/analysed_doc.rs +++ b/crates/language_server/src/analysis/analysed_doc.rs @@ -69,6 +69,7 @@ impl DocInfo { let end = Position::new(self.line_info.num_lines(), 0); Range::new(start, end) } + pub fn get_prefix_at_position(&self, position: Position) -> String { let position = position.to_roc_position(&self.line_info); let offset = position.offset as usize; @@ -82,6 +83,7 @@ impl DocInfo { String::from(symbol) } + pub fn format(&self) -> Option> { let source = &self.source; let arena = &Bump::new(); @@ -175,10 +177,12 @@ impl AnalyzedDocument { let (region, var) = roc_can::traverse::find_closest_type_at(pos, declarations)?; - //TODO:Can this be integrated into find closest type? is it even worth it? - let docs_opt = self - .symbol_at(position) - .and_then(|symb| modules_info.docs.get(module_id)?.get_doc_for_symbol(&symb)); + //TODO: Can this be integrated into "find closest type"? Is it worth it? + let docs_opt = self.symbol_at(position).and_then(|symbol| { + modules_info + .get_docs(module_id)? + .get_doc_for_symbol(&symbol) + }); let type_str = format_var_type(var, &mut subs.clone(), module_id, interns); @@ -238,7 +242,7 @@ impl AnalyzedDocument { subs, declarations, exposed_imports, - imports, + imports_by_module: imports, modules_info, .. } = self.module()?; @@ -299,7 +303,7 @@ impl AnalyzedDocument { &mut subs.clone(), module_id, interns, - modules_info.docs.get(module_id), + modules_info.get_docs(module_id), exposed_imports, ); Some(completions) diff --git a/crates/language_server/src/analysis/completion.rs b/crates/language_server/src/analysis/completion.rs index cfe16478f9..8bacf8c3b1 100644 --- a/crates/language_server/src/analysis/completion.rs +++ b/crates/language_server/src/analysis/completion.rs @@ -77,7 +77,7 @@ pub(super) fn get_module_completion_items( mod_id, interns, exposed_symbols, - modules_info.docs.get(mod_id), + modules_info.get_docs(mod_id), modules_info, )), ..Default::default() @@ -90,7 +90,7 @@ pub(super) fn get_module_completion_items( exposed_symbols, modules_info, mod_id, - modules_info.docs.get(mod_id), + modules_info.get_docs(mod_id), interns, ) } else { From 32c4083364200332a55a6913ea90ab4ad322ac33 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Mon, 22 Apr 2024 18:38:26 +1000 Subject: [PATCH 18/72] add new tests for trailing ! --- crates/compiler/can/tests/test_suffixed.rs | 66 ++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index 02dfe89475..d47220fe77 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -757,4 +757,70 @@ mod suffixed_tests { r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @24-195 Apply(@24-195 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @24-195 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @24-195 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line", suffixed: 0 }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line", suffixed: 0 }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok", suffixed: 0 }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, ); } + + #[test] + fn trailing_suffix_inside_when() { + run_test( + r#" + main = + result = Stdin.line! + + when result is + End -> + Task.ok {} + + Input name -> + Stdout.line! "Hello, $(name)" + "#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-226], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @32-43 Apply(@32-43 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@32-43 Var { module_name: "Stdin", ident: "line", suffixed: 0 }, @32-43 Closure([@23-29 Identifier { ident: "result", suffixed: 0 }], @61-226 When(@66-72 Var { module_name: "", ident: "result", suffixed: 0 }, [WhenBranch { patterns: [@96-99 Tag("End")], value: @127-137 Apply(@127-134 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@135-137 Record([])], Space), guard: None }, WhenBranch { patterns: [@159-169 Apply(@159-164 Tag("Input"), [@165-169 Identifier { ident: "name", suffixed: 0 }])], value: @197-226 Apply(@197-226 Var { module_name: "Stdout", ident: "line", suffixed: 0 }, [@210-226 Str(Line([Plaintext("Hello, "), Interpolated(@220-224 Var { module_name: "", ident: "name", suffixed: 0 })]))], Space), guard: None }]))], BangSuffix))] }"#, + ); + } +} + +#[cfg(test)] +mod test_suffixed_helpers { + + use roc_can::suffixed::is_matching_intermediate_answer; + use roc_module::called_via::CalledVia; + use roc_module::ident::ModuleName; + use roc_parse::ast::Expr; + use roc_parse::ast::Pattern; + use roc_region::all::Loc; + + #[test] + fn test_matching_answer() { + let loc_pat = Loc::at_zero(Pattern::Identifier { + ident: "#!a0", + suffixed: 0, + }); + let loc_new = Loc::at_zero(Expr::Var { + module_name: "", + ident: "#!a0", + suffixed: 0, + }); + + std::assert_eq!(is_matching_intermediate_answer(&loc_pat, &loc_new), true); + } + + #[test] + fn test_matching_answer_task_ok() { + let loc_pat = Loc::at_zero(Pattern::Identifier { + ident: "#!a0", + suffixed: 0, + }); + let intermetiate = &[&Loc::at_zero(Expr::Var { + module_name: "", + ident: "#!a0", + suffixed: 0, + })]; + let task_ok = Loc::at_zero(Expr::Var { + module_name: ModuleName::TASK, + ident: "ok", + suffixed: 0, + }); + + let loc_new = Loc::at_zero(Expr::Apply(&task_ok, intermetiate, CalledVia::BangSuffix)); + + std::assert_eq!(is_matching_intermediate_answer(&loc_pat, &loc_new), true); + } } From aa5dc09900f40ac72d3662928597f6e443fe65fe Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Mon, 22 Apr 2024 18:38:51 +1000 Subject: [PATCH 19/72] support for more trailing ! --- crates/compiler/can/src/suffixed.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 86fef367ca..9ecfcb28bf 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -857,15 +857,21 @@ fn is_matching_empty_record<'a>( is_empty_record && is_pattern_empty_record } -fn is_matching_intermediate_answer<'a>( +pub fn is_matching_intermediate_answer<'a>( loc_pat: &'a Loc>, - loc_expr: &'a Loc>, + loc_new: &'a Loc>, ) -> bool { let pat_ident = match loc_pat.value { Pattern::Identifier { ident, .. } => Some(ident), _ => None, }; - let exp_ident = match extract_wrapped_task_ok_value(loc_expr) { + let exp_iten = match loc_new.value { + Expr::Var { + module_name, ident, .. + } if module_name.is_empty() && ident.starts_with('#') => Some(ident), + _ => None, + }; + let exp_ident_in_task = match extract_wrapped_task_ok_value(loc_new) { Some(task_expr) => match task_expr.value { Expr::Var { module_name, ident, .. @@ -874,8 +880,9 @@ fn is_matching_intermediate_answer<'a>( }, None => None, }; - match (pat_ident, exp_ident) { - (Some(a), Some(b)) => a == b, + match (pat_ident, exp_iten, exp_ident_in_task) { + (Some(a), Some(b), None) => a == b, + (Some(a), None, Some(b)) => a == b, _ => false, } } From 84cd4233be0e4ef5b5a18122a53562ea1f7b82b3 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Mon, 22 Apr 2024 18:55:34 +1000 Subject: [PATCH 20/72] clippy fix --- crates/compiler/can/tests/test_suffixed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index d47220fe77..37a788ac66 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -799,7 +799,7 @@ mod test_suffixed_helpers { suffixed: 0, }); - std::assert_eq!(is_matching_intermediate_answer(&loc_pat, &loc_new), true); + std::assert!(is_matching_intermediate_answer(&loc_pat, &loc_new)); } #[test] @@ -821,6 +821,6 @@ mod test_suffixed_helpers { let loc_new = Loc::at_zero(Expr::Apply(&task_ok, intermetiate, CalledVia::BangSuffix)); - std::assert_eq!(is_matching_intermediate_answer(&loc_pat, &loc_new), true); + std::assert!(is_matching_intermediate_answer(&loc_pat, &loc_new)); } } From 442121bfc7ef2951b93a7bc618b7ef056ea087a8 Mon Sep 17 00:00:00 2001 From: Jackson Wambolt Date: Mon, 22 Apr 2024 21:17:47 -0500 Subject: [PATCH 21/72] Fix lang-server nix package build crash --- nix/builder.nix | 2 +- nix/default.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nix/builder.nix b/nix/builder.nix index 212e838be7..31fc1df682 100644 --- a/nix/builder.nix +++ b/nix/builder.nix @@ -3,7 +3,7 @@ let inherit (compile-deps) zigPkg llvmPkgs llvmVersion llvmMajorMinorStr glibcPath libGccSPath; subPackagePath = if subPackage != null then "crates/${subPackage}" else null; - mainBin = if subPackage == "lang_srv" then "roc_language_server" else "roc"; + mainBin = if subPackage == "language_server" then "roc_language_server" else "roc"; filteredSource = pkgs.callPackage ./fileFilter.nix { }; in rustPlatform.buildRustPackage { diff --git a/nix/default.nix b/nix/default.nix index d62664a142..8a9e167816 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -18,7 +18,7 @@ let # all rust crates in workspace.members of Cargo.toml roc-full = callPackage ./builder.nix { }; - roc-lang-server = callPackage ./builder.nix { subPackage = "lang_srv"; }; + roc-lang-server = callPackage ./builder.nix { subPackage = "language_server"; }; # only the CLI crate = executable provided in nightly releases roc-cli = callPackage ./builder.nix { subPackage = "cli"; }; }; From 7b594fc1127d7e1915164089970fc3b0d559afc4 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:47:39 +0200 Subject: [PATCH 22/72] basic-cli-091-release --- .github/workflows/basic_cli_build_release.yml | 4 ++-- .github/workflows/ci_manager.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/basic_cli_build_release.yml b/.github/workflows/basic_cli_build_release.yml index 620d0795c0..a095a7cb11 100644 --- a/.github/workflows/basic_cli_build_release.yml +++ b/.github/workflows/basic_cli_build_release.yml @@ -1,5 +1,5 @@ on: -# pull_request: + pull_request: workflow_dispatch: # this cancels workflows currently in progress if you start a new one @@ -11,7 +11,7 @@ env: # use .tar.gz for quick testing ARCHIVE_FORMAT: .tar.br # Make a new basic-cli git tag and set it here before starting this workflow - RELEASE_TAG: 0.9.0 + RELEASE_TAG: 0.9.1 jobs: prepare: diff --git a/.github/workflows/ci_manager.yml b/.github/workflows/ci_manager.yml index a33b81920d..684f3ff499 100644 --- a/.github/workflows/ci_manager.yml +++ b/.github/workflows/ci_manager.yml @@ -1,5 +1,5 @@ on: - pull_request: +# pull_request: name: CI manager From 8902f3e9e35f216ce91e2e1642dc53903a934864 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:57:04 +0200 Subject: [PATCH 23/72] fix typo Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- crates/compiler/can/src/suffixed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 9ecfcb28bf..35961c4ddd 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -865,7 +865,7 @@ pub fn is_matching_intermediate_answer<'a>( Pattern::Identifier { ident, .. } => Some(ident), _ => None, }; - let exp_iten = match loc_new.value { + let exp_ident = match loc_new.value { Expr::Var { module_name, ident, .. } if module_name.is_empty() && ident.starts_with('#') => Some(ident), @@ -880,7 +880,7 @@ pub fn is_matching_intermediate_answer<'a>( }, None => None, }; - match (pat_ident, exp_iten, exp_ident_in_task) { + match (pat_ident, exp_ident, exp_ident_in_task) { (Some(a), Some(b), None) => a == b, (Some(a), None, Some(b)) => a == b, _ => false, From c5c0fe9453a8248d087efbd09b212abeae42858a Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:02:59 +0200 Subject: [PATCH 24/72] debugging Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- ci/build_basic_cli.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/build_basic_cli.sh b/ci/build_basic_cli.sh index b9f984a0e1..f7cf49ca9e 100755 --- a/ci/build_basic_cli.sh +++ b/ci/build_basic_cli.sh @@ -6,6 +6,9 @@ set -euxo pipefail git clone https://github.com/roc-lang/basic-cli.git cd basic-cli git checkout $RELEASE_TAG +echo $RELEASE_TAG +cat platform/Stdout.roc +paniccc cd .. if [ "$(uname -s)" == "Linux" ]; then From b084c18e631b295ec843b67db14c0693218be57e Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:42:45 +0200 Subject: [PATCH 25/72] use correct src files --- .github/workflows/basic_cli_build_release.yml | 6 +++++- ci/build_basic_cli.sh | 3 --- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/basic_cli_build_release.yml b/.github/workflows/basic_cli_build_release.yml index a095a7cb11..32adaa4199 100644 --- a/.github/workflows/basic_cli_build_release.yml +++ b/.github/workflows/basic_cli_build_release.yml @@ -158,7 +158,11 @@ jobs: - name: rename nightly folder run: mv roc_nightly* roc_nightly - - run: git clone https://github.com/roc-lang/basic-cli.git + - run: | + git clone https://github.com/roc-lang/basic-cli.git + cd basic-cli + git checkout $RELEASE_TAG + cd .. - run: cp macos-apple-silicon-files/* ./basic-cli/platform diff --git a/ci/build_basic_cli.sh b/ci/build_basic_cli.sh index f7cf49ca9e..b9f984a0e1 100755 --- a/ci/build_basic_cli.sh +++ b/ci/build_basic_cli.sh @@ -6,9 +6,6 @@ set -euxo pipefail git clone https://github.com/roc-lang/basic-cli.git cd basic-cli git checkout $RELEASE_TAG -echo $RELEASE_TAG -cat platform/Stdout.roc -paniccc cd .. if [ "$(uname -s)" == "Linux" ]; then From 05ab4fc67df0590d75c5e8b728575f4e4cb3fb23 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:10:00 +0200 Subject: [PATCH 26/72] fix missing zlib on macos-13 zlib suddenly is no longer included in the macos 13 github action runner image... Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/test_nightly_many_os.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_nightly_many_os.yml b/.github/workflows/test_nightly_many_os.yml index 1e679041c2..36f149f140 100644 --- a/.github/workflows/test_nightly_many_os.yml +++ b/.github/workflows/test_nightly_many_os.yml @@ -18,12 +18,15 @@ jobs: with: version: 0.11.0 + - name: Install zlib on macOS-13 + if: matrix.os == 'macos-13' + run: brew install zlib + - name: get the latest release archive for linux (x86_64) if: startsWith(matrix.os, 'ubuntu') run: | curl -fOL https://github.com/roc-lang/roc/releases/download/nightly/roc_nightly-linux_x86_64-latest.tar.gz - - name: get the latest release archive for macos (x86_64) if: startsWith(matrix.os, 'macos') run: curl -fOL https://github.com/roc-lang/roc/releases/download/nightly/roc_nightly-macos_x86_64-latest.tar.gz From 29e59dfec985d04be45b43804fd1c363d2cccb7c Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:06:33 +0200 Subject: [PATCH 27/72] upgrade to basic-cli 0.9.1 --- crates/cli/tests/cli_run.rs | 2 +- crates/compiler/load_internal/tests/test_load.rs | 2 +- .../pass/newline_in_packages.full.formatted.roc | 2 +- .../pass/newline_in_packages.full.result-ast | 2 +- .../snapshots/pass/newline_in_packages.full.roc | 2 +- examples/cli/argsBROKEN.roc | 2 +- examples/cli/countdown.roc | 2 +- examples/cli/echo.roc | 2 +- examples/cli/env.roc | 2 +- examples/cli/fileBROKEN.roc | 2 +- examples/cli/form.roc | 2 +- examples/cli/http-get.roc | 2 +- examples/cli/ingested-file-bytes.roc | 2 +- examples/cli/ingested-file.roc | 2 +- examples/helloWorld.roc | 2 +- examples/inspect-logging.roc | 2 +- examples/parser/letter-counts.roc | 2 +- examples/parser/parse-movies-csv.roc | 2 +- www/content/platforms.md | 2 +- www/content/tutorial.md | 12 ++++++------ 20 files changed, 25 insertions(+), 25 deletions(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index ed57a4681b..f969c399f0 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -948,7 +948,7 @@ mod cli_run { This roc file can print its own source code. The source is: app "ingested-file" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [ pf.Stdout, "ingested-file.roc" as ownCode : Str, diff --git a/crates/compiler/load_internal/tests/test_load.rs b/crates/compiler/load_internal/tests/test_load.rs index 5454e697ce..ba0e57c084 100644 --- a/crates/compiler/load_internal/tests/test_load.rs +++ b/crates/compiler/load_internal/tests/test_load.rs @@ -1280,7 +1280,7 @@ fn roc_file_no_extension() { indoc!( r#" app "helloWorld" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc index 7c7a463b69..5e804ba783 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc @@ -1,7 +1,7 @@ app "hello" packages { pf: - "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br", + "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", } imports [pf.Stdout] provides [main] to pf diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast index d591a22da4..c60a44392d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast @@ -24,7 +24,7 @@ Full { Newline, ], package_name: @31-145 PackageName( - "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br", + "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", ), }, [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc index dabd9b4601..25148860d5 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc @@ -1,6 +1,6 @@ app "hello" packages { pf: -"https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" +"https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/examples/cli/argsBROKEN.roc b/examples/cli/argsBROKEN.roc index 837aaddb12..1d301f4757 100644 --- a/examples/cli/argsBROKEN.roc +++ b/examples/cli/argsBROKEN.roc @@ -1,5 +1,5 @@ app "args" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout, pf.Arg, pf.Task.{ Task }] provides [main] to pf diff --git a/examples/cli/countdown.roc b/examples/cli/countdown.roc index af64cef158..7f5173bbdc 100644 --- a/examples/cli/countdown.roc +++ b/examples/cli/countdown.roc @@ -1,5 +1,5 @@ app "countdown" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdin, pf.Stdout, pf.Task.{ await, loop }] provides [main] to pf diff --git a/examples/cli/echo.roc b/examples/cli/echo.roc index 1f929378ad..7b6e04bc2b 100644 --- a/examples/cli/echo.roc +++ b/examples/cli/echo.roc @@ -1,5 +1,5 @@ app "echo" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdin, pf.Stdout, pf.Task.{ Task }] provides [main] to pf diff --git a/examples/cli/env.roc b/examples/cli/env.roc index 03963bcd98..aef97a5978 100644 --- a/examples/cli/env.roc +++ b/examples/cli/env.roc @@ -1,5 +1,5 @@ app "env" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout, pf.Stderr, pf.Env, pf.Task.{ Task }] provides [main] to pf diff --git a/examples/cli/fileBROKEN.roc b/examples/cli/fileBROKEN.roc index f686aa46e7..007eb669bf 100644 --- a/examples/cli/fileBROKEN.roc +++ b/examples/cli/fileBROKEN.roc @@ -1,5 +1,5 @@ app "file-io" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [ pf.Stdout, pf.Stderr, diff --git a/examples/cli/form.roc b/examples/cli/form.roc index 5a850cfca7..cb447acfa9 100644 --- a/examples/cli/form.roc +++ b/examples/cli/form.roc @@ -1,5 +1,5 @@ app "form" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdin, pf.Stdout, pf.Task.{ await, Task }] provides [main] to pf diff --git a/examples/cli/http-get.roc b/examples/cli/http-get.roc index 5afb3e9aaa..eb922ea500 100644 --- a/examples/cli/http-get.roc +++ b/examples/cli/http-get.roc @@ -1,5 +1,5 @@ app "http-get" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Http, pf.Task.{ Task }, pf.Stdin, pf.Stdout] provides [main] to pf diff --git a/examples/cli/ingested-file-bytes.roc b/examples/cli/ingested-file-bytes.roc index 9b5ba1bfce..ebf5b67cef 100644 --- a/examples/cli/ingested-file-bytes.roc +++ b/examples/cli/ingested-file-bytes.roc @@ -1,5 +1,5 @@ app "ingested-file-bytes" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [ pf.Stdout, "../../LICENSE" as license : _, # A type hole can also be used here. diff --git a/examples/cli/ingested-file.roc b/examples/cli/ingested-file.roc index 47bc72412e..f6a420909c 100644 --- a/examples/cli/ingested-file.roc +++ b/examples/cli/ingested-file.roc @@ -1,5 +1,5 @@ app "ingested-file" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [ pf.Stdout, "ingested-file.roc" as ownCode : Str, diff --git a/examples/helloWorld.roc b/examples/helloWorld.roc index 512ea76f7a..172d634517 100644 --- a/examples/helloWorld.roc +++ b/examples/helloWorld.roc @@ -1,5 +1,5 @@ app "helloWorld" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/examples/inspect-logging.roc b/examples/inspect-logging.roc index 861b429b8c..0f69394d7d 100644 --- a/examples/inspect-logging.roc +++ b/examples/inspect-logging.roc @@ -2,7 +2,7 @@ # Shows how Roc values can be logged # app "inspect-logging" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [ pf.Stdout, Community, diff --git a/examples/parser/letter-counts.roc b/examples/parser/letter-counts.roc index 3b40690539..08769ba703 100644 --- a/examples/parser/letter-counts.roc +++ b/examples/parser/letter-counts.roc @@ -1,6 +1,6 @@ app "example" packages { - cli: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br", + cli: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br", } imports [ diff --git a/examples/parser/parse-movies-csv.roc b/examples/parser/parse-movies-csv.roc index b472ff48ce..fe1fd540f5 100644 --- a/examples/parser/parse-movies-csv.roc +++ b/examples/parser/parse-movies-csv.roc @@ -1,6 +1,6 @@ app "example" packages { - pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br", + pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br", } imports [ diff --git a/www/content/platforms.md b/www/content/platforms.md index 61bac0f91f..abb559033c 100644 --- a/www/content/platforms.md +++ b/www/content/platforms.md @@ -8,7 +8,7 @@ Here is a Roc application that prints `"Hello, World!"` to the command line: ```roc app "hello" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/www/content/tutorial.md b/www/content/tutorial.md index 816bd3ef75..a29d60d2f1 100644 --- a/www/content/tutorial.md +++ b/www/content/tutorial.md @@ -164,7 +164,7 @@ Make a file named `main.roc` and put this in it: ```roc app "hello" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf @@ -1436,7 +1436,7 @@ Let's take a closer look at the part of `main.roc` above the `main` def: ```roc app "hello" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf ``` @@ -1448,7 +1448,7 @@ The line `app "hello"` shows that this module is a Roc application. The "hello" The remaining lines all involve the [platform](https://github.com/roc-lang/roc/wiki/Roc-concepts-explained#platform) this application is built on: ```roc -packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } +packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf ``` @@ -1547,7 +1547,7 @@ Let's start with a basic "Hello World" program. ```roc app "cli-tutorial" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout] provides [main] to pf @@ -1581,7 +1581,7 @@ Let's change `main` to read a line from `stdin`, and then print what we got: ```roc app "cli-tutorial" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout, pf.Stdin, pf.Task] provides [main] to pf @@ -1626,7 +1626,7 @@ This works, but we can make it a little nicer to read. Let's change it to the fo ```roc app "cli-tutorial" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } imports [pf.Stdout, pf.Stdin, pf.Task.{ await }] provides [main] to pf From f4c2a7f8623a02b5b41c68d9010b980a3eddcd9d Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:41:24 +0200 Subject: [PATCH 28/72] back to normal CI --- .github/workflows/basic_cli_build_release.yml | 2 +- .github/workflows/ci_manager.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/basic_cli_build_release.yml b/.github/workflows/basic_cli_build_release.yml index 32adaa4199..8ddfcbce30 100644 --- a/.github/workflows/basic_cli_build_release.yml +++ b/.github/workflows/basic_cli_build_release.yml @@ -1,5 +1,5 @@ on: - pull_request: +# pull_request: workflow_dispatch: # this cancels workflows currently in progress if you start a new one diff --git a/.github/workflows/ci_manager.yml b/.github/workflows/ci_manager.yml index 684f3ff499..a33b81920d 100644 --- a/.github/workflows/ci_manager.yml +++ b/.github/workflows/ci_manager.yml @@ -1,5 +1,5 @@ on: -# pull_request: + pull_request: name: CI manager From 87feeb5135fa0fe97f8724b77b02759aa283e1ff Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Wed, 24 Apr 2024 08:45:29 +1000 Subject: [PATCH 29/72] add abilities for glue types --- crates/glue/platform/TypeId.roc | 14 ++++++++------ crates/glue/platform/Types.roc | 18 +++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/crates/glue/platform/TypeId.roc b/crates/glue/platform/TypeId.roc index e5e4f1f93a..21b5c26bfc 100644 --- a/crates/glue/platform/TypeId.roc +++ b/crates/glue/platform/TypeId.roc @@ -1,11 +1,13 @@ interface TypeId - exposes [TypeId, fromU64, toU64] + exposes [TypeId, typeIDfromU64, typeIDtoU64] imports [] -TypeId := U64 implements [Eq, Hash] +TypeId := U64 implements [Eq, Hash, Inspect, Encoding] -toU64 : TypeId -> U64 -toU64 = \@TypeId x -> x +# renamed here so we can import the functions directly as a workaround for +# https://github.com/roc-lang/roc/issues/5477 +typeIDtoU64 : TypeId -> U64 +typeIDtoU64 = \@TypeId x -> x -fromU64 : U64 -> TypeId -fromU64 = @TypeId +typeIDfromU64 : U64 -> TypeId +typeIDfromU64 = @TypeId diff --git a/crates/glue/platform/Types.roc b/crates/glue/platform/Types.roc index f4930759c1..3389e8cfcc 100644 --- a/crates/glue/platform/Types.roc +++ b/crates/glue/platform/Types.roc @@ -1,6 +1,6 @@ interface Types exposes [Types, shape, size, alignment, target, walkShapes, entryPoints] - imports [Shape.{ Shape }, TypeId.{ TypeId }, Target.{ Target }, TypeId] + imports [Shape.{ Shape }, TypeId.{ TypeId, typeIDfromU64, typeIDtoU64 }, Target.{ Target }] # TODO: switch AssocList uses to Dict once roc_std is updated. Tuple1 : [T Str TypeId] @@ -23,7 +23,7 @@ Types := { ## Names and types of the entry points of the program (e.g. mainForHost) entrypoints : List Tuple1, target : Target, -} +} implements [Inspect, Encoding] target : Types -> Target target = \@Types types -> types.target @@ -34,33 +34,33 @@ entryPoints = \@Types { entrypoints } -> entrypoints walkShapes : Types, state, (state, Shape, TypeId -> state) -> state walkShapes = \@Types { types: shapes }, originalState, update -> List.walkWithIndex shapes originalState \state, elem, index -> - id = TypeId.fromU64 index + id = typeIDfromU64 index update state elem id shape : Types, TypeId -> Shape shape = \@Types types, id -> - when List.get types.types (TypeId.toU64 id) is + when List.get types.types (typeIDtoU64 id) is Ok answer -> answer Err OutOfBounds -> - idStr = Num.toStr (TypeId.toU64 id) + idStr = Num.toStr (typeIDtoU64 id) crash "TypeId #$(idStr) was not found in Types. This should never happen, and means there was a bug in `roc glue`. If you have time, please open an issue at " alignment : Types, TypeId -> U32 alignment = \@Types types, id -> - when List.get types.aligns (TypeId.toU64 id) is + when List.get types.aligns (typeIDtoU64 id) is Ok answer -> answer Err OutOfBounds -> - idStr = Num.toStr (TypeId.toU64 id) + idStr = Num.toStr (typeIDtoU64 id) crash "TypeId #$(idStr) was not found in Types. This should never happen, and means there was a bug in `roc glue`. If you have time, please open an issue at " size : Types, TypeId -> U32 size = \@Types types, id -> - when List.get types.sizes (TypeId.toU64 id) is + when List.get types.sizes (typeIDtoU64 id) is Ok answer -> answer Err OutOfBounds -> - idStr = Num.toStr (TypeId.toU64 id) + idStr = Num.toStr (typeIDtoU64 id) crash "TypeId #$(idStr) was not found in Types. This should never happen, and means there was a bug in `roc glue`. If you have time, please open an issue at " From fc521e13ce50e4d48e2ea3e71cc40e9b441c8042 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 16:52:37 -0400 Subject: [PATCH 30/72] Update code example on homepage to use `!` --- www/InteractiveExample.roc | 39 +++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/www/InteractiveExample.roc b/www/InteractiveExample.roc index 474cd106d6..3536996383 100644 --- a/www/InteractiveExample.roc +++ b/www/InteractiveExample.roc @@ -19,39 +19,39 @@ view : Html.Node view = output = sectionsToStr [ - Desc [Comment "Click anything here to see an explanation.Tap anything here to\n# see an explanation."] "

        Comments in Roc begin with a # and go to the end of the line.

        ", + Desc [Comment "Click anything here to see an explanation.Tap anything here to\n# see an explanation."] "

        Comments in Roc begin with # and go to the end of the line.

        ", Newline, Desc [Ident "main", Kw "="] "

        This defines main, which is where our program will begin.

        In Roc, all definitions are constant, so writing main = again in the same scope would give an error.

        ", Indent, Desc [Ident "Path.fromStr", Str "\"url.txt\""] "

        This converts the string \"url.txt\" into a Path by passing it to Path.fromStr.

        Function arguments are separated with whitespace. Parentheses are only needed in nested function calls.

        ", - Newline, + Indent, Desc [Kw "|>", Ident "storeEmail"] "

        The pipe operator (|>) is syntax sugar for passing the previous value to the next function in the \"pipeline.\"

        This line takes the value that Path.fromStr \"url.txt\" returns and passes it to storeEmail.

        The next |> continues the pipeline.

        ", Newline, - Desc [Kw "|>", Ident "Task.onErr", Ident "handleErr"] "

        If the task returned by the previous step in the pipeline fails, pass its error to handleErr.

        The pipeline essentially does this:

        a = Path.fromStr \"url.txt\"\nb = storeEmail a\n\nTask.onErr b handleErr

        It creates a Path from a string, stores an email based on that path, and then does error handling.

        ", + Desc [Kw "|>", Ident "Task.onErr", Ident "handleErr"] "

        If the task returned by the previous step in the pipeline fails, pass its error to handleErr.

        The pipeline essentially does this:

        a = Path.fromStr \"url.txt\"\nb = storeEmail a\n\nTask.onErr b handleErr

        It creates a Path from a string, passes it to storeEmail, and specifies how to handle errors if storing the email fails.

        ", + Outdent, Outdent, - Newline, Desc [Ident "storeEmail", Kw "=", Lambda ["path"]] "

        This defines a function named storeEmail. It takes one argument, named path.

        In Roc, functions are ordinary values, so we assign names to them using = like with any other value.

        The \\arg1, arg2 -> syntax begins a function, and the part after -> is the function's body.

        ", Indent, - Desc [Ident "url", Kw "<-", Ident "File.readUtf8", Ident "path", Kw "|>", Ident "Task.await"] "

        This reads the contents of the file (as a UTF-8 string) into url.

        The <- does backpassing, which is syntax sugar for defining a function. This line desugars to:

        Task.await\n    (File.readUtf8 path)\n    \\url ->

        The lines after this one form the body of the \\url -> callback, which runs if the file read succeeds.

        ", + Desc [Ident "url", Kw "=", Ident "File.readUtf8!", Ident "path"] "

        This passes path to the File.readUtf8 function, which reads the contents of the file (as a UTF-8 string) into url.

        The ! operator is similar to await in other languages. It means “wait until the asynchronous File.readUtf8 operation successfully completes.”

        If the file read fails (maybe because path refers to a missing file), the rest of this function will be skipped, and the handleErr function will take over.

        ", Newline, - Desc [Ident "user", Kw "<-", Ident "Http.get", Ident "url", Ident "Json.codec", Kw "|>", Ident "Task.await"] "

        This fetches the contents of the URL and decodes them as JSON.

        If the shape of the JSON isn't compatible with the type of user (based on type inference), this will give a decoding error immediately.

        As with all the other lines ending in |> Task.await, if there's an error, nothing else in storeEmail will be run, and handleErr will end up handling the error.

        ", + Desc [Ident "user", Kw "=", Ident "Http.get!", Ident "url", Ident "Json.format"] "

        This fetches the contents of the URL and decodes them as JSON.

        If the shape of the JSON isn't compatible with the type of user (based on type inference), this will give a decoding error immediately.

        As with all the other function calls involving the ! operator, if there's an error, nothing else in storeEmail will be run, and handleErr will run.

        ", Newline, - Desc [Ident "dest", Kw "=", Ident "Path.fromStr", StrInterpolation "\"" "user.name" ".txt\""] "

        The \$(user.name) in this string literal will be replaced with the value in name. This is string interpolation.

        Note that this line doesn't end with |> Task.await. Earlier lines needed that because they were I/O tasks, but this is a plain old definition, so there's no task to await.

        ", + Desc [Ident "dest", Kw "=", Ident "Path.fromStr", StrInterpolation "\"" "user.name" ".txt\""] "

        The \$(user.name) in this string literal will be replaced with the value stored in the user record's name field. This is string interpolation.

        Note that this function call doesn't involve the ! operator. That's because Path.fromStr is a synchronous operation, so there's no need to use ! to wait for it to finish.

        ", Newline, - Desc [Literal "_", Kw "<-", Ident "File.writeUtf8", Ident "dest", Ident "user.email", Kw "|>", Ident "Task.await"] "

        This writes user.email to the file, encoded as UTF-8.

        We won't be using the output of writeUtf8, so we name it _. The special name _ is for when you don't want to use something.

        You can name as many things as you like _, but you can never reference anything named _. So it's only useful for when you don't want to choose a name.

        ", + Desc [Ident "File.writeUtf8!", Ident "dest", Ident "user.email"] "

        This writes user.email to the file, encoded as UTF-8.

        Since File.writeUtf8 doesn't produce any information on success, we don't bother using = like we did on the other lines.

        ", Newline, - Desc [Ident "Stdout.line", StrInterpolation "\"Wrote email to " "Path.display dest" "\""] "

        This prints what we did to stdout.

        Note that this line doesn't end with |> Task.await. That's because, although Stdout.line returns a task, we don't need to await it because nothing happens after it.

        ", + Desc [Ident "Stdout.line!", StrInterpolation "\"Wrote email to " "Path.display dest" "\""] "

        This prints what we did to stdout.

        Notice that this does a function call inside the string interpolation. Any valid Roc expression is allowed inside string interpolation, as long as it doesn't contain any newlines.

        ", Outdent, Newline, Desc [Ident "handleErr", Kw "=", Lambda ["err"]] "

        Like storeEmail, handleErr is also a function.

        Although type annotations are optional everywhere in Roc—because the language has 100% type inference—you could add type annotations to main, storeEmail, and handleErr if you wanted to.

        ", Indent, Desc [Kw "when", Ident "err", Kw "is"] "

        This will run one of the following lines depending on what value the err argument has.

        Each line does a pattern match on the shape of the error to decide whether to run, or to move on and try the next line's pattern.

        Roc will do compile-time exhaustiveness checking and tell you if you forgot to handle any error cases here that could have occurred, based on the tasks that were run in storeEmail.

        ", Indent, - Desc [Literal "HttpErr", Ident "url", Kw "_", Kw "->", Ident "Stderr.line", StrInterpolation "\"Error fetching URL " "url" "\""] "

        This line will run if the Http.get request from earlier encountered an HTTP error.

        It handles the error by printing an error message to stderr.

        The _ is where more information about the error is stored in the HttpErr. If we wanted to print more detail about what the error was, we'd name that something other than _ and actually use it.

        ", + Desc [Literal "HttpErr", Ident "url", Kw "_", Kw "->", Ident "Stderr.line!", StrInterpolation "\"Error fetching URL " "url" "\""] "

        This line will run if the Http.get request from earlier encountered an HTTP error.

        It handles the error by printing an error message to stderr.

        The _ is where more information about the error is stored in the HttpErr. If we wanted to print more detail about what the error was, we'd name that something other than _ and actually use it.

        ", Newline, - Desc [Literal "FileReadErr", Ident "path", Kw "_", Kw "->", Ident "Stderr.line", StrInterpolation "\"Error reading from " "Path.display path" "\""] "

        This line will run if the File.readUtf8 from earlier encountered a file I/O error.

        It handles the error by printing an error message to stderr.

        The _ is where more information about the error is stored in the FileReadErr. If we wanted to print more detail about what the error was, we'd name that something other than _ and actually use it.

        ", + Desc [Literal "FileReadErr", Ident "path", Kw "_", Kw "->", Ident "Stderr.line!", StrInterpolation "\"Error reading from " "Path.display path" "\""] "

        This line will run if the File.readUtf8 from earlier encountered a file I/O error.

        It handles the error by printing an error message to stderr.

        The _ is where more information about the error is stored in the FileReadErr. If we wanted to print more detail about what the error was, we'd name that something other than _ and actually use it.

        ", Newline, - Desc [Literal "FileWriteErr", Ident "path", Kw "_", Kw "->", Ident "Stderr.line", StrInterpolation "\"Error writing to " "Path.display path" "\""] "

        This line will run if the File.writeUtf8 from earlier encountered a file I/O error.

        It handles the error by printing an error message to stderr.

        The _ is where more information about the error is stored in the FileWriteErr. If we wanted to print more detail about what the error was, we'd name that something other than _ and actually use it.

        ", + Desc [Literal "FileWriteErr", Ident "path", Kw "_", Kw "->", Ident "Stderr.line!", StrInterpolation "\"Error writing to " "Path.display path" "\""] "

        This line will run if the File.writeUtf8 from earlier encountered a file I/O error.

        It handles the error by printing an error message to stderr.

        The _ is where more information about the error is stored in the FileWriteErr. If we wanted to print more detail about what the error was, we'd name that something other than _ and actually use it.

        ", ] div [role "presentation"] [ @@ -118,12 +118,21 @@ tokensToStr = \tokens -> identToHtml : Str -> Str identToHtml = \str -> List.walk (Str.split str ".") "" \accum, ident -> - identHtml = "$(ident)" + len = Str.countUtf8Bytes ident + withoutSuffix = ident |> Str.replaceLast "!" "" + + identHtml = "$(withoutSuffix)" + html = + # If removing a trailing "!" changed the length, then there must have been a trailing "!" + if len > Str.countUtf8Bytes withoutSuffix then + "$(identHtml)!" + else + identHtml if Str.isEmpty accum then - identHtml + html else - "$(accum).$(identHtml)" + "$(accum).$(html)" sectionsToStr : List Section -> Str sectionsToStr = \sections -> From 5b847a1f5f0e05dd6083cee5362281b4c8b4dcd7 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 16:53:53 -0400 Subject: [PATCH 31/72] Update /tutorial to include `!` suffix --- www/content/tutorial.md | 534 ++++++++++++++++++++++++---------------- www/public/site.css | 19 +- 2 files changed, 337 insertions(+), 216 deletions(-) diff --git a/www/content/tutorial.md b/www/content/tutorial.md index 816bd3ef75..76625b14b8 100644 --- a/www/content/tutorial.md +++ b/www/content/tutorial.md @@ -5,22 +5,13 @@
        1. REPL
        2. Building an Application
        3. -
        4. Defining Functions
        5. -
        6. if-then-else
        7. -
        8. Debugging
        9. -
        10. Records
        11. -
        12. Tags & Pattern Matching
        13. -
        14. Booleans
        15. -
        16. Lists
        17. +
        18. Pattern Matching
        19. Types
        20. -
        21. Numeric Types
        22. Crashing
        23. -
        24. Tests and Expectations
        25. +
        26. Testing
        27. Modules
        28. Tasks
        29. -
        30. Advanced Concepts
        31. -
        32. Reserved Keywords
        33. -
        34. Operator Desugaring Table
        35. +
        36. Advanced Concepts
        @@ -169,7 +160,7 @@ app "hello" provides [main] to pf main = - Stdout.line "I'm a Roc application!" + Stdout.line! "I'm a Roc application!" ``` Try running this with: @@ -194,7 +185,7 @@ iguanas = 2 total = Num.toStr (birds + iguanas) main = - Stdout.line "There are $(total) animals." + Stdout.line! "There are $(total) animals." ``` Now run `roc dev` again. This time the "Downloading ..." message won't appear; the file has been cached from last time, and won't need to be downloaded again. @@ -203,7 +194,7 @@ You should see this: There are 5 animals. -`main.roc` now has four definitions (_defs_ for short) `birds`, `iguanas`, `total`, and `main`. +`main.roc` now has four definitions (_defs_ for short) `birds`, `iguanas`, `total`, and `main`. A definition names an expression. @@ -234,7 +225,7 @@ iguanas = 2 total = addAndStringify birds iguanas main = - Stdout.line "There are $(total) animals." + Stdout.line! "There are $(total) animals." addAndStringify = \num1, num2 -> Num.toStr (num1 + num2) @@ -244,7 +235,7 @@ This new `addAndStringify` function we've defined accepts two numbers, adds them The `\num1, num2 ->` syntax defines a function's arguments, and the expression after the `->` is the body of the function. Whenever a function gets called, its body expression gets evaluated and returned. -### [if-then-else](#if-then-else) {#if-then-else} +### [`if`-`then`-`else` expressions](#if-then-else) {#if-then-else} Let's modify this function to return an empty string if the numbers add to zero. @@ -265,7 +256,7 @@ We did two things here: Every `if` must be accompanied by both `then` and also `else`. Having an `if` without an `else` is an error, because `if` is an expression, and all expressions must evaluate to a value. If there were ever an `if` without an `else`, that would be an expression that might not evaluate to a value! -### [else if](#else-if) {#else-if} +### [`else if` expressions](#else-if) {#else-if} We can combine `if` and `else` to get `else if`, like so: @@ -322,7 +313,7 @@ Comments that begin with `##` are "doc comments" which will be included in gener Like other comments, doc comments do not affect the running program. -## [Debugging](#debugging) {#debugging} +### [Debugging](#debugging) {#debugging} [Print debugging](https://en.wikipedia.org/wiki/Debugging#Techniques) is the most common debugging technique in the history of programming, and Roc has a `dbg` keyword to facilitate it. Here's an example of how to use `dbg`: @@ -356,7 +347,7 @@ dbg T "the value of count is:" count > **Note:** `dbg` is a debugging tool, and is only available when running your program with `roc program.roc`, `roc dev program.roc` or `roc test program.roc`. When you build a standalone binary with `roc build`, any uses of `dbg` won't be included! -## [Records](#records) {#records} +### [Records](#records) {#records} Currently our `addAndStringify` function takes two arguments. We can instead make it take one argument like so: @@ -458,58 +449,7 @@ The `fromScratch` and `fromOriginal` records are equal, although they're defined Note that `&` can't introduce new fields to a record, or change the types of existing fields. (Trying to do either of these will result in an error at build time!) -## [Default Value Record Fields](#default-value-record-fields) {#default-value-record-fields} - -Roc supports default value record fields using the `?` operator. This can be a useful pattern where you pass a function a record of configuration values, some of which you'd like to provide defaults for. - -In Roc you can write a function like: - -```roc -table = \{ - height, - width, - title ? "oak", - description ? "a wooden table" - } - -> -``` - -This is using _default value field destructuring_ to destructure a record while -providing default values for any fields that might be missing. - -Here's the type of `table`: - -```roc -table : - { - height : Pixels, - width : Pixels, - title ? Str, - description ? Str, - } - -> Table -``` - -This says that `table` takes a record with two fields that are _required_, `height` and -`width`, and two fields that may be _omitted_, `title` and `description`. It also says that -the `height` and `width` fields have the type `Pixels`, a type alias for some -numeric type, and the `title` and `description` fields have the type `Str`. -This means you can choose to omit the `title`, `description`, or both fields, when calling -the function... but if you provide them, they must have the type `Str`. - -This is also the type that would have been inferred for `table` if no annotation -had been written. Roc's compiler can tell from the destructuring syntax -`title ? ""` that `title` is a default value field, and that it has the type `Str`. - -Destructuring is the only way to implement a record with default value fields. For example, -if you write the expression `config.title` and `title` is a default value field, -you'll get a compile error. - -Default values is a concept that exists only in record fields, and it's intended for the use -case of config records like this. The ergonomics of destructuring mean this wouldn't be a good -fit for data modeling, consider using a custom tag union or the `Result` type instead. - -## [Tags & Pattern Matching](#tags) {#tags} +## [Pattern Matching](#pattern-matching) {#pattern-matching} Sometimes we want to represent that something can have one of several values. For example: @@ -639,31 +579,7 @@ A tag can also have a payload with more than one value. Instead of `Custom { r: We refer to whatever comes before a `->` in a `when` expression as a _pattern_—so for example, in the `Custom description -> description` branch, `Custom description` would be a pattern. In programming, using patterns in branching conditionals like `when` is known as [pattern matching](https://en.wikipedia.org/wiki/Pattern_matching). You may hear people say things like "let's pattern match on `Custom` here" as a way to suggest making a `when` branch that begins with something like `Custom description ->`. -### [Pattern Matching on Lists](#pattern-matching-on-lists) {#pattern-matching-on-lists} - -You can also pattern match on lists, like so: - -```roc -when myList is - [] -> 0 # the list is empty - [Foo, ..] -> 1 # it starts with a Foo tag - [_, ..] -> 2 # it contains at least one element, which we ignore - [Foo, Bar, ..] -> 3 # it starts with a Foo tag followed by a Bar tag - [Foo, Bar, Baz] -> 4 # it has exactly 3 elements: Foo, Bar, and Baz - [Foo, a, ..] -> 5 # its first element is Foo, and its second we name `a` - [Ok a, ..] -> 6 # it starts with an Ok containing a payload named `a` - [.., Foo] -> 7 # it ends with a Foo tag - [A, B, .., C, D] -> 8 # it has certain elements at the beginning and end - [head, .. as tail] -> 9 # destructure a list into a first element (head) and the rest (tail) -``` - -This can be both more concise and more efficient (at runtime) than calling [`List.get`](https://www.roc-lang.org/builtins/List#get) multiple times, since each call to `get` requires a separate conditional to handle the different `Result`s they return. - -> **Note:** Each list pattern can only have one `..`, which is known as the "rest pattern" because it's where the _rest_ of the list goes. - -See the [Pattern Matching example](https://www.roc-lang.org/examples/PatternMatching/README.html) which shows different ways to do pattern matching in Roc using tags, strings, and numbers. - -## [Booleans](#booleans) {#booleans} +### [Booleans](#booleans) {#booleans} In many programming languages, `true` and `false` are special language keywords that refer to the two [boolean](https://en.wikipedia.org/wiki/Boolean_data_type) values. In Roc, booleans do not get special keywords; instead, they are exposed as the ordinary values `Bool.true` and `Bool.false`. @@ -671,7 +587,7 @@ This design is partly to keep the number of special keywords in the language sma As an example of why tags are encouraged for data modeling, in many languages it would be common to write a record like `{ name: "Richard", isAdmin: Bool.true }`, but in Roc it would be preferable to write something like `{ name: "Richard", role: Admin }`. At first, the `role` field might only ever be set to `Admin` or `Normal`, but because the data has been modeled using tags instead of booleans, it's much easier to add other alternatives in the future, like `Guest` or `Moderator` - some of which might also want payloads. -## [Lists](#lists) {#lists} +### [Lists](#lists) {#lists} Another thing we can do in Roc is to make a _list_ of values. Here's an example: @@ -926,6 +842,30 @@ A helpful way to remember the argument order for `List.walk` is that that its ar > **Note:** Other languages give this operation different names, such as `fold`, `reduce`, `accumulate`, `aggregate`, `compress`, and `inject`. Some languages also have operations like `forEach` or `for...in` syntax, which walk across every element and perform potentially side-effecting operations on them; `List.walk` can be used to replace these too, if you include a `Task` in the state. We'll talk about tasks, and how to use them with `List.walk`, later on. +### [Pattern Matching on Lists](#pattern-matching-on-lists) {#pattern-matching-on-lists} + +You can also pattern match on lists, like so: + +```roc +when myList is + [] -> 0 # the list is empty + [Foo, ..] -> 1 # it starts with a Foo tag + [_, ..] -> 2 # it contains at least one element, which we ignore + [Foo, Bar, ..] -> 3 # it starts with a Foo tag followed by a Bar tag + [Foo, Bar, Baz] -> 4 # it has exactly 3 elements: Foo, Bar, and Baz + [Foo, a, ..] -> 5 # its first element is Foo, and its second we name `a` + [Ok a, ..] -> 6 # it starts with an Ok containing a payload named `a` + [.., Foo] -> 7 # it ends with a Foo tag + [A, B, .., C, D] -> 8 # it has certain elements at the beginning and end + [head, .. as tail] -> 9 # destructure a list into a first element (head) and the rest (tail) +``` + +This can be both more concise and more efficient (at runtime) than calling [`List.get`](https://www.roc-lang.org/builtins/List#get) multiple times, since each call to `get` requires a separate conditional to handle the different `Result`s they return. + +> **Note:** Each list pattern can only have one `..`, which is known as the "rest pattern" because it's where the _rest_ of the list goes. + +See the [Pattern Matching example](https://www.roc-lang.org/examples/PatternMatching/README.html) which shows different ways to do pattern matching in Roc using tags, strings, and numbers. + ### [The pipe operator](#the-pipe-operator) {#the-pipe-operator} When you have nested function calls, sometimes it can be clearer to write them in a "pipelined" style using the `|>` operator. Here are three examples of writing the same expression; they all compile to exactly the same thing, but two of them use the `|>` operator to change how the calls look. @@ -1184,13 +1124,11 @@ Now we can expose the `Username` opaque type so that other modules can use it in Note that if we define `Username := Str` inside another module (e.g. `Main`) and also use `@Username`, this will compile, however the new `Username` type in main would not be equal to the one defined in the `Username` module. Although both opaque types have the name `Username`, they were defined in different modules and so they are type-incompatible with each other, and even attempting to use `==` to compare them would be a type mismatch. -## [Numeric types](#numeric-types) {#numeric-types} +### [Integers](#integers) {#integers} Roc has different numeric types that each have different tradeoffs. They can all be broken down into two categories: [fractions](https://en.wikipedia.org/wiki/Fraction), and [integers](https://en.wikipedia.org/wiki/Integer). In Roc we call these `Frac` and `Int` for short. -### [Integers](#integers) {#integers} - -Roc's integer types have two important characteristics: their _size_ and their [_signedness_](https://en.wikipedia.org/wiki/Signedness). Together, these two characteristics determine the range of numbers the integer type can represent. +Integer types have two important characteristics: their _size_ and their [_signedness_](https://en.wikipedia.org/wiki/Signedness). Together, these two characteristics determine the range of numbers the integer type can represent. For example, the Roc type `U8` can represent the numbers 0 through 255, whereas the `I16` type can represent the numbers -32768 through 32767. You can actually infer these ranges from their names (`U8` and `I16`) alone! @@ -1217,11 +1155,11 @@ Here are the different fixed-size integer types that Roc supports: | `-32_768`
        `32_767` | `I16` | | `0`
        `65_535` | `U16` | | `-2_147_483_648`
        `2_147_483_647` | `I32` | -| `0`
        (over 4 billion) `4_294_967_295` | `U32` | +| `0`
        `4_294_967_295` (over 4 billion) | `U32` | | `-9_223_372_036_854_775_808`
        `9_223_372_036_854_775_807` | `I64` | -| `0`
        _(over 18 quintillion)_`18_446_744_073_709_551_615` | `U64` | +| `0`
        `18_446_744_073_709_551_615` (over 18 quintillion) | `U64` | | `-170_141_183_460_469_231_731_687_303_715_884_105_728`
        `170_141_183_460_469_231_731_687_303_715_884_105_727` | `I128` | -| `0`
        _(over 340 undecillion)_`340_282_366_920_938_463_463_374_607_431_768_211_455` | `U128` | +| `0`
        `340_282_366_920_938_463_463_374_607_431_768_211_455` (over 340 undecillion) | `U128` | If any operation would result in an integer that is either too big or too small to fit in that range (e.g. calling `Int.maxI32 + 1`, which adds 1 to the highest possible 32-bit integer), then the operation will [overflow](https://en.wikipedia.org/wiki/Integer_overflow). When an overflow occurs, the program will crash. @@ -1281,6 +1219,52 @@ The full list of possible suffixes includes: Integer literals can be written in [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) form by prefixing with `0x` followed by hexadecimal characters (`a` - `f` in addition to `0` - `9`). For example, writing `0xfe` is the same as writing `254`. Similarly, the prefix `0b` specifies binary integers. Writing `0b0000_1000` is the same as writing `8`. +### [Default-Value Record Fields](#default-value-record-fields) {#default-value-record-fields} + +Sometimes you may want to write a function that accepts configuration options. The way to do this in Roc is to accept a record. When you do this, it can sometimes be convenient to provide default values for certain fields in that record, so the caller can omit those fields and let them be populated by the defaults you specified. + +For example: + +```roc +table = \{ height, width, title ? "oak", description ? "a wooden table" } -> +``` + +This is using _default value field destructuring_ to destructure a record while +providing default values for any fields that the caller didn't provide. Here, the `?` operator +essentially means "if the caller did not provide this field, default it to the following value." + +The type of `table` uses `?` instead of `:` to indicate which fields the caller can omit: + +```roc +table : + { + height : U64, + width : U64, + title ? Str, + description ? Str, + } + -> Table +``` + +This says that `table` takes a record with two fields that are _required_—`height` and +`width`—and two fields that may be _omitted_, namely `title` and `description`. It also says that +the `height` and `width` fields have the type `U64` and the `title` and `description` fields have +the type `Str`. This means you can choose to omit the `title`, `description`, or both fields, +when calling the function…but if you provide them, they must have the type `Str`. + +This is also the type that would have been inferred for `table` if it had no annotation. +Roc's compiler can tell from the destructuring syntax `title ? ""` that `title` is a field with a default, +and that it has the type `Str`. + +Destructuring is the only way to implement a record with default value fields! For example, +if you write the expression `config.title` and `title` is a default value field, you'll get a compile error. + +Note that this language feature is really designed for passing configuration records to functions. +It's not intended to be used for data modeling; if you want to represent a value that might not be available, +use a tag union with tag names that describe why the value might not be there. For example, the tag union +`[Specified Str, Unspecified]` conveys different information from `[Found Str, NotFound]` even though both +of them store either a `Str` or nothing. + ## [Crashing](#crashing) {#crashing} Ideally, Roc programs would never crash. However, there are some situations where they may. For example: @@ -1328,7 +1312,7 @@ The reason Roc has a `crash` keyword is for scenarios where it's expected that n Errors that are recoverable should be represented using normal Roc types (like [Result](https://www.roc-lang.org/builtins/Result)) and then handled without crashing. For example, by having the application report that something went wrong, and then continue running from there. -## [Tests and expectations](#tests-and-expectations) {#tests-and-expectations} +## [Testing](#testing) {#testing} You can write automated tests for your Roc code like so: @@ -1532,9 +1516,9 @@ See the [Ingest Files Example](https://www.roc-lang.org/examples/IngestFiles/REA ## [Tasks](#tasks) {#tasks} -Tasks are technically not part of the Roc language, but they're very common in platforms. Let's continue using the [basic-cli](https://github.com/roc-lang/basic-cli) platform we've been using up to this point as an example! +Tasks are not currently part of the Roc builtins—currently, each platform exposes their own `Task` implementation, but the plan is to standardize them into a builtin `Task` like module like the builtin modules we already have for `List`, `Str`, and so on—but they're an important part of building Roc applications, so let's continue using the [basic-cli](https://github.com/roc-lang/basic-cli) platform we've been using up to this point as an example! -In the `basic-cli` platform, we have four operations we can do: +In the `basic-cli` platform, here are four operations we can do: - Write a string to the terminal - Read a string from user input @@ -1552,10 +1536,10 @@ app "cli-tutorial" provides [main] to pf main = - Stdout.line "Hello, World!" + Stdout.line! "Hello, World!" ``` -The `Stdout.line` function takes a `Str` and writes it to [standard output](). It has this type: +The `Stdout.line` function takes a `Str` and writes it to [standard output](). (We'll discuss the `!` part later.) `Stdout.line` has this type: ```roc Stdout.line : Str -> Task {} * @@ -1575,7 +1559,7 @@ Stdin.line : Task [Input Str, End] * Once this task runs, we'll end up with the [tag union](https://www.roc-lang.org/tutorial#tags-with-payloads) `[Input Str, End]`. Then we can check whether we got an `End` or some actual `Input`, and print out a message accordingly. -### [Printing Roc values with `Inspect.toStr`](#inspect) {#inspect} +### [Reading values from tasks](#inspect) {#task-input} Let's change `main` to read a line from `stdin`, and then print what we got: @@ -1586,154 +1570,276 @@ app "cli-tutorial" provides [main] to pf main = - Task.await Stdin.line \input -> - Stdout.line "Your input was: $(Inspect.toStr input)" + Stdout.line! "Type in something and press Enter:" + input = Stdin.line! + Stdout.line! "Your input was: $(input)" ``` -The [`Inspect.toStr`](https://www.roc-lang.org/builtins/Inspect#toStr) function returns a `Str` representation of any Roc value. It's useful for things like debugging and logging (although [`dbg`](https://www.roc-lang.org/tutorial#debugging) is often nicer for debugging), but its output is almost never something that should be shown to end users! In this case we're just using it for our own learning, but in a real program we'd run a `when` on `input` and do something different depending on whether we got an `End` or `Input` tag. +If you run this program, it will print "Type in something and press Enter:" and then pause. +That's because it's waiting for you to type something in and press Enter! Once you do, +it should print back out what you entered. -If you run this program, at first it won't do anything. It's waiting for you to type something in and press Enter! Once you do, it should print back out what you entered—either `Your input was: End` or `Your input was: Input ` depending on whether you pressed Enter or the key combination to close stdin (namely Ctrl+D on UNIX or Ctrl+Z on Windows). Try doing it both ways to watch the output change! +### [Task failure](#task-failure) {#task-failure} -### [Chaining tasks with `Task.await`](#await) {#await} +Sometimes, tasks can fail. For example, a task for reading from a file might fail if the file is not found. +Even reading from stdin and writing to stdout can fail! -The `Task.await` function combines two tasks into one bigger `Task` which first runs one of the given tasks and then the other. In this case, it's combining a `Stdin.line` task with a `Stdout.line` task into one bigger `Task`, and then setting `main` to be that bigger task. +For example, the `Stdin.line` task can fail if stdin is closed before it receives a line. You can try this out +by running the program and pressing Ctrl+Z on Windows, or Ctrl+D on macOS or Linux. (Press that key rather than +typing in text and pressing Enter.) You'll see a default error message, which the `basic-cli` platform provides +in case an error occurs that we didn't handle. -The type of `Task.await` is: +Although this default error handling behavior might be exactly what we want if we're writing a quick script, +high-quality programs handle errors gracefully. Fortunately, we can do this nicely in Roc! + +If we wanted to add the type annotation to `main` that Roc is inferring for it, we would add this annotation: + +```roc +main : Task {} [Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err] +main = +``` + +Let's break down what this type is saying: +* `Task` tells us this is a `Task` type. Its two type parameters are just like the ones we saw in `Result` earlier: the first type tells us what this task will produce if it succeeds, and the other one tells us what it will produce if it fails. +* `{}` tells us that this task always produces an empty record when it succeeds. (That is, it doesn't produce anything useful. Empty records don't have any information in them!) This is because the last task in `main` comes from `Stdout.line`, which doesn't produce anything. (In contrast, the `Stdin` task's first type parameter is a `Str`, because it produces a `Str` if it succeeds.) +* `[Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err]` tells us the different ways this task can fail. The `StdoutErr` and `StdinErr` tags are there becase we used `Stdout.line` and `Stdin.line`. We'll talk about `Exit I32` more in a moment. + +To understand what the `Exit I32 Str` error means, let's try temporarily commenting out our current `main` and replacing +it with this one: + +```roc +main : Task {} [Exit I32 Str] +main = Task.err (Exit 42 "An error happened!") +``` + +Now if we run the application, it will print the line "An error happened!" to stderr and exit with a status code of 42. (You can check the status code of the most recent terminal command that finished in Windows by running `echo %ERRORLEVEL%` (or `$LASTEXITCODE` in PowerShell), or by running `echo $?` in macOS or Linux.) + +Now let's try running it with this version of `main`: + +```roc +main : Task {} [Exit I32 Str] +main = Task.ok {} +``` + +This program won't print anything at all, but it will exit with a status code of `0`, indicating success. + +In summary: +* If the `main` task ends in a `Task.ok {}`, then it means the final task succeeded and the program will exit with status code 0. +* If the `main` task ends in a `Task.err (Exit 42 "…")`, then it means the final task failed, and the only information we got about the failure was that the program should exit with code 42 instead of 0, and that it should print a particular string to stderr to inform the user about what happened. + +### [Handling task failures](#handling-task-failures) {#handling-task-failures} + +If the `main` task ends up failing with any other errors besides `Exit` (such as `StdoutErr` or `StdinErr`), then the `basic-cli` platform's automatic error handling will handle them by printing out words taken from the source code (such as "StdoutErr" and "StinErr"), which could lead to a bad experience for people using this program! + +We can prevent that by gracefully handling the other error types, and then translating them into `Exit` errors so that they affect the program's exit code and don't result in the platform printing anything. A convenient way to make sure we've handled all the other errors is to keep our current type annotation for `main` but restore our old implementation: + +```roc +main : Task {} [Exit I32 Str] +main = + Stdout.line! "Type in something and press Enter:" + input = Stdin.line! + Stdout.line! "Your input was: $(input)" +``` + +Adding this type annotation will give us a type mismatch - which is exactly what we want in this case! The type mismatch is telling us that we're claiming the `main` task will only ever fail with an `Exit` tag, but this implementation can *also* fail with `StdoutErr` and `StdinErr` tags. + +In other words, adding this annotation effectively opted us out of `basic-cli`'s default error handling. Now any potential task failures (now and in the future) will have to be handled somehow; if we forget to handle any, we'll get a type mismatch like this! For that reason, `basic-cli` applications that are intended to be high-quality (so, not things like quick scripts) will generally benefit from applying this type annotation to `main`. + +Here's one way we can handle those errors: + +```roc +main : Task {} [Exit I32 Str] +main = + task = + Stdout.line! "Type in something and press Enter:" + input = Stdin.line! + Stdout.line! "Your input was: $(input)" + + Task.mapErr task \err -> + when err is + StdoutErr _ -> Exit 1 "Error writing to stdout." + StdinErr _ -> Exit 2 "Error writing to stdin." +``` + +The `Task.mapErr` function translates one error into another. Here, we're translating the `StdoutErr` and `StdinErr` errors into `Exit` errors which include a different exit code plus a message that will print to stderr to explain what happened. + +We could also use `Task.onErr` instead, which is like `mapErr` except instead of returning a new error, it returns an entirely new `Task`. This means each branch of our `when` gets a bit more verbose, but it does mean we can run additional tasks before exiting. For example: + +```roc + Task.onErr task \err -> + when err is + StdoutErr _ -> Task.err (Exit 1 "Error writing to stdout.") + StdinErr _ -> + # Here we could now run some other tasks, + # e.g. to log the error to disk. + + Task.err (Exit 2 "Error writing to stdin.") +``` + +Since we don't have any extra tasks to run, `mapErr` is more concise because we don't have to say `Task.err` at the end of each branch. + +### [The _ type](#_) {#_} + +In a larger program, we might want to split `main` into different pieces for logic and handling errors: + +```roc +main : Task {} [Exit I32] +main = + run + |> Task.mapErr handleErr + +run : Task {} _ +run = + Stdout.line! "Type in something and press Enter:" + input = Stdin.line! + Stdout.line! "Your input was: $(input)" + +handleErr : _ -> [Exit I32 Str] +handleErr = \err -> + when err is + StdoutErr _ -> Exit 1 "Error writing to stdout." + StdinErr _ -> Exit 2 "Error writing to stdin." +``` + +Here, we used `_` to create *partial* type annotations. Wherever a `_` appears in a type annotation, it essentially means "I'm choosing not to annotate this part right here" and it lets Roc use type inference to fill in the blank behind the scenes. Roc will still compile them and check their types as normal (just like it did before we had any annotations at all); the `_` is about which parts of the type we're choosing to annotate and which parts we're leaving to inference. + +This is a useful technique to use when we don't want to write out a bunch of error types that we're going to handle anyway, and would otherwise have to keep updating every time a new error appeared. If we want to know the full list of errors, we can see it in a number of ways: + +* Look at the branches of our `when err is`, since they cover all the errors (and we'd get a compile error if we left any out) +* If we're using an editor that supports it, hovering over the `_` might display the inferred type that goes there. +* We can put an obviously wrong type in there (e.g. replace the `{}` with `Str`, which is totally wrong) and look at the compiler error to see what it inferred as the correct type. + +We can also use `_` in type aliases, to express that two types are the same without annotating either of them. For example: + +```roc +RunErr : _ +``` + +```roc +run : Task {} RunErr +``` + +```roc +handleErr : RunErr -> [Exit I32 Str] +``` + +Of course, we could also choose not to use `_` at all and populate the `RunErr` type alias with the full list of errors that could happen in our `run` task. All of these are totally reasonable stylistic choices, depending on how you prefer the code to look. The all compile to exactly the same thing, and have the same runtime characteristics. + +### [The ! suffix](#the-!-suffix) {#the-!-suffix} + +The `!` suffix operator is a bit of syntax sugar for the `Task.await` function, which has this type: ```roc Task.await : Task a err, (a -> Task b err) -> Task b err ``` -The second argument to `Task.await` is a "callback function" which runs after the first task completes. This callback function receives the output of that first task, and then returns the second task. This means the second task can make use of output from the first task, like we did in our `\input -> ...` callback function here: +Basically, this function creates a task which runs one task, and then runs a second task which can use the output of the first task. (If the first task fails, the second task never gets run.) + +More specifically, `Task.await` returns a `Task` which: +1. Runs the given `Task a err` +2. If it fails with some error, returns a `Task` which fails with that same error. (So if the given `Task a err` fails, the `a -> Task b err` function never gets called.) +3. If it succeeds (meaning it produces a success value which has the type `a`), pass the value it succeeded with to the `a -> Task b err` function. Whatever `Task b err` that function returns will be the `Task b err` the entire `Task.await` call returns. + +The `!` suffix is syntax sugar for connecting tasks using `Task.await`. Let's revisit our earlier example here: ```roc -\input -> - Stdout.line "Your input was: $(Inspect.toStr input)" +Stdout.line! "Type in something and press Enter:" +input = Stdin.line! +Stdout.line! "Your input was: $(input)" ``` -Notice that, just like before, we're still building `main` from a single `Task`. This is how we'll always do it! We'll keep building up bigger and bigger `Task`s out of smaller tasks, and then setting `main` to be that one big `Task`. +This desugars to the following: -For example, we can print a prompt before we pause to read from `stdin`, so it no longer looks like the program isn't doing anything when we start it up: +```roc +Task.await (Stdout.line "Type in something and press Enter:") \_ -> + Task.await Stdin.line \input -> + Stdout.line "Your input was: $(input)" +``` + +Each of the `!` operators desugars to a `Task.await` call, except for the last one (which desugars to nothing because there's no task after it to connect to; if we wanted to, we could have left out that `!` without changing what the programa does, but it looks more consistent to have both `Stdout.line!` calls end in a `!`). + +If you like, you can always call `Task.await` directly instead of using `!` (since `!` is nothing more than syntax sugar for `Task.await`), but it's a stylsitic convention in the Roc ecosystem to use `!` instead. + +### [Tagging errors](#tagging-errors) {#tagging-errors} + +Although it's rare, it is possible that either of the `Stdout.line!` operations in our example could fail: ```roc main = - Task.await (Stdout.line "Type something press Enter:") \_ -> - Task.await Stdin.line \input -> - Stdout.line "Your input was: $(Inspect.toStr input)" + Stdout.line! "Type something and press Enter." + input = Stdin.line! + Stdout.line! "You entered: $(input)" ``` -This works, but we can make it a little nicer to read. Let's change it to the following: +If that happens, we don't necessarily know which one was the cause of the failure. Our `handleErr` function runs when a `StdoutErr` happens, but once it receives a `StdoutErr` it has no way of knowing whether the first or second `Stdout.line` was the cause. -```roc -app "cli-tutorial" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.0/oKWkaruh2zXxin_xfsYsCJobH1tO8_JvNkFzDwwzNUQ.tar.br" } - imports [pf.Stdout, pf.Stdin, pf.Task.{ await }] - provides [main] to pf +(In this particular example, it's not very likely that this would come up at all, and even if it did, we might not care which one caused the problem. But you can imagine having multiple HTTP requests, or file writes, and wanting to know which of them was the one that failed.) -main = - await (Stdout.line "Type something press Enter:") \_ -> - await Stdin.line \input -> - Stdout.line "Your input was: $(Inspect.toStr input)" -``` - -Here we've changed how we're importing the `Task` module. Before it was `pf.Task` and now it's `pf.Task.{ await }`. The difference is that we're importing `await` in an _unqualified_ way, meaning that whenever we write `await` in this module, it will refer to `Task.await`. Now we no longer need to write `Task.` every time we want to use `await`. - -It's most common in Roc to call functions from other modules in a _qualified_ way (`Task.await`) rather than unqualified (`await`) like this, but it can be nice for a function with an uncommon name (like "await") which often gets called repeatedly across a small number of lines of code. - -Speaking of calling `await` repeatedly, if we keep calling it more and more on this code, we'll end up doing a lot of indenting. If we'd rather not indent so much, we can rewrite `task` into this style which looks different but does the same thing: +A quick way to do this is to "tag the error" using `Task.mapErr` like so: ```roc main = - _ <- await (Stdout.line "Type something press Enter:") - input <- await Stdin.line + Stdout.line "Type something and press Enter." + |> Task.mapErr! PrintPrompt - Stdout.line "Your input was: $(Inspect.toStr input)" + input = Stdin.line! + + Stdout.line "You entered: $(input)" + |> Task.mapErr! PrintInput ``` -## [Backpassing](#backpassing) {#backpassing} +The `mapErr` function has this type: -This `<-` syntax is called _backpassing_. The `<-` is a way to define an anonymous function, just like `\ ... ->` is. +``` +Task.mapErr : Task ok a, (a -> b) -> Task ok b +``` -Here, we're using backpassing to define two anonymous functions. Here's one of them: +Here we're passing in "tagging functions"—namely, `PrintPrompt` and `PrintInput`. (See [Using tags as functions](#using-tags-as-functions) for how this works.) + +Note that the `!` moves when we do this. It's no longer after `Stdout.line`, but rather after `Task.mapErr` instead: ```roc -input <- - -Stdout.line "Your input was: $(Inspect.toStr input)" + Stdout.line "Type something and press Enter." + |> Task.mapErr! PrintPrompt ``` -It may not look like it, but this code is defining an anonymous function! You might remember it as the anonymous function we previously defined like this: +This code is doing three things: +1. Call `Stdout.line "..."`, which returns a `Task` value +2. Transform that `Task` value into another `Task` value using `|> Task.mapErr` +3. Wait until that final `Task` value (returned by `mapErr`) successfully completes, using `!` + +It's easier to see why the `!` needs to move when considering a `Task` that produces a useful value, like `Stdin.line`. Compare these two: ```roc -\input -> - Stdout.line "Your input was: $(Inspect.toStr input)" + input = + Stdin.line + |> Task.mapErr! ReadStdin ``` -These two anonymous functions are the same, just defined using different syntax. - -The reason the `<-` syntax is called _backpassing_ is because it both defines a function and passes that function _back_ as an argument to whatever comes after the `<-` (which in this case is `await Stdin.line`). - -Let's look at these two complete expressions side by side. They are both saying exactly the same thing, with different syntax! - -Here's the original: +This versions starts with the `Stdin.line` task, then passes it to `Task.mapErr` to tag its error with `ReadStdin`, and then finally uses `!` to await that final transformed task that `Task.mapErr` returned. ```roc -await Stdin.line \input -> - Stdout.line "Your input was: $(Inspect.toStr input)" + input = + Stdin.line! + |> Task.mapErr ReadStdin ``` -And here's the equivalent expression with backpassing syntax: +This version starts with the `Stdin.line` task, awaits it with `!` to get its `Str` value if it succeded, and then tries to call `Task.mapErr` on that `Str` value. This will be a type mismatch! -```roc -input <- await Stdin.line - -Stdout.line "Your input was: $(Inspect.toStr input)" -``` - -Here's the other function we're defining with backpassing: - -```roc -_ <- -input <- await Stdin.line - -Stdout.line "Your input was: $(Inspect.toStr input)" -``` - -We could also have written that function this way if we preferred: - -```roc -_ <- - -await Stdin.line \input -> - Stdout.line "Your input was: $(Inspect.toStr input)" -``` - -This is using a mix of a backpassing function `_ <-` and a normal function `\input ->`, which is totally allowed! Since backpassing is nothing more than syntax sugar for defining a function and passing back as an argument to another function, there's no reason we can't mix and match if we like. - -That said, the typical style in which this `task` would be written in Roc is using backpassing for all the `await` calls, like we had above: - -```roc -main = - _ <- await (Stdout.line "Type something press Enter:") - input <- await Stdin.line - - Stdout.line "Your input was: $(Inspect.toStr input)" -``` - -This way, it reads like a series of instructions: - -1. First, run the `Stdout.line` task and await its completion. Ignore its output (hence the underscore in `_ <-`) -2. Next, run the `Stdin.line` task and await its completion. Name its output `input`. -3. Finally, run the `Stdout.line` task again, using the `input` value we got from the `Stdin.line` effect. - -Some important things to note about backpassing and `await`: - -- `await` is not a language keyword in Roc! It's referring to the `Task.await` function, which we imported unqualified by writing `Task.{ await }` in our module imports. (That said, it is playing a similar role here to the `await` keyword in languages that have `async`/`await` keywords, even though in this case it's a function instead of a special keyword.) -- Backpassing syntax does not need to be used with `await` in particular. It can be used with any function. -- Roc's compiler treats functions defined with backpassing exactly the same way as functions defined the other way. The only difference between `\input ->` and `input <-` is how they look, so feel free to use whichever looks nicer to you! +In general, an easy rule to remember is "do the `!` last" - if you want to modify a `Task` before running it, use the `!` only after you've made all the modifications and ended up with the final `Task` you'd like to run. See the [Task & Error Handling example](https://www.roc-lang.org/examples/Tasks/README.html) for a more detailed explanation of how to use tasks to help with error handling in a larger program. +### [Displaying Roc values with `Inspect.toStr`](#inspect) {#inspect} + +The [`Inspect.toStr`](https://www.roc-lang.org/builtins/Inspect#toStr) function returns a `Str` representation of any Roc value. It's useful for things like debugging and logging (although [`dbg`](https://www.roc-lang.org/tutorial#debugging) is often nicer for debugging in particular), but its output is almost never something that should be shown to end users! In this case we're just using it for our own learning, but it would be better to run a `when` on `e` and display a more helpful message. + +```roc +when err is + StdoutErr e -> Exit 1 "Error writing to stdout: $(Inspect.toStr e)" + StdinErr e -> Exit 2 "Error writing to stdin: $(Inspect.toStr e)" +``` + ## [Examples](#examples) {#examples} Well done on making it this far! @@ -1742,7 +1848,7 @@ We've covered all of the basic syntax and features of Roc in this Tutorial. You You can continue reading through more advanced topics below, or perhaps checkout some of the [Examples](/examples) for more a detailed exploration of ways to do various things. -## [Appendix: Advanced Concepts](#appendix-advanced-concepts) {#appendix-advanced-concepts} +## [Advanced Concepts](#advanced-concepts) {#advanced-concepts} Here are some concepts you likely won't need as a beginner, but may want to know about eventually. This is listed as an appendix rather than the main tutorial, to emphasize that it's totally fine to stop reading here and go build things! @@ -2081,7 +2187,7 @@ These are all the reserved keywords in Roc. You can't choose any of these as nam `if`, `then`, `else`, `when`, `as`, `is`, `dbg`, `expect`, `expect-fx`, `crash`, `interface`, `app`, `package`, `platform`, `hosted`, `exposes`, `imports`, `with`, `generates`, `packages`, `requires`, `provides`, `to` -### [Operator Desugaring Table](#operator-desugaring-table) {#operator-desugaring-table} +## [Operator Desugaring Table](#operator-desugaring-table) {#operator-desugaring-table} Here are various Roc expressions involving operators, and what they desugar to. diff --git a/www/public/site.css b/www/public/site.css index f03c662803..9178b6acdd 100644 --- a/www/public/site.css +++ b/www/public/site.css @@ -1137,6 +1137,21 @@ code .dim { color: #7c38f5; } +.interactive-desc code, .interactive-desc pre { + background: none; + color: inherit; +} + +.interactive-desc pre { + border: 1px solid; + padding: 0 8px; +} + +.interactive-desc code { + font-weight: bold; + padding: 0; +} + .interactive-radio { display: none; } @@ -1222,10 +1237,10 @@ code .dim { } #tutorial-main h3 { - font-size: 3rem; + font-family: inherit; + font-size: 1.65rem; line-height: 3rem; text-shadow: 1px 1px 1px #010101; - margin-bottom: 0.5rem; } #tutorial-main h4 { From c676a21a13dcc65d048c8778326776583e318384 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 19:03:17 -0400 Subject: [PATCH 32/72] Don't use "synchronous" terminology --- www/InteractiveExample.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/InteractiveExample.roc b/www/InteractiveExample.roc index 3536996383..1be9e3e63c 100644 --- a/www/InteractiveExample.roc +++ b/www/InteractiveExample.roc @@ -36,7 +36,7 @@ view = Newline, Desc [Ident "user", Kw "=", Ident "Http.get!", Ident "url", Ident "Json.format"] "

        This fetches the contents of the URL and decodes them as JSON.

        If the shape of the JSON isn't compatible with the type of user (based on type inference), this will give a decoding error immediately.

        As with all the other function calls involving the ! operator, if there's an error, nothing else in storeEmail will be run, and handleErr will run.

        ", Newline, - Desc [Ident "dest", Kw "=", Ident "Path.fromStr", StrInterpolation "\"" "user.name" ".txt\""] "

        The \$(user.name) in this string literal will be replaced with the value stored in the user record's name field. This is string interpolation.

        Note that this function call doesn't involve the ! operator. That's because Path.fromStr is a synchronous operation, so there's no need to use ! to wait for it to finish.

        ", + Desc [Ident "dest", Kw "=", Ident "Path.fromStr", StrInterpolation "\"" "user.name" ".txt\""] "

        The \$(user.name) in this string literal will be replaced with the value stored in the user record's name field. This is string interpolation.

        Note that this function call doesn't involve the ! operator. That's because Path.fromStr doesn't involve any Tasks, so there's no need to use ! to wait for it to finish.

        ", Newline, Desc [Ident "File.writeUtf8!", Ident "dest", Ident "user.email"] "

        This writes user.email to the file, encoded as UTF-8.

        Since File.writeUtf8 doesn't produce any information on success, we don't bother using = like we did on the other lines.

        ", Newline, From e4bc7147c98b15666efe8d63e9aff5ae7f9e3af4 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 19:48:56 -0400 Subject: [PATCH 33/72] Add test to reproduce Ok and Err alias failure --- crates/repl_test/src/tests.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/repl_test/src/tests.rs b/crates/repl_test/src/tests.rs index 831c50369b..7099e22f19 100644 --- a/crates/repl_test/src/tests.rs +++ b/crates/repl_test/src/tests.rs @@ -1200,6 +1200,22 @@ fn tag_with_type_behind_alias() { ); } +#[test] +fn aliases_named_err_and_ok() { + expect_success( + indoc!( + r#" + Err : [Blah] + Ok : [Stuff] + + v : (Err, Ok) + v = (Blah, Stuff) + v"# + ), + r#"(Blah, Stuff) : ( [Blah], [Stuff] )*"#, + ); +} + #[cfg(not(feature = "wasm"))] #[test] fn issue_2588_record_with_function_and_nonfunction() { From f557a29090967057e53be339d4204539088eb578 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 19:47:11 -0400 Subject: [PATCH 34/72] Don't add Ok and Err as symbols to scope --- crates/compiler/can/src/scope.rs | 12 +++++------- crates/compiler/module/src/symbol.rs | 28 ++-------------------------- 2 files changed, 7 insertions(+), 33 deletions(-) diff --git a/crates/compiler/can/src/scope.rs b/crates/compiler/can/src/scope.rs index b427f869a5..15df01fe43 100644 --- a/crates/compiler/can/src/scope.rs +++ b/crates/compiler/can/src/scope.rs @@ -53,13 +53,11 @@ impl Scope { initial_ident_ids: IdentIds, starting_abilities_store: PendingAbilitiesStore, ) -> Scope { - let default_imports = - // Add all `Apply` types. - (Symbol::apply_types_in_scope().into_iter()) - // Add all tag names we might want to suggest as hints in error messages. - .chain(Symbol::symbols_in_scope_for_hints()); - - let default_imports = default_imports.map(|(a, (b, c))| (a, b, c)).collect(); + // Add all `Apply` types. + let default_imports = Symbol::apply_types_in_scope() + .into_iter() + .map(|(a, (b, c))| (a, b, c)) + .collect(); Scope { home, diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index a57047fa46..0220710cd6 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -876,7 +876,6 @@ macro_rules! define_builtins { module_id.register_debug_idents(&ident_ids); } - exposed_idents_by_module.insert( module_id, ident_ids @@ -1016,27 +1015,6 @@ macro_rules! define_builtins { m => roc_error_macros::internal_error!("{:?} is not a builtin module!", m), } } - - /// Symbols that should be added to the default scope, for hints as suggestions of - /// names you might want to use. - /// - /// TODO: this is a hack to get tag names to show up in error messages as suggestions, - /// really we should be extracting tag names from candidate type aliases in scope. - pub fn symbols_in_scope_for_hints() -> VecMap { - let mut scope = VecMap::default(); - - $( - $( - $( - if $in_scope_for_hints { - scope.insert($ident_name.into(), (Symbol::new(ModuleId::$module_const, IdentId($ident_id)), Region::zero())); - } - )? - )* - )+ - - scope - } } }; } @@ -1434,15 +1412,13 @@ define_builtins! { } 7 RESULT: "Result" => { 0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias - 1 RESULT_OK: "Ok" in_scope_for_hints=true // Result.Result a e = [Ok a, Err e] - 2 RESULT_ERR: "Err" in_scope_for_hints=true // Result.Result a e = [Ok a, Err e] + 1 RESULT_IS_ERR: "isErr" + 2 RESULT_ON_ERR: "onErr" 3 RESULT_MAP: "map" 4 RESULT_MAP_ERR: "mapErr" 5 RESULT_WITH_DEFAULT: "withDefault" 6 RESULT_TRY: "try" 7 RESULT_IS_OK: "isOk" - 8 RESULT_IS_ERR: "isErr" - 9 RESULT_ON_ERR: "onErr" } 8 DICT: "Dict" => { 0 DICT_DICT: "Dict" exposed_type=true // the Dict.Dict type alias From 6571c18a3556319156ce051df23254049d2d0006 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 23:10:45 -0400 Subject: [PATCH 35/72] Update tests --- crates/compiler/can/src/scope.rs | 16 ++-------------- crates/compiler/load/tests/test_reporting.rs | 4 ++-- crates/compiler/load_internal/tests/test_load.rs | 2 +- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/crates/compiler/can/src/scope.rs b/crates/compiler/can/src/scope.rs index 15df01fe43..b5fe6f2eec 100644 --- a/crates/compiler/can/src/scope.rs +++ b/crates/compiler/can/src/scope.rs @@ -726,13 +726,7 @@ mod test { assert_eq!( &idents, - &[ - Ident::from("Str"), - Ident::from("List"), - Ident::from("Box"), - Ident::from("Ok"), - Ident::from("Err"), - ] + &[Ident::from("Str"), Ident::from("List"), Ident::from("Box"),] ); } @@ -749,13 +743,7 @@ mod test { assert_eq!( &idents, - &[ - Ident::from("Str"), - Ident::from("List"), - Ident::from("Box"), - Ident::from("Ok"), - Ident::from("Err"), - ] + &[Ident::from("Str"), Ident::from("List"), Ident::from("Box"),] ); let builtin_count = idents.len(); diff --git a/crates/compiler/load/tests/test_reporting.rs b/crates/compiler/load/tests/test_reporting.rs index 4772a86bcc..9bca7a8b9c 100644 --- a/crates/compiler/load/tests/test_reporting.rs +++ b/crates/compiler/load/tests/test_reporting.rs @@ -812,10 +812,10 @@ mod test_reporting { Did you mean one of these? - Ok List - Err Box + Str + isDisabled " ), ); diff --git a/crates/compiler/load_internal/tests/test_load.rs b/crates/compiler/load_internal/tests/test_load.rs index ba0e57c084..ab03b7bd43 100644 --- a/crates/compiler/load_internal/tests/test_load.rs +++ b/crates/compiler/load_internal/tests/test_load.rs @@ -989,8 +989,8 @@ fn issue_2863_module_type_does_not_exist() { Did you mean one of these? Decoding - Dict Result + Dict DecodeError " ) From ce4501c32994d6e0d1a831c52ddda0ca836a5dc3 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 22:07:44 -0400 Subject: [PATCH 36/72] Update mono tests --- ...ose_correct_recursion_var_under_record.txt | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt b/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt index f2c684b534..9f4f8f7f51 100644 --- a/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt +++ b/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt @@ -50,17 +50,17 @@ procedure Num.22 (#Attr.2, #Attr.3): let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; ret Num.275; -procedure Result.5 (Result.12, Result.13): - let Result.39 : U8 = 1i64; - let Result.40 : U8 = GetTagId Result.12; - let Result.41 : Int1 = lowlevel Eq Result.39 Result.40; - if Result.41 then - dec Result.13; - let Result.14 : Str = UnionAtIndex (Id 1) (Index 0) Result.12; - ret Result.14; +procedure Result.5 (Result.10, Result.11): + let Result.37 : U8 = 1i64; + let Result.38 : U8 = GetTagId Result.10; + let Result.39 : Int1 = lowlevel Eq Result.37 Result.38; + if Result.39 then + dec Result.11; + let Result.12 : Str = UnionAtIndex (Id 1) (Index 0) Result.10; + ret Result.12; else - dec Result.12; - ret Result.13; + dec Result.10; + ret Result.11; procedure Test.10 (Test.11): let Test.12 : Str = CallByName Test.2 Test.11; From e895c71dbdfac595080bf9d631e5dfa9f4fd52e3 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 25 Apr 2024 23:09:28 -0400 Subject: [PATCH 37/72] Ignore unused warnings if the module name is Task --- crates/compiler/load_internal/src/file.rs | 24 ++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 4977409590..30ad6e01f4 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -2161,11 +2161,25 @@ fn report_unused_imported_modules( Occupied(entry) => entry.into_mut(), }; - for (unused, region) in unused_imported_modules.drain() { - if !unused.is_builtin() { - existing.push(roc_problem::can::Problem::UnusedModuleImport( - unused, region, - )); + // TODO this outer conditional can be replaced by just the for loop + // once we have Task as builtin. (Also the for loop doesn't need the "Task" check.) + if !unused_imported_modules.is_empty() { + let module_ids = Arc::clone(&state.arc_modules); + let module_ids = module_ids.lock(); + + for (unused, region) in unused_imported_modules.drain() { + if !unused.is_builtin() { + let is_task_module = match module_ids.get_name(unused) { + Some(name) => name.as_inner().as_str() == "Task", + None => false, + }; + + if !is_task_module { + existing.push(roc_problem::can::Problem::UnusedModuleImport( + unused, region, + )); + } + } } } From 00950d2a0e6cd6dabbad81294cdc02f8c61fd010 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 26 Apr 2024 06:59:01 -0400 Subject: [PATCH 38/72] Update insta snapshots --- crates/compiler/load/tests/test_reporting.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/compiler/load/tests/test_reporting.rs b/crates/compiler/load/tests/test_reporting.rs index 9bca7a8b9c..2acc007fb3 100644 --- a/crates/compiler/load/tests/test_reporting.rs +++ b/crates/compiler/load/tests/test_reporting.rs @@ -647,7 +647,7 @@ mod test_reporting { if true then 1 else 2 " ), - @r" + @r###" ── UNRECOGNIZED NAME in /code/proj/Main.roc ──────────────────────────────────── Nothing is named `true` in this scope. @@ -657,11 +657,11 @@ mod test_reporting { Did you mean one of these? + Str Frac Num - Str - Err - " + U8 + "### ); test_report!( @@ -2212,10 +2212,10 @@ mod test_reporting { Did you mean one of these? - Ok U8 Box Eq + f " ); @@ -5805,9 +5805,9 @@ All branches in an `if` must have the same type! Did you mean one of these? Str - Err U8 F64 + Box "### ); From 15d5c56622dc959f64f237b06219bc4bc1377fca Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:28:55 +0200 Subject: [PATCH 39/72] new zig path --- .github/workflows/ci_manager.yml | 2 +- .github/workflows/nightly_macos_apple_silicon.yml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_manager.yml b/.github/workflows/ci_manager.yml index a33b81920d..a8438b639d 100644 --- a/.github/workflows/ci_manager.yml +++ b/.github/workflows/ci_manager.yml @@ -1,5 +1,5 @@ on: - pull_request: + #pull_request: name: CI manager diff --git a/.github/workflows/nightly_macos_apple_silicon.yml b/.github/workflows/nightly_macos_apple_silicon.yml index 66e4449cf4..0b047d1c55 100644 --- a/.github/workflows/nightly_macos_apple_silicon.yml +++ b/.github/workflows/nightly_macos_apple_silicon.yml @@ -1,5 +1,5 @@ on: - #pull_request: + pull_request: workflow_dispatch: schedule: - cron: '0 9 * * *' @@ -18,6 +18,10 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Update PATH to use zig 11 + run: | + echo "PATH=/Users/m1ci/Downloads/zig-macos-aarch64-0.11.0:$PATH" >> $GITHUB_ENV + - run: zig version - name: llvm version From 8a92517387b7b418fc92ea28379a717bdeda9215 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:31:35 +0200 Subject: [PATCH 40/72] ditch llvm version check Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/nightly_macos_apple_silicon.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/nightly_macos_apple_silicon.yml b/.github/workflows/nightly_macos_apple_silicon.yml index 0b047d1c55..f987f5f09c 100644 --- a/.github/workflows/nightly_macos_apple_silicon.yml +++ b/.github/workflows/nightly_macos_apple_silicon.yml @@ -24,9 +24,6 @@ jobs: - run: zig version - - name: llvm version - run: llc --version | grep LLVM - - name: run tests run: cargo test --locked --release From 063b2c6f91b65d4988334777ebb33bfc38caa58b Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:44:50 +0200 Subject: [PATCH 41/72] zig debugging Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/nightly_macos_apple_silicon.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/nightly_macos_apple_silicon.yml b/.github/workflows/nightly_macos_apple_silicon.yml index f987f5f09c..01c4bc0ca2 100644 --- a/.github/workflows/nightly_macos_apple_silicon.yml +++ b/.github/workflows/nightly_macos_apple_silicon.yml @@ -24,6 +24,10 @@ jobs: - run: zig version + - run: which zig + + - run: ls /Users/m1ci/Downloads/zig-macos-aarch64-0.11.0/ + - name: run tests run: cargo test --locked --release From df1972be0206697bdcfde2d52082ca3afa8033b3 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 26 Apr 2024 16:11:46 -0400 Subject: [PATCH 42/72] Don't indent |> on homepage example --- www/InteractiveExample.roc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/InteractiveExample.roc b/www/InteractiveExample.roc index 1be9e3e63c..53cbec9363 100644 --- a/www/InteractiveExample.roc +++ b/www/InteractiveExample.roc @@ -24,12 +24,12 @@ view = Desc [Ident "main", Kw "="] "

        This defines main, which is where our program will begin.

        In Roc, all definitions are constant, so writing main = again in the same scope would give an error.

        ", Indent, Desc [Ident "Path.fromStr", Str "\"url.txt\""] "

        This converts the string \"url.txt\" into a Path by passing it to Path.fromStr.

        Function arguments are separated with whitespace. Parentheses are only needed in nested function calls.

        ", - Indent, + Newline, Desc [Kw "|>", Ident "storeEmail"] "

        The pipe operator (|>) is syntax sugar for passing the previous value to the next function in the \"pipeline.\"

        This line takes the value that Path.fromStr \"url.txt\" returns and passes it to storeEmail.

        The next |> continues the pipeline.

        ", Newline, Desc [Kw "|>", Ident "Task.onErr", Ident "handleErr"] "

        If the task returned by the previous step in the pipeline fails, pass its error to handleErr.

        The pipeline essentially does this:

        a = Path.fromStr \"url.txt\"\nb = storeEmail a\n\nTask.onErr b handleErr

        It creates a Path from a string, passes it to storeEmail, and specifies how to handle errors if storing the email fails.

        ", Outdent, - Outdent, + Newline, Desc [Ident "storeEmail", Kw "=", Lambda ["path"]] "

        This defines a function named storeEmail. It takes one argument, named path.

        In Roc, functions are ordinary values, so we assign names to them using = like with any other value.

        The \\arg1, arg2 -> syntax begins a function, and the part after -> is the function's body.

        ", Indent, Desc [Ident "url", Kw "=", Ident "File.readUtf8!", Ident "path"] "

        This passes path to the File.readUtf8 function, which reads the contents of the file (as a UTF-8 string) into url.

        The ! operator is similar to await in other languages. It means “wait until the asynchronous File.readUtf8 operation successfully completes.”

        If the file read fails (maybe because path refers to a missing file), the rest of this function will be skipped, and the handleErr function will take over.

        ", From 17d761252fbc63d9fbda46999b25607beae52f94 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 26 Apr 2024 16:31:20 -0400 Subject: [PATCH 43/72] Improve reporting for doc links problems --- Cargo.lock | 2 + crates/compiler/load_internal/src/file.rs | 1 + crates/compiler/load_internal/src/module.rs | 8 + crates/compiler/module/src/ident.rs | 18 ++- crates/docs/Cargo.toml | 3 + crates/docs/src/lib.rs | 157 +++++++++++++++++--- 6 files changed, 164 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8728080e1..ecc5b2ee0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2502,12 +2502,14 @@ dependencies = [ "roc_module", "roc_packaging", "roc_parse", + "roc_problem", "roc_region", "roc_reporting", "roc_solve", "roc_target", "roc_types", "snafu", + "ven_pretty", ] [[package]] diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 4977409590..76251358bf 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -3381,6 +3381,7 @@ fn finish( LoadedModule { module_id: state.root_id, + filename: state.root_path, interns, solved, can_problems: state.module_cache.can_problems, diff --git a/crates/compiler/load_internal/src/module.rs b/crates/compiler/load_internal/src/module.rs index a18e76f163..28ad33cf7b 100644 --- a/crates/compiler/load_internal/src/module.rs +++ b/crates/compiler/load_internal/src/module.rs @@ -30,6 +30,7 @@ use std::time::{Duration, Instant}; #[derive(Debug)] pub struct LoadedModule { pub module_id: ModuleId, + pub filename: PathBuf, pub interns: Interns, pub solved: Solved, pub can_problems: MutMap>, @@ -54,6 +55,13 @@ pub struct LoadedModule { } impl LoadedModule { + /// Infer the filename for the given ModuleId, based on this root module's filename. + pub fn filename(&self, module_id: ModuleId) -> PathBuf { + let module_name = self.interns.module_name(module_id); + + module_name.filename(&self.filename) + } + pub fn total_problems(&self) -> usize { let mut total = 0; diff --git a/crates/compiler/module/src/ident.rs b/crates/compiler/module/src/ident.rs index 17f9d79582..c82a737204 100644 --- a/crates/compiler/module/src/ident.rs +++ b/crates/compiler/module/src/ident.rs @@ -1,5 +1,8 @@ pub use roc_ident::IdentStr; -use std::fmt::{self, Debug}; +use std::{ + fmt::{self, Debug}, + path::{Path, PathBuf}, +}; use crate::symbol::PQModuleName; @@ -45,6 +48,19 @@ impl<'a> QualifiedModuleName<'a> { #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct ModuleName(IdentStr); +impl ModuleName { + /// Given the root module's path, infer this module's path based on its name. + pub fn filename(&self, root_filename: impl AsRef) -> PathBuf { + let mut answer = root_filename.as_ref().with_file_name(""); + + for part in self.split(".") { + answer = answer.join(part); + } + + answer.with_extension("roc") + } +} + impl std::ops::Deref for ModuleName { type Target = str; diff --git a/crates/docs/Cargo.toml b/crates/docs/Cargo.toml index b9c1e7f0c8..e5337c5373 100644 --- a/crates/docs/Cargo.toml +++ b/crates/docs/Cargo.toml @@ -21,6 +21,9 @@ roc_reporting = { path = "../reporting" } roc_solve = { path = "../compiler/solve" } roc_target = { path = "../compiler/roc_target" } roc_types = { path = "../compiler/types" } +roc_problem = { path = "../compiler/problem" } + +ven_pretty = { path = "../vendor/pretty" } bumpalo.workspace = true pulldown-cmark.workspace = true diff --git a/crates/docs/src/lib.rs b/crates/docs/src/lib.rs index 2d9b5dd175..75e698e6f7 100644 --- a/crates/docs/src/lib.rs +++ b/crates/docs/src/lib.rs @@ -13,6 +13,7 @@ use roc_packaging::cache::{self, RocCacheDir}; use roc_parse::ident::{parse_ident, Accessor, Ident}; use roc_parse::keyword; use roc_parse::state::State; +use roc_problem::Severity; use roc_region::all::Region; use std::fs; use std::path::{Path, PathBuf}; @@ -146,7 +147,7 @@ pub fn generate_docs_html(root_file: PathBuf, build_dir: &Path) { } // Write each package module's index.html file - for (_, module_docs) in exposed_module_docs.iter() { + for (module_id, module_docs) in exposed_module_docs.iter() { let module_name = module_docs.name.as_str(); let module_dir = build_dir.join(module_name.replace('.', "/").as_str()); @@ -164,8 +165,13 @@ pub fn generate_docs_html(root_file: PathBuf, build_dir: &Path) { ) .replace( "", - render_module_documentation(module_docs, &loaded_module, &all_exposed_symbols) - .as_str(), + render_module_documentation( + *module_id, + module_docs, + &loaded_module, + &all_exposed_symbols, + ) + .as_str(), ); fs::write(module_dir.join("index.html"), rendered_module) @@ -235,6 +241,7 @@ fn render_package_index(docs_by_module: &[(ModuleId, ModuleDocumentation)]) -> S } fn render_module_documentation( + module_id: ModuleId, module: &ModuleDocumentation, root_module: &LoadedModule, all_exposed_symbols: &VecSet, @@ -292,6 +299,7 @@ fn render_module_documentation( if let Some(docs) = &doc_def.docs { markdown_to_html( &mut buf, + &root_module.filename(module_id), all_exposed_symbols, &module.scope, docs, @@ -305,6 +313,7 @@ fn render_module_documentation( DocEntry::ModuleDoc(docs) => { markdown_to_html( &mut buf, + &root_module.filename(module_id), all_exposed_symbols, &module.scope, docs, @@ -314,6 +323,7 @@ fn render_module_documentation( DocEntry::DetachedDoc(docs) => { markdown_to_html( &mut buf, + &root_module.filename, all_exposed_symbols, &module.scope, docs, @@ -899,13 +909,20 @@ struct DocUrl { title: String, } +enum LinkProblem { + MalformedAutoLink, + AutoLinkIdentNotInScope, + AutoLinkNotExposed, + AutoLinkModuleNotImported, +} + fn doc_url<'a>( all_exposed_symbols: &VecSet, scope: &Scope, interns: &'a Interns, mut module_name: &'a str, ident: &str, -) -> DocUrl { +) -> Result { if module_name.is_empty() { // This is an unqualified lookup, so look for the ident // in scope! @@ -918,10 +935,7 @@ fn doc_url<'a>( module_name = symbol.module_string(interns); } Err(_) => { - // TODO return Err here - panic!( - "Tried to generate an automatic link in docs for symbol `{ident}`, but that symbol was not in scope in this module." - ); + return Err((format!("[{ident}]"), LinkProblem::AutoLinkIdentNotInScope)); } } } else { @@ -940,9 +954,10 @@ fn doc_url<'a>( // Note: You can do qualified lookups on your own module, e.g. // if I'm in the Foo module, I can do a `Foo.bar` lookup. else if !all_exposed_symbols.contains(&symbol) { - // TODO return Err here - panic!( - "Tried to generate an automatic link in docs for `{module_name}.{ident}`, but `{module_name}` does not expose `{ident}`."); + return Err(( + format!("[{module_name}.{ident}]"), + LinkProblem::AutoLinkNotExposed, + )); } // This is a valid symbol for this dependency, @@ -952,8 +967,10 @@ fn doc_url<'a>( // incorporate the package name into the link. } None => { - // TODO return Err here - panic!("Tried to generate a doc link for `{module_name}.{ident}` but the `{module_name}` module was not imported!"); + return Err(( + format!("[{module_name}.{ident}]"), + LinkProblem::AutoLinkModuleNotImported, + )); } } } @@ -967,14 +984,15 @@ fn doc_url<'a>( url.push('#'); url.push_str(ident); - DocUrl { + Ok(DocUrl { url, title: format!("Docs for {module_name}.{ident}"), - } + }) } fn markdown_to_html( buf: &mut String, + filename: &Path, all_exposed_symbols: &VecSet, scope: &Scope, markdown: &str, @@ -1010,20 +1028,33 @@ fn markdown_to_html( match iter.next() { Some(Accessor::RecordField(symbol_name)) if iter.next().is_none() => { - let DocUrl { url, title } = doc_url( + match doc_url( all_exposed_symbols, scope, &loaded_module.interns, module_name, symbol_name, - ); + ) { + Ok(DocUrl { url, title }) => Some((url.into(), title.into())), + Err((link_markdown, problem)) => { + report_markdown_link_problem( + loaded_module.module_id, + filename.to_path_buf(), + &link_markdown, + problem, + ); - Some((url.into(), title.into())) + None + } + } } _ => { - // This had record field access, - // e.g. [foo.bar] - which we - // can't create a doc link to! + report_markdown_link_problem( + loaded_module.module_id, + filename.to_path_buf(), + &format!("[{}]", link.reference), + LinkProblem::MalformedAutoLink, + ); None } } @@ -1031,17 +1062,36 @@ fn markdown_to_html( Ok((_, Ident::Tag(type_name), _)) => { // This looks like a tag name, but it could // be a type alias that's in scope, e.g. [I64] - let DocUrl { url, title } = doc_url( + match doc_url( all_exposed_symbols, scope, &loaded_module.interns, "", type_name, + ) { + Ok(DocUrl { url, title }) => Some((url.into(), title.into())), + Err((link_markdown, problem)) => { + report_markdown_link_problem( + loaded_module.module_id, + filename.to_path_buf(), + &link_markdown, + problem, + ); + + None + } + } + } + _ => { + report_markdown_link_problem( + loaded_module.module_id, + filename.to_path_buf(), + &format!("[{}]", link.reference), + LinkProblem::MalformedAutoLink, ); - Some((url.into(), title.into())) + None } - _ => None, } } _ => None, @@ -1137,3 +1187,62 @@ fn markdown_to_html( pulldown_cmark::html::push_html(buf, docs_parser.into_iter()); } + +/// TODO: this should be moved into Reporting, and the markdown checking +/// for docs should be part of `roc check`. Problems like these should +/// be reported as `roc check` warnings and included in the total count +/// of warnings at the end. +fn report_markdown_link_problem( + module_id: ModuleId, + filename: PathBuf, + link_markdown: &str, + problem: LinkProblem, +) { + use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE}; + use ven_pretty::DocAllocator; + + // Report parsing and canonicalization problems + let interns = Interns::default(); + let alloc = RocDocAllocator::new(&[], module_id, &interns); + + let report = { + const AUTO_LINK_TIP: &str = "Tip: When a link in square brackets doesn't have a URL immediately after it in parentheses, the part in square brackets needs to be the name of either an uppercase type in scope, or a lowercase value in scope. Then Roc will generate a link to its docs, if available."; + + let link_problem = match problem { + LinkProblem::MalformedAutoLink => alloc.stack([ + alloc.reflow("The part in square brackets is not a Roc type or value name that can be automatically linked to."), + alloc.reflow(AUTO_LINK_TIP), + ]), + LinkProblem::AutoLinkIdentNotInScope => alloc.stack([ + alloc.reflow("The name in square brackets was not found in scope."), + alloc.reflow(AUTO_LINK_TIP), + ]), + LinkProblem::AutoLinkNotExposed => alloc.stack([ + alloc.reflow("The name in square brackets is not exposed by the module where it's defined."), + alloc.reflow(AUTO_LINK_TIP), + ]), + LinkProblem::AutoLinkModuleNotImported => alloc.stack([ + alloc.reflow("The name in square brackets is not in scope because its module is not imported."), + alloc.reflow(AUTO_LINK_TIP), + ]) + }; + + let doc = alloc.stack([ + alloc.reflow("This link in a doc comment is invalid:"), + alloc.reflow(link_markdown).indent(4), + link_problem, + ]); + + Report { + filename, + doc, + title: "INVALID DOCS LINK".to_string(), + severity: Severity::Warning, + } + }; + + let palette = DEFAULT_PALETTE; + let mut buf = String::new(); + + report.render_color_terminal(&mut buf, &alloc, &palette); +} From 9b4cc9f25b4ae762f41f4eeb981bff923b2d1782 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 26 Apr 2024 20:34:58 -0400 Subject: [PATCH 44/72] clippy --- crates/compiler/module/src/ident.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/module/src/ident.rs b/crates/compiler/module/src/ident.rs index c82a737204..f54f089110 100644 --- a/crates/compiler/module/src/ident.rs +++ b/crates/compiler/module/src/ident.rs @@ -53,7 +53,7 @@ impl ModuleName { pub fn filename(&self, root_filename: impl AsRef) -> PathBuf { let mut answer = root_filename.as_ref().with_file_name(""); - for part in self.split(".") { + for part in self.split('.') { answer = answer.join(part); } From 7044e1581077867acd91e46268c435567ba1a616 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 26 Apr 2024 20:37:07 -0400 Subject: [PATCH 45/72] Copy edits and fixes on tutorial --- www/content/tutorial.md | 155 +++++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/www/content/tutorial.md b/www/content/tutorial.md index 76625b14b8..9c3b5eb676 100644 --- a/www/content/tutorial.md +++ b/www/content/tutorial.md @@ -198,9 +198,9 @@ You should see this: A definition names an expression. -- The first two defs assign the names `birds` and `iguanas` to the expressions `3` and `2`. -- The next def assigns the name `total` to the expression `Num.toStr (birds + iguanas)`. -- The last def assigns the name `main` to an expression which returns a `Task`. We'll [discuss tasks later](#tasks). +- The first two defs assign the names `birds` and `iguanas` to the expressions `3` and `2`. +- The next def assigns the name `total` to the expression `Num.toStr (birds + iguanas)`. +- The last def assigns the name `main` to an expression which returns a `Task`. We'll [discuss tasks later](#tasks). Once we have a def, we can use its name in other expressions. For example, the `total` expression refers to `birds` and `iguanas`, and `Stdout.line "There are $(total) animals."` refers to `total`. @@ -251,8 +251,8 @@ addAndStringify = \num1, num2 -> We did two things here: -- We introduced a _local def_ named `sum`, and set it equal to `num1 + num2`. Because we defined `sum` inside `addAndStringify`, it's _local_ to that scope and can't be accessed outside that function. -- We added an `if`\-`then`\-`else` conditional to return either `""` or `Num.toStr sum` depending on whether `sum == 0`. +- We introduced a _local def_ named `sum`, and set it equal to `num1 + num2`. Because we defined `sum` inside `addAndStringify`, it's _local_ to that scope and can't be accessed outside that function. +- We added an `if`\-`then`\-`else` conditional to return either `""` or `Num.toStr sum` depending on whether `sum == 0`. Every `if` must be accompanied by both `then` and also `else`. Having an `if` without an `else` is an error, because `if` is an expression, and all expressions must evaluate to a value. If there were ever an `if` without an `else`, that would be an expression that might not evaluate to a value! @@ -402,10 +402,10 @@ returnFoo { foo: "hi!", bar: "blah" } Sometimes we assign a def to a field that happens to have the same name—for example, `{ x: x }`. In these cases, we shorten it to writing the name of the def alone—for example, `{ x }`. We can do this with as many fields as we like; here are several different ways to define the same record: -- `{ x: x, y: y }` -- `{ x, y }` -- `{ x: x, y }` -- `{ x, y: y }` +- `{ x: x, y: y }` +- `{ x, y }` +- `{ x: x, y }` +- `{ x, y: y }` ### [Record destructuring](#record-destructuring) {#record-destructuring} @@ -443,8 +443,8 @@ fromOriginal = { original & birds: 4, iguanas: 3 } The `fromScratch` and `fromOriginal` records are equal, although they're defined in different ways. -- `fromScratch` was built using the same record syntax we've been using up to this point. -- `fromOriginal` created a new record using the contents of `original` as defaults for fields that it didn't specify after the `&`. +- `fromScratch` was built using the same record syntax we've been using up to this point. +- `fromOriginal` created a new record using the contents of `original` as defaults for fields that it didn't specify after the `&`. Note that `&` can't introduce new fields to a record, or change the types of existing fields. (Trying to do either of these will result in an error at build time!) @@ -465,6 +465,8 @@ stoplightColor = Here, `stoplightColor` can have one of three values: `Red`, `Yellow`, or `Green`. The capitalization is very important! If these were lowercase (`red`, `yellow`, `green`), then they would refer to defs. However, because they are capitalized, they instead refer to _tags_. +### [Tags](#tags) {#tags} + A tag is a literal value just like a number or a string. Similarly to how I can write the number `42` or the string `"forty-two"` without defining them first, I can also write the tag `FortyTwo` without defining it first. Also, similarly to how `42 == 42` and `"forty-two" == "forty-two"`, it's also the case that `FortyTwo == FortyTwo`. Let's say we wanted to turn `stoplightColor` from a `Red`, `Green`, or `Yellow` into a string. Here's one way we could do that: @@ -792,9 +794,9 @@ that quite does what you want, and you might find yourself calling `List.get` re retrieve every element in the list and use it to build up the new value you want. That approach can work, but it has a few downsides: -- Each `List.get` call returns a `Result` that must be dealt with, even though you plan to use every element in the list anyway -- There's a runtime performance overhead associated with each of these `Result`s, which you won't find in other "look at every element in the list" operations like `List.keepIf`. -- It's more verbose than the alternative we're about to discuss +- Each `List.get` call returns a `Result` that must be dealt with, even though you plan to use every element in the list anyway +- There's a runtime performance overhead associated with each of these `Result`s, which you won't find in other "look at every element in the list" operations like `List.keepIf`. +- It's more verbose than the alternative we're about to discuss The `List.walk` function gives you a way to walk over the elements in a list and build up whatever return value you like. It's a great alternative to calling `List.get` on every element in the list @@ -1100,9 +1102,9 @@ Here, Roc's compiler will infer that `color`'s type is `[Red, Yellow, Green]`, b A type can be defined to be opaque to hide its internal structure. This is a lot more amazing than it may seem. It can make your code more modular, robust, and easier to read: -- If a type is opaque you can modify its internal structure and be certain that no dependencies need to be updated. -- You can prevent that data needs to be checked multiple times. For example, you can create an opaque `NonEmptyList` from a `List` after you've checked it. Now all functions that you pass this `NonEmptyList` to do not need to handle the empty list case. -- Having the type `Username` in a type signature gives you more context compared to `Str`. Even if the `Username` is an opaque type for `Str`. +- If a type is opaque you can modify its internal structure and be certain that no dependencies need to be updated. +- You can prevent that data needs to be checked multiple times. For example, you can create an opaque `NonEmptyList` from a `List` after you've checked it. Now all functions that you pass this `NonEmptyList` to do not need to handle the empty list case. +- Having the type `Username` in a type signature gives you more context compared to `Str`. Even if the `Username` is an opaque type for `Str`. You can create an opaque type with the `:=` operator. Let's make one called `Username`: @@ -1142,9 +1144,9 @@ Following this pattern, the 16 in `I16` means that it's a signed 16-bit integer. Choosing a size depends on your performance needs and the range of numbers you want to represent. Consider: -- Larger integer sizes can represent a wider range of numbers. If you absolutely need to represent numbers in a certain range, make sure to pick an integer size that can hold them! -- Smaller integer sizes take up less memory. These savings rarely matters in variables and function arguments, but the sizes of integers that you use in data structures can add up. This can also affect whether those data structures fit in [cache lines](https://en.wikipedia.org/wiki/CPU_cache#Cache_performance), which can easily be a performance bottleneck. -- Certain processors work faster on some numeric sizes than others. There isn't even a general rule like "larger numeric sizes run slower" (or the reverse, for that matter) that applies to all processors. In fact, if the CPU is taking too long to run numeric calculations, you may find a performance improvement by experimenting with numeric sizes that are larger than otherwise necessary. However, in practice, doing this typically degrades overall performance, so be careful to measure properly! +- Larger integer sizes can represent a wider range of numbers. If you absolutely need to represent numbers in a certain range, make sure to pick an integer size that can hold them! +- Smaller integer sizes take up less memory. These savings rarely matters in variables and function arguments, but the sizes of integers that you use in data structures can add up. This can also affect whether those data structures fit in [cache lines](https://en.wikipedia.org/wiki/CPU_cache#Cache_performance), which can easily be a performance bottleneck. +- Certain processors work faster on some numeric sizes than others. There isn't even a general rule like "larger numeric sizes run slower" (or the reverse, for that matter) that applies to all processors. In fact, if the CPU is taking too long to run numeric calculations, you may find a performance improvement by experimenting with numeric sizes that are larger than otherwise necessary. However, in practice, doing this typically degrades overall performance, so be careful to measure properly! Here are the different fixed-size integer types that Roc supports: @@ -1155,11 +1157,11 @@ Here are the different fixed-size integer types that Roc supports: | `-32_768`
        `32_767` | `I16` | | `0`
        `65_535` | `U16` | | `-2_147_483_648`
        `2_147_483_647` | `I32` | -| `0`
        `4_294_967_295` (over 4 billion) | `U32` | +| `0`
        `4_294_967_295` (over 4 billion) | `U32` | | `-9_223_372_036_854_775_808`
        `9_223_372_036_854_775_807` | `I64` | -| `0`
        `18_446_744_073_709_551_615` (over 18 quintillion) | `U64` | +| `0`
        `18_446_744_073_709_551_615` (over 18 quintillion) | `U64` | | `-170_141_183_460_469_231_731_687_303_715_884_105_728`
        `170_141_183_460_469_231_731_687_303_715_884_105_727` | `I128` | -| `0`
        `340_282_366_920_938_463_463_374_607_431_768_211_455` (over 340 undecillion) | `U128` | +| `0`
        `340_282_366_920_938_463_463_374_607_431_768_211_455` (over 340 undecillion) | `U128` | If any operation would result in an integer that is either too big or too small to fit in that range (e.g. calling `Int.maxI32 + 1`, which adds 1 to the highest possible 32-bit integer), then the operation will [overflow](https://en.wikipedia.org/wiki/Integer_overflow). When an overflow occurs, the program will crash. @@ -1169,9 +1171,9 @@ As such, it's very important to design your integer operations not to exceed the Roc has three fractional types: -- `F32`, a 32-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754) -- `F64`, a 64-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754) -- `Dec`, a 128-bit decimal [fixed-point number](https://en.wikipedia.org/wiki/Fixed-point_arithmetic) +- `F32`, a 32-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754) +- `F64`, a 64-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754) +- `Dec`, a 128-bit decimal [fixed-point number](https://en.wikipedia.org/wiki/Fixed-point_arithmetic) These are different from integers, they can represent numbers with fractional components, such as 1.5 and -0.123. @@ -1360,11 +1362,13 @@ pluralize = \singular, plural, count -> This `expect` will fail if you call `pluralize` passing a count of 0. Note that inline `expect`s do not halt the program! They are designed to inform, not to affect control flow. Different `roc` commands will also handle `expect`s differently: + - `roc build` discards all `expect`s for optimal runtime performance. - `roc dev` only runs inline `expect`s that are encountered during normal execution of the program. - `roc test` runs top level `expect`s and inline `expect`s that are encountered because of the running of top level `expect`s. Let's clear up any confusion with an example: + ```roc main = expect 1 == 2 @@ -1378,6 +1382,7 @@ double = \num -> expect double 0 == 0 ``` + - `roc build` wil run `main`, ignore `expect 1 == 2` and just print `Hello, World!`. - `roc dev` will run `main`, tell you `expect 1 == 2` failed but will still print `Hello, World!`. - `roc test` will run `expect double 0 == 0` followed by `expect num > -1` and will print how many top level expects passed: `0 failed and 1 passed in 100 ms.`. @@ -1386,12 +1391,12 @@ expect double 0 == 0 Each `.roc` file is a separate module and contains Roc code for different purposes. Here are all of the different types of modules that Roc supports; -- **Builtins** provide functions that are automatically imported into every module. -- **Applications** are combined with a platform and compiled into an executable. -- **Interfaces** provide functions which can be imported into other modules. -- **Packages** organise modules to share functionality across applications and platforms. -- **Platforms** provide effects such as IO to interface with the outside world. -- **Hosted** _note this module type is likely to be deprecated soon_. +- **Builtins** provide functions that are automatically imported into every module. +- **Applications** are combined with a platform and compiled into an executable. +- **Interfaces** provide functions which can be imported into other modules. +- **Packages** organise modules to share functionality across applications and platforms. +- **Platforms** provide effects such as IO to interface with the outside world. +- **Hosted** _note this module type is likely to be deprecated soon_. ### [Builtin Modules](#builtin-modules) {#builtin-modules} @@ -1411,8 +1416,8 @@ These modules are not ordinary `.roc` files that live on your filesystem. Rather Besides being built into the compiler, the builtin modules are different from other modules in that: -- They are always imported. You never need to add them to `imports`. -- All their types are imported unqualified automatically. So you never need to write `Num.Dec`, because it's as if the `Num` module was imported using `imports [Num.{ Dec }]` (the same is true for all the other types in the `Num` module.) +- They are always imported. You never need to add them to `imports`. +- All their types are imported unqualified automatically. So you never need to write `Num.Dec`, because it's as if the `Num` module was imported using `imports [Num.{ Dec }]` (the same is true for all the other types in the `Num` module.) ### [App Module Header](#app-module-header) {#app-module-header} @@ -1439,9 +1444,9 @@ provides [main] to pf The `packages { pf: "https://...tar.br" }` part says three things: -- We're going to be using a _package_ (a collection of modules) that can be downloaded from the URL `"https://...tar.br"` -- That package's [base64](https://en.wikipedia.org/wiki/Base64#URL_applications)\-encoded [BLAKE3]() cryptographic hash is the long string at the end (before the `.tar.br` file extension). Once the file has been downloaded, its contents will be verified against this hash, and it will only be installed if they match. This way, you can be confident the download was neither corrupted nor changed since it was originally published. -- We're going to name that package `pf` so we can refer to it more concisely in the future. +- We're going to be using a _package_ (a collection of modules) that can be downloaded from the URL `"https://...tar.br"` +- That package's [base64](https://en.wikipedia.org/wiki/Base64#URL_applications)\-encoded [BLAKE3]() cryptographic hash is the long string at the end (before the `.tar.br` file extension). Once the file has been downloaded, its contents will be verified against this hash, and it will only be installed if they match. This way, you can be confident the download was neither corrupted nor changed since it was originally published. +- We're going to name that package `pf` so we can refer to it more concisely in the future. The `imports [pf.Stdout]` line says that we want to import the `Stdout` module from the `pf` package, and make it available in the current module. @@ -1516,14 +1521,14 @@ See the [Ingest Files Example](https://www.roc-lang.org/examples/IngestFiles/REA ## [Tasks](#tasks) {#tasks} -Tasks are not currently part of the Roc builtins—currently, each platform exposes their own `Task` implementation, but the plan is to standardize them into a builtin `Task` like module like the builtin modules we already have for `List`, `Str`, and so on—but they're an important part of building Roc applications, so let's continue using the [basic-cli](https://github.com/roc-lang/basic-cli) platform we've been using up to this point as an example! +Tasks are not currently part of the Roc builtins—for now, each platform exposes their own `Task` implementation, but the plan is to standardize them into a builtin `Task` like module like the builtin modules we already have for `List`, `Str`, and so on—but they're an important part of building Roc applications, so let's continue using the [basic-cli](https://github.com/roc-lang/basic-cli) platform we've been using up to this point as an example! In the `basic-cli` platform, here are four operations we can do: -- Write a string to the terminal -- Read a string from user input -- Write a string to a file -- Read a string from a file +- Write a string to the terminal +- Read a string from user input +- Write a string to a file +- Read a string from a file We'll use these four operations to learn about tasks. @@ -1600,9 +1605,10 @@ main = ``` Let's break down what this type is saying: -* `Task` tells us this is a `Task` type. Its two type parameters are just like the ones we saw in `Result` earlier: the first type tells us what this task will produce if it succeeds, and the other one tells us what it will produce if it fails. -* `{}` tells us that this task always produces an empty record when it succeeds. (That is, it doesn't produce anything useful. Empty records don't have any information in them!) This is because the last task in `main` comes from `Stdout.line`, which doesn't produce anything. (In contrast, the `Stdin` task's first type parameter is a `Str`, because it produces a `Str` if it succeeds.) -* `[Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err]` tells us the different ways this task can fail. The `StdoutErr` and `StdinErr` tags are there becase we used `Stdout.line` and `Stdin.line`. We'll talk about `Exit I32` more in a moment. + +- `Task` tells us this is a `Task` type. Its two type parameters are just like the ones we saw in `Result` earlier: the first type tells us what this task will produce if it succeeds, and the other one tells us what it will produce if it fails. +- `{}` tells us that this task always produces an empty record when it succeeds. (That is, it doesn't produce anything useful. Empty records don't have any information in them!) This is because the last task in `main` comes from `Stdout.line`, which doesn't produce anything. (In contrast, the `Stdin` task's first type parameter is a `Str`, because it produces a `Str` if it succeeds.) +- `[Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err]` tells us the different ways this task can fail. The `StdoutErr` and `StdinErr` tags are there becase we used `Stdout.line` and `Stdin.line`. We'll talk about `Exit I32` more in a moment. To understand what the `Exit I32 Str` error means, let's try temporarily commenting out our current `main` and replacing it with this one: @@ -1624,8 +1630,9 @@ main = Task.ok {} This program won't print anything at all, but it will exit with a status code of `0`, indicating success. In summary: -* If the `main` task ends in a `Task.ok {}`, then it means the final task succeeded and the program will exit with status code 0. -* If the `main` task ends in a `Task.err (Exit 42 "…")`, then it means the final task failed, and the only information we got about the failure was that the program should exit with code 42 instead of 0, and that it should print a particular string to stderr to inform the user about what happened. + +- If the `main` task ends in a `Task.ok {}`, then it means the final task succeeded and the program will exit with status code 0. +- If the `main` task ends in a `Task.err (Exit 42 "…")`, then it means the final task failed, and the only information we got about the failure was that the program should exit with code 42 instead of 0, and that it should print a particular string to stderr to inform the user about what happened. ### [Handling task failures](#handling-task-failures) {#handling-task-failures} @@ -1641,7 +1648,7 @@ main = Stdout.line! "Your input was: $(input)" ``` -Adding this type annotation will give us a type mismatch - which is exactly what we want in this case! The type mismatch is telling us that we're claiming the `main` task will only ever fail with an `Exit` tag, but this implementation can *also* fail with `StdoutErr` and `StdinErr` tags. +Adding this type annotation will give us a type mismatch - which is exactly what we want in this case! The type mismatch is telling us that we're claiming the `main` task will only ever fail with an `Exit` tag, but this implementation can _also_ fail with `StdoutErr` and `StdinErr` tags. In other words, adding this annotation effectively opted us out of `basic-cli`'s default error handling. Now any potential task failures (now and in the future) will have to be handled somehow; if we forget to handle any, we'll get a type mismatch like this! For that reason, `basic-cli` applications that are intended to be high-quality (so, not things like quick scripts) will generally benefit from applying this type annotation to `main`. @@ -1678,12 +1685,12 @@ We could also use `Task.onErr` instead, which is like `mapErr` except instead of Since we don't have any extra tasks to run, `mapErr` is more concise because we don't have to say `Task.err` at the end of each branch. -### [The _ type](#_) {#_} +### [The \_ type](#_) {#\_} In a larger program, we might want to split `main` into different pieces for logic and handling errors: ```roc -main : Task {} [Exit I32] +main : Task {} [Exit I32 Str] main = run |> Task.mapErr handleErr @@ -1701,13 +1708,13 @@ handleErr = \err -> StdinErr _ -> Exit 2 "Error writing to stdin." ``` -Here, we used `_` to create *partial* type annotations. Wherever a `_` appears in a type annotation, it essentially means "I'm choosing not to annotate this part right here" and it lets Roc use type inference to fill in the blank behind the scenes. Roc will still compile them and check their types as normal (just like it did before we had any annotations at all); the `_` is about which parts of the type we're choosing to annotate and which parts we're leaving to inference. +Here, we used `_` to create _partial_ type annotations. Wherever a `_` appears in a type annotation, it essentially means "I'm choosing not to annotate this part right here" and it lets Roc use type inference to fill in the blank behind the scenes. Roc will still compile them and check their types as normal (just like it did before we had any annotations at all); the `_` is about which parts of the type we're choosing to annotate and which parts we're leaving to inference. This is a useful technique to use when we don't want to write out a bunch of error types that we're going to handle anyway, and would otherwise have to keep updating every time a new error appeared. If we want to know the full list of errors, we can see it in a number of ways: -* Look at the branches of our `when err is`, since they cover all the errors (and we'd get a compile error if we left any out) -* If we're using an editor that supports it, hovering over the `_` might display the inferred type that goes there. -* We can put an obviously wrong type in there (e.g. replace the `{}` with `Str`, which is totally wrong) and look at the compiler error to see what it inferred as the correct type. +- Look at the branches of our `when err is`, since they cover all the errors (and we'd get a compile error if we left any out) +- If we're using an editor that supports it, hovering over the `_` might display the inferred type that goes there. +- We can put an obviously wrong type in there (e.g. replace the `{}` with `Str`, which is totally wrong) and look at the compiler error to see what it inferred as the correct type. We can also use `_` in type aliases, to express that two types are the same without annotating either of them. For example: @@ -1723,11 +1730,11 @@ run : Task {} RunErr handleErr : RunErr -> [Exit I32 Str] ``` -Of course, we could also choose not to use `_` at all and populate the `RunErr` type alias with the full list of errors that could happen in our `run` task. All of these are totally reasonable stylistic choices, depending on how you prefer the code to look. The all compile to exactly the same thing, and have the same runtime characteristics. +Of course, we could also choose not to use `_` at all and populate the `RunErr` type alias with the full list of errors that could happen in our `run` task. All of these are totally reasonable stylistic choices, depending on how you prefer the code to look. They all compile to exactly the same thing, and have the same runtime characteristics. ### [The ! suffix](#the-!-suffix) {#the-!-suffix} -The `!` suffix operator is a bit of syntax sugar for the `Task.await` function, which has this type: +The `!` suffix operator is syntax sugar for the `Task.await` function, which has this type: ```roc Task.await : Task a err, (a -> Task b err) -> Task b err @@ -1736,6 +1743,7 @@ Task.await : Task a err, (a -> Task b err) -> Task b err Basically, this function creates a task which runs one task, and then runs a second task which can use the output of the first task. (If the first task fails, the second task never gets run.) More specifically, `Task.await` returns a `Task` which: + 1. Runs the given `Task a err` 2. If it fails with some error, returns a `Task` which fails with that same error. (So if the given `Task a err` fails, the `a -> Task b err` function never gets called.) 3. If it succeeds (meaning it produces a success value which has the type `a`), pass the value it succeeded with to the `a -> Task b err` function. Whatever `Task b err` that function returns will be the `Task b err` the entire `Task.await` call returns. @@ -1775,7 +1783,7 @@ If that happens, we don't necessarily know which one was the cause of the failur (In this particular example, it's not very likely that this would come up at all, and even if it did, we might not care which one caused the problem. But you can imagine having multiple HTTP requests, or file writes, and wanting to know which of them was the one that failed.) -A quick way to do this is to "tag the error" using `Task.mapErr` like so: +A quick way to do this is to "tag the error" using `Task.mapErr` to wrap the error in a [tag](#tags) like so: ```roc main = @@ -1804,6 +1812,7 @@ Note that the `!` moves when we do this. It's no longer after `Stdout.line`, but ``` This code is doing three things: + 1. Call `Stdout.line "..."`, which returns a `Task` value 2. Transform that `Task` value into another `Task` value using `|> Task.mapErr` 3. Wait until that final `Task` value (returned by `mapErr`) successfully completes, using `!` @@ -1832,7 +1841,7 @@ See the [Task & Error Handling example](https://www.roc-lang.org/examples/Tasks/ ### [Displaying Roc values with `Inspect.toStr`](#inspect) {#inspect} -The [`Inspect.toStr`](https://www.roc-lang.org/builtins/Inspect#toStr) function returns a `Str` representation of any Roc value. It's useful for things like debugging and logging (although [`dbg`](https://www.roc-lang.org/tutorial#debugging) is often nicer for debugging in particular), but its output is almost never something that should be shown to end users! In this case we're just using it for our own learning, but it would be better to run a `when` on `e` and display a more helpful message. +The [`Inspect.toStr`](https://www.roc-lang.org/builtins/Inspect#toStr) function returns a `Str` representation of any Roc value using its [`Inspect` ability](/abilities#inspect-ability). It's useful for things like debugging and logging (although [`dbg`](https://www.roc-lang.org/tutorial#debugging) is often nicer for debugging in particular), but its output is almost never something that should be shown to end users! In this case we're just using it for our own learning, but it would be better to run a `when` on `e` and display a more helpful message. ```roc when err is @@ -1863,9 +1872,9 @@ fullName = \user -> I can pass this function a record that has more fields than just `firstName` and `lastName`, as long as it has _at least_ both of those fields (and both of them are strings). So any of these calls would work: -- `fullName { firstName: "Sam", lastName: "Sample" }` -- `fullName { firstName: "Sam", lastName: "Sample", email: "blah@example.com" }` -- `fullName { age: 5, firstName: "Sam", things: 3, lastName: "Sample", role: Admin }` +- `fullName { firstName: "Sam", lastName: "Sample" }` +- `fullName { firstName: "Sam", lastName: "Sample", email: "blah@example.com" }` +- `fullName { age: 5, firstName: "Sam", things: 3, lastName: "Sample", role: Admin }` This `user` argument is an _open record_ - that is, a description of a minimum set of fields on a record, and their types. When a function takes an open record as an argument, it's okay if you pass it a record with more fields than just the ones specified. @@ -1905,9 +1914,9 @@ addHttps = \record -> This function uses _constrained records_ in its type. The annotation is saying: -- This function takes a record which has at least a `url` field, and possibly others -- That `url` field has the type `Str` -- It returns a record of exactly the same type as the one it was given +- This function takes a record which has at least a `url` field, and possibly others +- That `url` field has the type `Str` +- It returns a record of exactly the same type as the one it was given So if we give this function a record with five fields, it will return a record with those same five fields. The only requirement is that one of those fields must be `url: Str`. @@ -1915,9 +1924,9 @@ In practice, constrained records appear in type annotations much less often than Here's when you can typically expect to encounter these three flavors of type variables in records: -- _Open records_ are what the compiler infers when you use a record as an argument, or when destructuring it (for example, `{ x, y } =`). -- _Closed records_ are what the compiler infers when you create a new record (for example, `{ x: 5, y: 6 }`) -- _Constrained records_ are what the compiler infers when you do a record update (for example, `{ user & email: newEmail }`) +- _Open records_ are what the compiler infers when you use a record as an argument, or when destructuring it (for example, `{ x, y } =`). +- _Closed records_ are what the compiler infers when you create a new record (for example, `{ x: 5, y: 6 }`) +- _Constrained records_ are what the compiler infers when you do a record update (for example, `{ user & email: newEmail }`) Of note, you can pass a closed record to a function that accepts a smaller open record, but not the reverse. So a function `{ a : Str, b : Bool }* -> Str` can accept an `{ a : Str, b : Bool, c : Bool }` record, but a function `{ a : Str, b : Bool, c : Bool } -> Str` would not accept an `{ a : Str, b : Bool }*` record. @@ -2097,10 +2106,10 @@ However, I could not pass an `[Ok Str]*` to a function with a _closed_ tag union In summary, here's a way to think about the difference between open unions in a value you have, compared to a value you're accepting: -- If you _have_ a closed union, that means it has all the tags it ever will, and can't accumulate more. -- If you _have_ an open union, that means it can accumulate more tags through conditional branches. -- If you _accept_ a closed union, that means you only have to handle the possibilities listed in the union. -- If you _accept_ an open union, that means you have to handle the possibility that it has a tag you can't know about. +- If you _have_ a closed union, that means it has all the tags it ever will, and can't accumulate more. +- If you _have_ an open union, that means it can accumulate more tags through conditional branches. +- If you _accept_ a closed union, that means you only have to handle the possibilities listed in the union. +- If you _accept_ an open union, that means you have to handle the possibility that it has a tag you can't know about. ### [Type Variables in Tag Unions](#type-variables-in-tag-unions) {#type-variables-in-tag-unions} @@ -2140,8 +2149,8 @@ So if we give this function a `[Foo Str, Bar Bool, Baz (List Str)]` argument, th If we removed the type annotation from `example` above, Roc's compiler would infer the same type anyway. This may be surprising if you look closely at the body of the function, because: -- The return type includes `Foo Str`, but no branch explicitly returns `Foo`. Couldn't the return type be `[Bar Bool]a` instead? -- The argument type includes `Bar Bool` even though we never look at `Bar`'s payload. Couldn't the argument type be inferred to be `Bar *` instead of `Bar Bool`, since we never look at it? +- The return type includes `Foo Str`, but no branch explicitly returns `Foo`. Couldn't the return type be `[Bar Bool]a` instead? +- The argument type includes `Bar Bool` even though we never look at `Bar`'s payload. Couldn't the argument type be inferred to be `Bar *` instead of `Bar Bool`, since we never look at it? The reason it has this type is the `other -> other` branch. Take a look at that branch, and ask this question: "What is the type of `other`?" There has to be exactly one answer! It can't be the case that `other` has one type before the `->` and another type after it; whenever you see a named value in Roc, it is guaranteed to have the same type everywhere it appears in that scope. From 052862e0c64621000ad0ae22490b7aa8147e5a2d Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 26 Apr 2024 21:14:31 -0400 Subject: [PATCH 46/72] Fix some unused warnings --- crates/cli/tests/cli_run.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index f969c399f0..e67474321e 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -54,6 +54,7 @@ mod cli_run { const OPTIMIZE_FLAG: &str = concatcp!("--", roc_cli::FLAG_OPTIMIZE); const LINKER_FLAG: &str = concatcp!("--", roc_cli::FLAG_LINKER); const CHECK_FLAG: &str = concatcp!("--", roc_cli::FLAG_CHECK); + #[allow(dead_code)] const PREBUILT_PLATFORM: &str = concatcp!("--", roc_cli::FLAG_PREBUILT); #[allow(dead_code)] const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET); @@ -1025,20 +1026,21 @@ mod cli_run { // TODO not sure if this cfg should still be here: #[cfg(not(debug_assertions))] // this is for testing the benchmarks, to perform proper benchmarks see crates/cli/benches/README.md mod test_benchmarks { + #[allow(unused_imports)] use super::{TestCliCommands, UseValgrind}; use cli_utils::helpers::cli_testing_dir; + #[allow(unused_imports)] use super::{check_output_with_stdin, OPTIMIZE_FLAG, PREBUILT_PLATFORM}; + #[allow(unused_imports)] use std::{path::Path, sync::Once}; - static BENCHMARKS_BUILD_PLATFORM: Once = Once::new(); - fn test_benchmark( roc_filename: &str, stdin: &[&str], expected_ending: &str, - use_valgrind: UseValgrind, + _use_valgrind: UseValgrind, ) { let file_name = cli_testing_dir("benchmarks").join(roc_filename); @@ -1062,15 +1064,18 @@ mod cli_run { } #[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))] - check_output_regular(&file_name, stdin, expected_ending, use_valgrind); + check_output_regular(&file_name, stdin, expected_ending, _use_valgrind); #[cfg(feature = "wasm32-cli-run")] check_output_wasm(&file_name, stdin, expected_ending); #[cfg(feature = "i386-cli-run")] - check_output_i386(&file_name, stdin, expected_ending, use_valgrind); + check_output_i386(&file_name, stdin, expected_ending, _use_valgrind); } + #[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))] + static BENCHMARKS_BUILD_PLATFORM: Once = Once::new(); + #[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))] fn check_output_regular( file_name: &Path, From 5eb2dc7f8af425715ce6724b9f732bd7110dd922 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 26 Apr 2024 22:38:23 -0400 Subject: [PATCH 47/72] Update Inspect docs --- www/content/abilities.md | 55 ++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/www/content/abilities.md b/www/content/abilities.md index 2eeb025b43..4e81c4cca4 100644 --- a/www/content/abilities.md +++ b/www/content/abilities.md @@ -1,15 +1,14 @@ - # Abilities An Ability defines a set of functions that can be implemented by different types. -Abilities are used to constrain the types of function arguments to only those which implement the required functions. +Abilities are used to constrain the types of function arguments to only those which implement the required functions. The function `toJson` below is an example which uses the `Encoding` Ability. ```roc toJson : a -> List U8 where a implements Encoding -toJson = \val -> +toJson = \val -> val |> Encode.toBytes JSON.encoder ``` @@ -60,10 +59,11 @@ Eq implements ``` **Structural equality** is defined as follows: + 1. Tags are equal if their name and also contents are equal. 2. Records are equal if their fields are equal. 3. The collections `Str`, `List`, `Dict`, and `Set` are equal iff they are the same length and their elements are equal. -4. `Num` values are equal if their numbers are equal. However, if both inputs are *NaN* then `isEq` returns `Bool.false`. Refer to `Num.isNaN` for more detail. +4. `Num` values are equal if their numbers are equal. However, if both inputs are _NaN_ then `isEq` returns `Bool.false`. Refer to `Num.isNaN` for more detail. 5. Functions cannot be compared for structural equality, therefore Roc cannot derive `isEq` for types that contain functions. ### [`Hash` Ability](#hash-ability) {#hash-ability} @@ -80,9 +80,9 @@ Hash implements **Implementation Status** - Design Proposal, implementation has not yet started. See [zulip discussion thread](https://roc.zulipchat.com/#narrow/stream/304641-ideas/topic/ordering.2Fsorting.20ability/near/395539545) for more information. If you would like to help implement this, please let us know. -The `Sort` Ability defines the `compare` function, which can be used to compare two values for ordering. +The `Sort` Ability defines the `compare` function, which can be used to compare two values for ordering. -`Sort` is not derived for `Str` as working with utf-8 strings which is a variable length encoding scheme is complex and is achieved through a dedicated library such as [roc-lang/unicode](https://github.com/roc-lang/unicode). +`Sort` is not derived for `Str` as working with utf-8 strings which is a variable length encoding scheme is complex and is achieved through a dedicated library such as [roc-lang/unicode](https://github.com/roc-lang/unicode). **Proposed Definition** of the `Sort` Ability. @@ -111,7 +111,7 @@ fruitBasket = [ ("Apples", 10), ("Bananas", 12), ("Oranges", 5) -] +] expect Encode.toBytes fruitBasket json == bytes # true ``` @@ -134,15 +134,15 @@ Decoding for `Dict` values **has not been implemented**, see [#5294](https://git ```roc bytes : List U8 -bytes = +bytes = """ [ - [ 10, \"Green Bottles\" ], + [ 10, \"Green Bottles\" ], [ 12, \"Buckle My Shoe\" ], [ 5, \"Little Ducks\" ] ] """ - |> Str.toUtf8 + |> Str.toUtf8 result : Result (List (U32, Str)) _ result = Decode.fromBytes bytes json @@ -160,31 +160,36 @@ Decoding implements ### [`Inspect` Ability](#inspect-ability) {#inspect-ability} -**Implementation Status** - Accepted Proposal, implementation in-progress. See [#5775](https://github.com/roc-lang/roc/pull/5775) for progress on auto-deriving `Inspect` for builtin types. +The `Inspect` Ability lets you turn values into strings (or other things, but most commonly strings) that inform Roc programmers about the contents of the value. -The `Inspect` Ability defines the `toInspector` function which can be used with an Inspector to inspect Roc values using the `Inspect.inspect` function. - -Example Inspectors: -- A [LogFormatter](https://github.com/roc-lang/roc/blob/main/examples/LogFormatter.roc) which creates a string representation of Roc values, for use e.g. debug printing to the console. -- A [GuiFormatter](https://github.com/roc-lang/roc/blob/main/examples/GuiFormatter.roc) which creates a GUI representation of Roc values for use e.g. debug visualization in a graphical application. +Every Roc value has the `Inspect` ability automatically, although some of them (such as opaque types which do not list `Inspect` as one of their abilities) use a default `Inspect` implementation which doesn't expose any information about the value. Any opaque type can replace this default `Inspect` implementation with a custom one which exposes as much information as desired about that type's values. **Definition** of the `Inspect` Ability. ```roc -# Inspect.roc Inspect implements - toInspector : val -> Inspector f where val implements Inspect, f implements InspectFormatter + toInspector : val -> Inspector f + where + val implements Inspect, + f implements InspectFormatter ``` +The `toInspector` function takes a value and returns an `Inspector` which describes how to abstractly represent that value's contents in a way that doesn't tie it to a particular representation (such as a string). Then a separate "formatter" can translate a given `Inspector` to a specific format (such as a string in the case of [`Inspect.toStr`](https://www.roc-lang.org/builtins/Inspect#toStr), but also possibly a structured log format, or an interactive GUI element). + +Example formatters: + +- A [LogFormatter](https://github.com/roc-lang/roc/blob/main/examples/LogFormatter.roc) which creates a string representation of Roc values, for use e.g. debug printing to the console. +- A [GuiFormatter](https://github.com/roc-lang/roc/blob/main/examples/GuiFormatter.roc) which creates a GUI representation of Roc values for use e.g. debug visualization in a graphical application. + ## [Opaque Types](#opaque-types) {#opaque-types} -Opaque Types are used to hide implementation details of a type. Modules export functions to define a *public* API for working with a type. +Opaque Types are used to hide implementation details of a type. Modules export functions to define a _public_ API for working with a type. By default abilities are not derived for Opaque Types. However, [Derived](#derived-implementations) and [Custom](#custom-implementations) implementations are two ways to work with abilities for your Opaque Types. ### [Derived Implementations](#derived-implementations) {#derived-implementations} -Abilities can be automatically derived for Opaque Types where the type is an alias for a builtin, or it is composed of other types which also implement that ability. +Abilities can be automatically derived for Opaque Types where the type is an alias for a builtin, or it is composed of other types which also implement that ability. For example you can automatically derive the `Eq` and `Hash` abilities using `implements [ Eq, Hash ]`. @@ -196,7 +201,7 @@ StatsDB := Dict Str { score : Dec, average : Dec } implements [ Eq, Hash ] add : StatsDB, Str, { score : Dec, average : Dec } -> StatsDB add = \@StatsDB db, name, stats -> db |> Dict.insert name stats |> @StatsDB -expect +expect db1 = Dict.empty {} |> @StatsDB |> add "John" { score: 10, average: 10 } db2 = Dict.empty {} |> @StatsDB |> add "John" { score: 10, average: 10 } @@ -237,16 +242,16 @@ fromU8 = \r, g, b, a -> @Color (RGBAu8 r g b a) fromI16 : I16, I16, I16, I16 -> Result Color [OutOfRange] fromI16 = \r, g, b, a -> - if r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255 then + if r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255 then Err OutOfRange - else + else Ok (@Color (RGBAu8 (Num.toU8 r) (Num.toU8 g) (Num.toU8 b) (Num.toU8 a))) fromF32 : F32, F32, F32, F32 -> Result Color [OutOfRange] fromF32 = \r, g, b, a -> - if r < 0.0 || r > 1.0 || g < 0.0 || g > 1.0 || b < 0.0 || b > 1.0 || a < 0.0 || a > 1.0 then + if r < 0.0 || r > 1.0 || g < 0.0 || g > 1.0 || b < 0.0 || b > 1.0 || a < 0.0 || a > 1.0 then Err OutOfRange - else + else Ok (@Color (RGBAf32 r g b a)) ``` From 56ebcd646d3ebb3831947412e77d0674306abe07 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:24:46 +0200 Subject: [PATCH 48/72] use LIBRARY_PATH for zstd Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/nightly_macos_apple_silicon.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/nightly_macos_apple_silicon.yml b/.github/workflows/nightly_macos_apple_silicon.yml index 01c4bc0ca2..e51a16822a 100644 --- a/.github/workflows/nightly_macos_apple_silicon.yml +++ b/.github/workflows/nightly_macos_apple_silicon.yml @@ -14,6 +14,8 @@ jobs: test-and-build: name: Rust tests, build and package nightly release runs-on: [self-hosted, macOS, ARM64] + env: + LIBRARY_PATH: ${{ steps.set_lib_path.outputs.library_path }} timeout-minutes: 90 steps: - uses: actions/checkout@v4 @@ -24,9 +26,9 @@ jobs: - run: zig version - - run: which zig - - - run: ls /Users/m1ci/Downloads/zig-macos-aarch64-0.11.0/ + - name: Need to make sure zstd can be found + id: set_lib_path + run: echo "::set-output name=library_path::$(brew --prefix zstd)/lib" - name: run tests run: cargo test --locked --release From 1dddd18541d646676509c70e09cc6d8ed6adaba0 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:27:03 +0200 Subject: [PATCH 49/72] hardcode LIBRARY_PATH Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/nightly_macos_apple_silicon.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/nightly_macos_apple_silicon.yml b/.github/workflows/nightly_macos_apple_silicon.yml index e51a16822a..0eaf80f522 100644 --- a/.github/workflows/nightly_macos_apple_silicon.yml +++ b/.github/workflows/nightly_macos_apple_silicon.yml @@ -15,7 +15,7 @@ jobs: name: Rust tests, build and package nightly release runs-on: [self-hosted, macOS, ARM64] env: - LIBRARY_PATH: ${{ steps.set_lib_path.outputs.library_path }} + LIBRARY_PATH: /opt/homebrew/Cellar/zstd/1.5.6/lib timeout-minutes: 90 steps: - uses: actions/checkout@v4 @@ -26,10 +26,6 @@ jobs: - run: zig version - - name: Need to make sure zstd can be found - id: set_lib_path - run: echo "::set-output name=library_path::$(brew --prefix zstd)/lib" - - name: run tests run: cargo test --locked --release From a46ba3886a88aad09dc2f75f1e0e6c399ab9b006 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:52:21 +0200 Subject: [PATCH 50/72] back to normal CI --- .github/workflows/ci_manager.yml | 2 +- .github/workflows/nightly_macos_apple_silicon.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_manager.yml b/.github/workflows/ci_manager.yml index a8438b639d..a33b81920d 100644 --- a/.github/workflows/ci_manager.yml +++ b/.github/workflows/ci_manager.yml @@ -1,5 +1,5 @@ on: - #pull_request: + pull_request: name: CI manager diff --git a/.github/workflows/nightly_macos_apple_silicon.yml b/.github/workflows/nightly_macos_apple_silicon.yml index 0eaf80f522..b4d12d700f 100644 --- a/.github/workflows/nightly_macos_apple_silicon.yml +++ b/.github/workflows/nightly_macos_apple_silicon.yml @@ -1,5 +1,5 @@ on: - pull_request: + #pull_request: workflow_dispatch: schedule: - cron: '0 9 * * *' From e8dc6b0ace6c7c068feffafd1b1d2f21aed3b959 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 27 Apr 2024 13:46:43 -0400 Subject: [PATCH 51/72] Add tuples to /tutorial --- www/content/tutorial.md | 98 +++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/www/content/tutorial.md b/www/content/tutorial.md index 3ef7827f50..a186ec5b63 100644 --- a/www/content/tutorial.md +++ b/www/content/tutorial.md @@ -313,40 +313,6 @@ Comments that begin with `##` are "doc comments" which will be included in gener Like other comments, doc comments do not affect the running program. -### [Debugging](#debugging) {#debugging} - -[Print debugging](https://en.wikipedia.org/wiki/Debugging#Techniques) is the most common debugging technique in the history of programming, and Roc has a `dbg` keyword to facilitate it. Here's an example of how to use `dbg`: - -```roc -pluralize = \singular, plural, count -> - dbg count - - if count == 1 then - singular - else - plural -``` - -Whenever this `dbg` line of code is reached, the value of `count` will be printed to [stderr](), along with the source code file and line number where the `dbg` itself was written: - -[pluralize.roc 6:8] 5 - -Here, `[pluralize.roc 6:8]` tells us that this `dbg` was written in the file `pluralize.roc` on line 6, column 8. - -You can give `dbg` any expression you like, for example: - -```roc -dbg Str.concat singular plural -``` - -An easy way to print multiple values at a time is to wrap them in a tag, for example a concise tag like `T`: - -```roc -dbg T "the value of count is:" count -``` - -> **Note:** `dbg` is a debugging tool, and is only available when running your program with `roc program.roc`, `roc dev program.roc` or `roc test program.roc`. When you build a standalone binary with `roc build`, any uses of `dbg` won't be included! - ### [Records](#records) {#records} Currently our `addAndStringify` function takes two arguments. We can instead make it take one argument like so: @@ -449,6 +415,70 @@ The `fromScratch` and `fromOriginal` records are equal, although they're defined Note that `&` can't introduce new fields to a record, or change the types of existing fields. (Trying to do either of these will result in an error at build time!) +### [Debugging with `dbg`](#dbg) {#dbg} + +[Print debugging](https://en.wikipedia.org/wiki/Debugging#Techniques) is the most common debugging technique in the history of programming, and Roc has a `dbg` keyword to facilitate it. Here's an example of how to use `dbg`: + +```roc +pluralize = \singular, plural, count -> + dbg count + + if count == 1 then + singular + else + plural +``` + +Whenever this `dbg` line of code is reached, the value of `count` will be printed to [stderr](), along with the source code file and line number where the `dbg` itself was written: + +[pluralize.roc 6:8] 5 + +Here, `[pluralize.roc 6:8]` tells us that this `dbg` was written in the file `pluralize.roc` on line 6, column 8. + +You can give `dbg` any expression you like, for example: + +```roc +dbg Str.concat singular plural +``` + +### [Tuples](#tuples) {#tuples} + +One way to have `dbg` print multiple values at a time is to wrap them in a record: + +```roc +dbg { text: "the value of count is:", value: count } +``` + +A more concise way would be to wrap them in a _tuple_, like so: + +```roc +dbg ("the value of count is:", count) +``` + +Visually, tuples in Roc look like lists (but with parentheses instead of square brackets). However, a tuple is much more like a record - in fact, tuples and records compile down to the exact same representation at runtime! So anywhere you would use a tuple, you can use a record instead, and the in-memory representation will be exactly the same. + +Like records, tuples are fixed-length and can't be iterated over. Also, they can contain values of different types. The difference is that in a record, each field is labeled (and their position doesn't matter), whereas in a tuple, each field is specified by its position. + +### [Accessing values in tuples](#tuple-access) {#tuple-access} + +Just like how there are two ways to access a record's fields (namely, the `.` operator and [record destructuring(#record-destructuring)), there are also two similar ways to access tuple fields: + +```roc +# tuple field access +tuple = ("hello", 42, ["list"]) + +first = tuple.0 # "hello" +second = tuple.1 # 42 +third = tuple.2 # ["list"] +``` + +```roc +# tuple destructuring +(first, second, third) = ("hello", 42, ["list"]) +``` + +By the way, there are two common ways to pronounce "tuple"—one sounds like "two-pull" and the other rhymes with "supple"—and although no clear consensus has emerged in the programming world, people seem generally accepting when others pronounce it differently than they do. + ## [Pattern Matching](#pattern-matching) {#pattern-matching} Sometimes we want to represent that something can have one of several values. For example: From 6080c12ca8c96c31148a31f5732abe85d549b1d3 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 23 Apr 2024 20:58:32 -0700 Subject: [PATCH 52/72] Parse `!` suffixes as an Expr::TaskAwaitBang instead of using suffix field in ident --- crates/compiler/can/src/desugar.rs | 1 + crates/compiler/can/src/expr.rs | 4 +- crates/compiler/fmt/src/expr.rs | 60 +++----------- crates/compiler/fmt/src/spaces.rs | 1 + crates/compiler/parse/src/ast.rs | 8 +- crates/compiler/parse/src/expr.rs | 82 +++++++++++++------ crates/compiler/parse/src/ident.rs | 26 +++--- crates/language_server/src/analysis/tokens.rs | 1 + 8 files changed, 94 insertions(+), 89 deletions(-) diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index fb36715300..8539747853 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -342,6 +342,7 @@ pub fn desugar_expr<'a>( arena.alloc(Loc { region, value }) } + TaskAwaitBang(_) => todo!("desugar task await bang"), RecordAccess(sub_expr, paths) => { let region = loc_expr.region; let loc_sub_expr = Loc { diff --git a/crates/compiler/can/src/expr.rs b/crates/compiler/can/src/expr.rs index 8ff7029cb7..4854b8024c 100644 --- a/crates/compiler/can/src/expr.rs +++ b/crates/compiler/can/src/expr.rs @@ -1171,6 +1171,7 @@ pub fn canonicalize_expr<'a>( output, ) } + ast::Expr::TaskAwaitBang(..) => todo!("canonicalize_expr on TaskAwaitBang"), ast::Expr::Tag(tag) => { let variant_var = var_store.fresh(); let ext_var = var_store.fresh(); @@ -2464,7 +2465,8 @@ pub fn is_valid_interpolation(expr: &ast::Expr<'_>) -> bool { | ast::Expr::Closure(_, loc_expr) => is_valid_interpolation(&loc_expr.value), ast::Expr::TupleAccess(sub_expr, _) | ast::Expr::ParensAround(sub_expr) - | ast::Expr::RecordAccess(sub_expr, _) => is_valid_interpolation(sub_expr), + | ast::Expr::RecordAccess(sub_expr, _) + | ast::Expr::TaskAwaitBang(sub_expr) => is_valid_interpolation(sub_expr), ast::Expr::Apply(loc_expr, args, _called_via) => { is_valid_interpolation(&loc_expr.value) && args diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs index 9e270a1a34..e5fec8e3d6 100644 --- a/crates/compiler/fmt/src/expr.rs +++ b/crates/compiler/fmt/src/expr.rs @@ -38,9 +38,7 @@ impl<'a> Formattable for Expr<'a> { | Num(..) | NonBase10Int { .. } | SingleQuote(_) - | RecordAccess(_, _) | AccessorFunction(_) - | TupleAccess(_, _) | Var { .. } | Underscore { .. } | MalformedIdent(_, _) @@ -51,6 +49,10 @@ impl<'a> Formattable for Expr<'a> { | EmptyDefsFinal | Crash => false, + RecordAccess(inner, _) | TupleAccess(inner, _) | TaskAwaitBang(inner) => { + inner.is_multiline() + } + // These expressions always have newlines Defs(_, _) | When(_, _) => true, @@ -512,60 +514,18 @@ impl<'a> Formattable for Expr<'a> { } } RecordAccess(expr, key) => { - // Check for any `!` suffixes and format these at the end of expression - let (expr_to_format, suffix_count) = if let Var { - module_name, - ident, - suffixed, - } = expr - { - ( - Var { - module_name, - ident, - suffixed: 0, - }, - suffixed, - ) - } else { - (**expr, &0u8) - }; - - expr_to_format.format_with_options(buf, Parens::InApply, Newlines::Yes, indent); + expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent); buf.push('.'); buf.push_str(key); - - for _ in 0..*suffix_count { - buf.push('!'); - } } TupleAccess(expr, key) => { - // Check for any `!` suffixes and format these at the end of expression - let (expr_to_format, suffix_count) = if let Var { - module_name, - ident, - suffixed, - } = expr - { - ( - Var { - module_name, - ident, - suffixed: 0, - }, - suffixed, - ) - } else { - (**expr, &0u8) - }; - - expr_to_format.format_with_options(buf, Parens::InApply, Newlines::Yes, indent); + expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent); buf.push('.'); buf.push_str(key); - - for _ in 0..*suffix_count { - buf.push('!'); - } + } + TaskAwaitBang(expr) => { + expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent); + buf.push('!'); } MalformedIdent(str, _) => { buf.indent(indent); diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index 732fe23f14..af21f85c08 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -686,6 +686,7 @@ impl<'a> RemoveSpaces<'a> for Expr<'a> { Expr::RecordAccess(a, b) => Expr::RecordAccess(arena.alloc(a.remove_spaces(arena)), b), Expr::AccessorFunction(a) => Expr::AccessorFunction(a), Expr::TupleAccess(a, b) => Expr::TupleAccess(arena.alloc(a.remove_spaces(arena)), b), + Expr::TaskAwaitBang(a) => Expr::TaskAwaitBang(arena.alloc(a.remove_spaces(arena))), Expr::List(a) => Expr::List(a.remove_spaces(arena)), Expr::RecordUpdate { update, fields } => Expr::RecordUpdate { update: arena.alloc(update.remove_spaces(arena)), diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 0cde720fb1..eac2e934f8 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -252,7 +252,7 @@ pub enum Expr<'a> { is_negative: bool, }, - // String Literals + /// String Literals Str(StrLiteral<'a>), // string without escapes in it /// eg 'b' SingleQuote(&'a str), @@ -266,6 +266,9 @@ pub enum Expr<'a> { /// Look up exactly one field on a tuple, e.g. `(x, y).1`. TupleAccess(&'a Expr<'a>, &'a str), + /// Task await bang - i.e. the ! in `File.readUtf8! path` + TaskAwaitBang(&'a Expr<'a>), + // Collection Literals List(Collection<'a, &'a Loc>>), @@ -1873,7 +1876,8 @@ impl<'a> Malformed for Expr<'a> { Str(inner) => inner.is_malformed(), RecordAccess(inner, _) | - TupleAccess(inner, _) => inner.is_malformed(), + TupleAccess(inner, _) | + TaskAwaitBang(inner) => inner.is_malformed(), List(items) => items.is_malformed(), diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index c98168247d..feb3e42069 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -7,7 +7,7 @@ use crate::blankspace::{ space0_after_e, space0_around_e_no_after_indent_check, space0_around_ee, space0_before_e, space0_before_optional_after, space0_e, spaces, spaces_around, spaces_before, }; -use crate::ident::{integer_ident, lowercase_ident, parse_ident, Accessor, Ident}; +use crate::ident::{integer_ident, lowercase_ident, parse_ident, Accessor, Ident, Suffix}; use crate::keyword; use crate::parser::{ self, backtrackable, byte, byte_indent, increment_min_indent, line_min_indent, optional, @@ -135,7 +135,7 @@ fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc>, EExpr<'a> specialize_err(EExpr::InParens, loc_expr_in_parens_help()), record_field_access_chain() )), - move |arena: &'a Bump, value: Loc<(Loc>, Vec<'a, Accessor<'a>>)>| { + move |arena: &'a Bump, value: Loc<(Loc>, Vec<'a, Suffix<'a>>)>| { let Loc { mut region, value: (loc_expr, field_accesses), @@ -156,16 +156,23 @@ fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc>, EExpr<'a> ) } -fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, Accessor<'a>>, EExpr<'a>> { - zero_or_more!(skip_first!( - byte(b'.', EExpr::Access), - specialize_err( - |_, pos| EExpr::Access(pos), - one_of!( - map!(lowercase_ident(), Accessor::RecordField), - map!(integer_ident(), Accessor::TupleIndex), +fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, Suffix<'a>>, EExpr<'a>> { + zero_or_more!(one_of!( + skip_first!( + byte(b'.', EExpr::Access), + specialize_err( + |_, pos| EExpr::Access(pos), + one_of!( + map!(lowercase_ident(), |x| Suffix::Accessor( + Accessor::RecordField(x) + )), + map!(integer_ident(), |x| Suffix::Accessor(Accessor::TupleIndex( + x + ))), + ) ) - ) + ), + map!(byte(b'!', EExpr::Access), |_| Suffix::TaskAwaitBang), )) } @@ -188,10 +195,7 @@ fn loc_term_or_underscore_or_conditional<'a>( loc!(underscore_expression()), loc!(record_literal_help()), loc!(specialize_err(EExpr::List, list_literal_help())), - loc!(map_with_arena!( - assign_or_destructure_identifier(), - ident_to_expr - )), + ident_seq(), ) } @@ -211,10 +215,7 @@ fn loc_term_or_underscore<'a>( loc!(underscore_expression()), loc!(record_literal_help()), loc!(specialize_err(EExpr::List, list_literal_help())), - loc!(map_with_arena!( - assign_or_destructure_identifier(), - ident_to_expr - )), + ident_seq(), ) } @@ -229,13 +230,36 @@ fn loc_term<'a>(options: ExprParseOptions) -> impl Parser<'a, Loc>, EEx loc!(specialize_err(EExpr::Closure, closure_help(options))), loc!(record_literal_help()), loc!(specialize_err(EExpr::List, list_literal_help())), - loc!(map_with_arena!( - assign_or_destructure_identifier(), - ident_to_expr - )), + ident_seq(), ) } +fn ident_seq<'a>() -> impl Parser<'a, Loc>, EExpr<'a>> { + (|arena: &'a Bump, state: State<'a>, min_indent: u32| parse_ident_seq(arena, state, min_indent)) + .trace("ident_seq") +} + +fn parse_ident_seq<'a>( + arena: &'a Bump, + state: State<'a>, + min_indent: u32, +) -> ParseResult<'a, Loc>, EExpr<'a>> { + let (p, loc_ident, state) = + loc!(assign_or_destructure_identifier()).parse(arena, state, min_indent)?; + let expr = ident_to_expr(arena, loc_ident.value); + let (_p, suffixes, state) = record_field_access_chain() + .trace("record_field_access_chain") + .parse(arena, state, min_indent) + .map_err(|(_p, e)| (MadeProgress, e))?; + let expr = apply_expr_access_chain(arena, expr, suffixes); + Ok((MadeProgress, Loc::at(loc_ident.region, expr), state)) +} +// loc!(map_with_arena!( +// assign_or_destructure_identifier(), +// ident_to_expr +// )) +// } + fn underscore_expression<'a>() -> impl Parser<'a, Expr<'a>, EExpr<'a>> { move |arena: &'a Bump, state: State<'a>, min_indent: u32| { let start = state.pos(); @@ -2249,6 +2273,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result return Err(()), Expr::Str(string) => Pattern::StrLiteral(string), @@ -3174,13 +3199,18 @@ fn record_builder_help<'a>( fn apply_expr_access_chain<'a>( arena: &'a Bump, value: Expr<'a>, - accessors: Vec<'a, Accessor<'a>>, + accessors: Vec<'a, Suffix<'a>>, ) -> Expr<'a> { accessors .into_iter() .fold(value, |value, accessor| match accessor { - Accessor::RecordField(field) => Expr::RecordAccess(arena.alloc(value), field), - Accessor::TupleIndex(field) => Expr::TupleAccess(arena.alloc(value), field), + Suffix::Accessor(Accessor::RecordField(field)) => { + Expr::RecordAccess(arena.alloc(value), field) + } + Suffix::Accessor(Accessor::TupleIndex(field)) => { + Expr::TupleAccess(arena.alloc(value), field) + } + Suffix::TaskAwaitBang => Expr::TaskAwaitBang(arena.alloc(value)), }) } diff --git a/crates/compiler/parse/src/ident.rs b/crates/compiler/parse/src/ident.rs index 6511cbf7fd..e4466d5ec8 100644 --- a/crates/compiler/parse/src/ident.rs +++ b/crates/compiler/parse/src/ident.rs @@ -388,6 +388,12 @@ impl<'a> Accessor<'a> { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Suffix<'a> { + Accessor(Accessor<'a>), + TaskAwaitBang, +} + /// a `.foo` or `.1` accessor function fn chomp_accessor(buffer: &[u8], pos: Position) -> Result { // assumes the leading `.` has been chomped already @@ -529,16 +535,16 @@ fn chomp_identifier_chain<'a>( chomped += width as usize; // Parse any `!` suffixes - let mut suffixed = 0; - while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) { - if ch == '!' { - suffixed += 1; - chomped += width; - } else { - // we're done - break; - } - } + let suffixed = 0; + // while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) { + // if ch == '!' { + // suffixed += 1; + // chomped += width; + // } else { + // // we're done + // break; + // } + // } let ident = Ident::Access { module_name, diff --git a/crates/language_server/src/analysis/tokens.rs b/crates/language_server/src/analysis/tokens.rs index 0fcf758625..2f3616c9bf 100644 --- a/crates/language_server/src/analysis/tokens.rs +++ b/crates/language_server/src/analysis/tokens.rs @@ -645,6 +645,7 @@ impl IterTokens for Loc> { Expr::RecordAccess(rcd, _field) => Loc::at(region, *rcd).iter_tokens(arena), Expr::AccessorFunction(accessor) => Loc::at(region, accessor).iter_tokens(arena), Expr::TupleAccess(tup, _field) => Loc::at(region, *tup).iter_tokens(arena), + Expr::TaskAwaitBang(inner) => Loc::at(region, *inner).iter_tokens(arena), Expr::List(lst) => lst.iter_tokens(arena), Expr::RecordUpdate { update, fields } => (update.iter_tokens(arena).into_iter()) .chain(fields.iter().flat_map(|f| f.iter_tokens(arena))) From 7c53cf0cd74e522de5b5dd5acf7f76d93fb23bee Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 24 Apr 2024 19:42:13 -0700 Subject: [PATCH 53/72] Fixup tests --- crates/compiler/can/src/suffixed.rs | 14 +-- crates/compiler/fmt/src/expr.rs | 6 +- crates/compiler/parse/src/ast.rs | 109 ++++++++++++++---- crates/compiler/parse/src/expr.rs | 24 ++-- crates/compiler/parse/src/ident.rs | 20 ++-- .../snapshots/pass/suffixed.expr.result-ast | 16 ++- ...ffixed_multiple_defs.moduledefs.result-ast | 36 +++--- .../pass/suffixed_nested.expr.result-ast | 24 ++-- .../pass/suffixed_one_def.full.result-ast | 28 +++-- .../suffixed_optional_last.full.result-ast | 12 +- 10 files changed, 191 insertions(+), 98 deletions(-) diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 35961c4ddd..7829bc7065 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -6,7 +6,7 @@ use roc_error_macros::internal_error; use roc_module::called_via::CalledVia; use roc_module::ident::ModuleName; use roc_parse::ast::Expr::{self, *}; -use roc_parse::ast::{is_loc_expr_suffixed, wrap_in_task_ok, Pattern, ValueDef, WhenBranch}; +use roc_parse::ast::{is_expr_suffixed, wrap_in_task_ok, Pattern, ValueDef, WhenBranch}; use roc_region::all::{Loc, Region}; use std::cell::Cell; @@ -260,7 +260,7 @@ pub fn unwrap_suffixed_expression_closure_help<'a>( return Err(EUnwrapped::Malformed); } - // note we use `None` here as we don't want to pass a DefExpr up and + // note we use `None` here as we don't want to pass a DefExpr up and // unwrap the definition pattern for the closure match unwrap_suffixed_expression(arena, closure_loc_ret, None) { Ok(unwrapped_expr) => { @@ -368,7 +368,7 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( let (current_if_then_statement, current_if_then_expression) = if_then; // unwrap suffixed (innermost) expressions e.g. `if true then doThing! then ...` - if is_loc_expr_suffixed(current_if_then_expression) { + if is_expr_suffixed(¤t_if_then_expression.value) { // split if_thens around the current index let (before, after) = roc_parse::ast::split_around(if_thens, index); @@ -429,7 +429,7 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( // unwrap suffixed statements e.g. `if isThing! then ...` // note we want to split and nest if-then's so we only run Task's // that are required - if is_loc_expr_suffixed(current_if_then_statement) { + if is_expr_suffixed(¤t_if_then_statement.value) { // split if_thens around the current index let (before, after) = roc_parse::ast::split_around(if_thens, index); @@ -572,14 +572,14 @@ pub fn unwrap_suffixed_expression_when_help<'a>( Expr::When(condition, branches) => { // first unwrap any when branches values - // e.g. - // when foo is + // e.g. + // when foo is // [] -> line! "bar" // _ -> line! "baz" for (branch_index, WhenBranch{value: branch_loc_expr,patterns, guard}) in branches.iter().enumerate() { // if the branch isn't suffixed we can leave it alone - if is_loc_expr_suffixed(branch_loc_expr) { + if is_expr_suffixed(&branch_loc_expr.value) { let unwrapped_branch_value = match unwrap_suffixed_expression(arena, branch_loc_expr, None) { Ok(unwrapped_branch_value) => unwrapped_branch_value, Err(EUnwrapped::UnwrappedSubExpr { sub_arg, sub_pat, sub_new }) => apply_task_await(arena, branch_loc_expr.region, sub_arg, sub_pat, sub_new), diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs index e5fec8e3d6..72996d8e17 100644 --- a/crates/compiler/fmt/src/expr.rs +++ b/crates/compiler/fmt/src/expr.rs @@ -9,7 +9,7 @@ use crate::spaces::{ use crate::Buf; use roc_module::called_via::{self, BinOp}; use roc_parse::ast::{ - is_loc_expr_suffixed, AssignedField, Base, Collection, CommentOrNewline, Expr, ExtractSpaces, + is_expr_suffixed, AssignedField, Base, Collection, CommentOrNewline, Expr, ExtractSpaces, Pattern, RecordBuilderField, WhenBranch, }; use roc_parse::ast::{StrLiteral, StrSegment}; @@ -749,8 +749,8 @@ fn fmt_binops<'a>( || loc_right_side.value.is_multiline() || lefts.iter().any(|(expr, _)| expr.value.is_multiline()); - let is_any_lefts_suffixed = lefts.iter().any(|(left, _)| is_loc_expr_suffixed(left)); - let is_right_suffixed = is_loc_expr_suffixed(loc_right_side); + let is_any_lefts_suffixed = lefts.iter().any(|(left, _)| is_expr_suffixed(&left.value)); + let is_right_suffixed = is_expr_suffixed(&loc_right_side.value); let is_any_suffixed = is_any_lefts_suffixed || is_right_suffixed; let mut is_first = false; diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index eac2e934f8..71dbc458f7 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -395,45 +395,43 @@ pub fn split_loc_exprs_around<'a>( (before, after) } -pub fn is_loc_expr_suffixed(loc_expr: &Loc) -> bool { - match loc_expr.value.extract_spaces().item { +pub fn is_expr_suffixed(expr: &Expr) -> bool { + match expr { // expression without arguments, `read!` - Expr::Var { suffixed, .. } => suffixed > 0, + Expr::Var { suffixed, .. } => false, + + Expr::TaskAwaitBang(..) => true, // expression with arguments, `line! "Foo"` Expr::Apply(sub_loc_expr, apply_args, _) => { - let is_function_suffixed = is_loc_expr_suffixed(sub_loc_expr); - let any_args_suffixed = apply_args.iter().any(|arg| is_loc_expr_suffixed(arg)); + let is_function_suffixed = is_expr_suffixed(&sub_loc_expr.value); + let any_args_suffixed = apply_args.iter().any(|arg| is_expr_suffixed(&arg.value)); any_args_suffixed || is_function_suffixed } // expression in a pipeline, `"hi" |> say!` Expr::BinOps(firsts, last) => { - let is_expr_suffixed = is_loc_expr_suffixed(last); - let any_chain_suffixed = firsts + firsts .iter() - .any(|(chain_loc_expr, _)| is_loc_expr_suffixed(chain_loc_expr)); - - is_expr_suffixed || any_chain_suffixed + .any(|(chain_loc_expr, _)| is_expr_suffixed(&chain_loc_expr.value)) + || is_expr_suffixed(&last.value) } // expression in a if-then-else, `if isOk! then "ok" else doSomething!` Expr::If(if_thens, final_else) => { let any_if_thens_suffixed = if_thens.iter().any(|(if_then, else_expr)| { - is_loc_expr_suffixed(if_then) || is_loc_expr_suffixed(else_expr) + is_expr_suffixed(&if_then.value) || is_expr_suffixed(&else_expr.value) }); - is_loc_expr_suffixed(final_else) || any_if_thens_suffixed + is_expr_suffixed(&final_else.value) || any_if_thens_suffixed } // expression in parens `(read!)` - Expr::ParensAround(sub_loc_expr) => { - is_loc_expr_suffixed(&Loc::at(loc_expr.region, *sub_loc_expr)) - } + Expr::ParensAround(sub_loc_expr) => is_expr_suffixed(sub_loc_expr), // expression in a closure - Expr::Closure(_, sub_loc_expr) => is_loc_expr_suffixed(sub_loc_expr), + Expr::Closure(_, sub_loc_expr) => is_expr_suffixed(&sub_loc_expr.value), // expressions inside a Defs // note we ignore the final expression as it should not be suffixed @@ -441,16 +439,85 @@ pub fn is_loc_expr_suffixed(loc_expr: &Loc) -> bool { let any_defs_suffixed = defs.tags.iter().any(|tag| match tag.split() { Ok(_) => false, Err(value_index) => match defs.value_defs[value_index.index()] { - ValueDef::Body(_, loc_expr) => is_loc_expr_suffixed(loc_expr), - ValueDef::AnnotatedBody { body_expr, .. } => is_loc_expr_suffixed(body_expr), + ValueDef::Body(_, loc_expr) => is_expr_suffixed(&loc_expr.value), + ValueDef::AnnotatedBody { body_expr, .. } => is_expr_suffixed(&body_expr.value), _ => false, }, }); any_defs_suffixed } + Expr::Float(_) => false, + Expr::Num(_) => false, + Expr::NonBase10Int { + string, + base, + is_negative, + } => false, + Expr::Str(_) => false, + Expr::SingleQuote(_) => false, + Expr::RecordAccess(a, _) => is_expr_suffixed(a), + Expr::AccessorFunction(_) => false, + Expr::TupleAccess(a, _) => is_expr_suffixed(a), + Expr::List(items) => items.iter().any(|x| is_expr_suffixed(&x.value)), + Expr::RecordUpdate { update, fields } => { + is_expr_suffixed(&update.value) + || fields + .iter() + .any(|field| is_assigned_value_suffixed(&field.value)) + } + Expr::Record(items) => items + .iter() + .any(|field| is_assigned_value_suffixed(&field.value)), + Expr::Tuple(items) => items.iter().any(|x| is_expr_suffixed(&x.value)), + Expr::RecordBuilder(items) => items + .iter() + .any(|rbf| is_record_builder_field_suffixed(&rbf.value)), + Expr::IngestedFile(_, _) => false, + Expr::Underscore(_) => false, + Expr::Crash => false, + Expr::Tag(_) => false, + Expr::OpaqueRef(_) => false, + Expr::EmptyDefsFinal => false, + Expr::Backpassing(_, _, _) => false, // TODO: we might want to check this? + Expr::Expect(a, b) | Expr::Dbg(a, b) => { + is_expr_suffixed(&a.value) || is_expr_suffixed(&b.value) + } + Expr::LowLevelDbg(_, _, _) => todo!(), + Expr::UnaryOp(a, _) => is_expr_suffixed(&a.value), + Expr::When(a, _) => is_expr_suffixed(&a.value), + Expr::SpaceBefore(a, _) => is_expr_suffixed(a), + Expr::SpaceAfter(a, _) => is_expr_suffixed(a), + Expr::MalformedIdent(_, _) => false, + Expr::MalformedClosure => false, + Expr::MalformedSuffixed(_) => false, + Expr::PrecedenceConflict(_) => false, + Expr::MultipleRecordBuilders(_) => false, + Expr::UnappliedRecordBuilder(_) => false, + } +} - _ => false, +fn is_assigned_value_suffixed<'a>(value: &AssignedField<'a, Expr<'a>>) -> bool { + match value { + AssignedField::RequiredValue(_, _, a) | AssignedField::OptionalValue(_, _, a) => { + is_expr_suffixed(&a.value) + } + AssignedField::LabelOnly(_) => false, + AssignedField::SpaceBefore(a, _) | AssignedField::SpaceAfter(a, _) => { + is_assigned_value_suffixed(a) + } + AssignedField::Malformed(_) => false, + } +} + +fn is_record_builder_field_suffixed(field: &RecordBuilderField<'_>) -> bool { + match field { + RecordBuilderField::Value(_, _, a) => is_expr_suffixed(&a.value), + RecordBuilderField::ApplyValue(_, _, _, a) => is_expr_suffixed(&a.value), + RecordBuilderField::LabelOnly(_) => false, + RecordBuilderField::SpaceBefore(a, _) => is_record_builder_field_suffixed(a), + RecordBuilderField::SpaceAfter(a, _) => is_record_builder_field_suffixed(a), + RecordBuilderField::Malformed(_) => false, } } @@ -669,13 +736,13 @@ impl<'a> Defs<'a> { .. }, loc_expr, - ) if collection.is_empty() && is_loc_expr_suffixed(loc_expr) => { + ) if collection.is_empty() && is_expr_suffixed(&loc_expr.value) => { let mut new_defs = self.clone(); new_defs.remove_value_def(tag_index); return Some((new_defs, loc_expr)); } - ValueDef::Stmt(loc_expr) if is_loc_expr_suffixed(loc_expr) => { + ValueDef::Stmt(loc_expr) if is_expr_suffixed(&loc_expr.value) => { let mut new_defs = self.clone(); new_defs.remove_value_def(tag_index); diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index feb3e42069..e8f4703823 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1,5 +1,5 @@ use crate::ast::{ - is_loc_expr_suffixed, AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces, + is_expr_suffixed, AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces, Implements, ImplementsAbilities, Pattern, RecordBuilderField, Spaceable, Spaces, TypeAnnotation, TypeDef, TypeHeader, ValueDef, }; @@ -365,7 +365,7 @@ fn expr_operator_chain<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a let initial_state = state.clone(); let end = state.pos(); - let new_options = if is_loc_expr_suffixed(&expr) { + let new_options = if is_expr_suffixed(&expr.value) { options.set_suffixed_found() } else { options @@ -394,7 +394,7 @@ fn expr_operator_chain<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a Ok((progress, expr, new_state)) => { // We need to check if we have just parsed a suffixed statement, // if so, this is a defs node. - if is_loc_expr_suffixed(&Loc::at_zero(expr)) { + if is_expr_suffixed(&expr) { let def_region = Region::new(end, new_state.pos()); let value_def = ValueDef::Stmt(arena.alloc(Loc::at(def_region, expr))); @@ -466,7 +466,7 @@ impl<'a> ExprState<'a> { } else if !self.expr.value.is_tag() && !self.expr.value.is_opaque() && !self.arguments.is_empty() - && !is_loc_expr_suffixed(&self.expr) + && !is_expr_suffixed(&self.expr.value) { let region = Region::across_all(self.arguments.iter().map(|v| &v.region)); @@ -693,7 +693,9 @@ pub fn parse_single_def<'a>( |_, loc_def_expr| -> ValueDef<'a> { ValueDef::Stmt(arena.alloc(loc_def_expr)) }, ) { Ok((_, Some(single_def), state)) => match single_def.type_or_value { - Either::Second(ValueDef::Stmt(loc_expr)) if is_loc_expr_suffixed(loc_expr) => { + Either::Second(ValueDef::Stmt(loc_expr)) + if is_expr_suffixed(&loc_expr.value) => + { Ok((MadeProgress, Some(single_def), state)) } _ => Ok((NoProgress, None, initial)), // a hacky way to get expression-based error messages. TODO fix this @@ -926,7 +928,9 @@ pub fn parse_single_def<'a>( |_, loc_def_expr| -> ValueDef<'a> { ValueDef::Stmt(arena.alloc(loc_def_expr)) }, ) { Ok((_, Some(single_def), state)) => match single_def.type_or_value { - Either::Second(ValueDef::Stmt(loc_expr)) if is_loc_expr_suffixed(loc_expr) => { + Either::Second(ValueDef::Stmt(loc_expr)) + if is_expr_suffixed(&loc_expr.value) => + { Ok((MadeProgress, Some(single_def), state)) } _ => Ok((NoProgress, None, initial)), @@ -955,7 +959,7 @@ pub fn parse_single_def_assignment<'a>( // If the expression is actually a suffixed statement, then we need to continue // to parse the rest of the expression - if crate::ast::is_loc_expr_suffixed(&first_loc_expr) { + if crate::ast::is_expr_suffixed(&first_loc_expr.value) { let mut defs = Defs::default(); // Take the suffixed value and make it a e.g. Body(`{}=`, Apply(Var(...))) // we will keep the pattern `def_loc_pattern` for the new Defs @@ -1858,7 +1862,7 @@ fn parse_expr_operator<'a>( expr_state.end = new_end; expr_state.spaces_after = spaces; - let new_options = if is_loc_expr_suffixed(&new_expr) { + let new_options = if is_expr_suffixed(&new_expr.value) { options.set_suffixed_found() } else { options @@ -1877,7 +1881,7 @@ fn parse_expr_operator<'a>( let def_region = expr.get_region_spanning_binops(); let mut new_expr = Loc::at(def_region, expr); - if is_loc_expr_suffixed(&new_expr) { + if is_expr_suffixed(&new_expr.value) { // We have parsed a statement such as `"hello" |> line!` // put the spaces from after the operator in front of the call if !spaces_after_operator.is_empty() { @@ -1990,7 +1994,7 @@ fn parse_expr_end<'a>( Ok((_, mut arg, state)) => { let new_end = state.pos(); - let new_options = if is_loc_expr_suffixed(&arg) { + let new_options = if is_expr_suffixed(&arg.value) { options.set_suffixed_found() } else { options diff --git a/crates/compiler/parse/src/ident.rs b/crates/compiler/parse/src/ident.rs index e4466d5ec8..1179663f6b 100644 --- a/crates/compiler/parse/src/ident.rs +++ b/crates/compiler/parse/src/ident.rs @@ -585,16 +585,16 @@ fn chomp_identifier_chain<'a>( let value = unsafe { std::str::from_utf8_unchecked(&buffer[..chomped]) }; // Parse any `!` suffixes - let mut suffixed = 0; - while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) { - if ch == '!' { - suffixed += 1; - chomped += width; - } else { - // we're done - break; - } - } + let suffixed = 0; + // while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) { + // if ch == '!' { + // suffixed += 1; + // chomped += width; + // } else { + // // we're done + // break; + // } + // } let ident = Ident::Access { module_name: "", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast index 0f145b75bb..200b750619 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast @@ -1,5 +1,11 @@ -Var { - module_name: "Stdout", - ident: "line", - suffixed: 3, -} +TaskAwaitBang( + TaskAwaitBang( + TaskAwaitBang( + Var { + module_name: "Stdout", + ident: "line", + suffixed: 0, + }, + ), + ), +) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast index a18299efbd..aafb449ee4 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast @@ -49,11 +49,13 @@ Defs { value_defs: [ Stmt( @14-21 Apply( - @12-14 Var { - module_name: "", - ident: "a", - suffixed: 1, - }, + @12-13 TaskAwaitBang( + Var { + module_name: "", + ident: "a", + suffixed: 0, + }, + ), [ @16-21 Str( PlainLine( @@ -70,11 +72,13 @@ Defs { suffixed: 0, }, @26-39 Apply( - @29-33 Var { - module_name: "B", - ident: "b", - suffixed: 1, - }, + @29-32 TaskAwaitBang( + Var { + module_name: "B", + ident: "b", + suffixed: 0, + }, + ), [ @34-39 Str( PlainLine( @@ -88,11 +92,13 @@ Defs { Stmt( @45-49 SpaceBefore( Apply( - @45-47 Var { - module_name: "", - ident: "c", - suffixed: 1, - }, + @45-46 TaskAwaitBang( + Var { + module_name: "", + ident: "c", + suffixed: 0, + }, + ), [ @48-49 Var { module_name: "", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast index cf5ba0436f..9dbf333a7f 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast @@ -1,17 +1,21 @@ Apply( - @0-4 Var { - module_name: "", - ident: "foo", - suffixed: 1, - }, + @0-3 TaskAwaitBang( + Var { + module_name: "", + ident: "foo", + suffixed: 0, + }, + ), [ @9-17 ParensAround( Apply( - @9-13 Var { - module_name: "", - ident: "bar", - suffixed: 1, - }, + @9-12 TaskAwaitBang( + Var { + module_name: "", + ident: "bar", + suffixed: 0, + }, + ), [ @14-17 Var { module_name: "", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast index ac7d8252cf..92c6aa5159 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast @@ -125,7 +125,7 @@ Full { Index(2147483649), ], regions: [ - @199-212, + @199-211, @241-284, ], space_before: [ @@ -140,7 +140,7 @@ Full { type_defs: [], value_defs: [ Stmt( - @199-212 BinOps( + @199-211 BinOps( [ ( @199-204 Str( @@ -151,11 +151,13 @@ Full { @205-207 Pizza, ), ], - @208-212 Var { - module_name: "A", - ident: "x", - suffixed: 1, - }, + @208-211 TaskAwaitBang( + Var { + module_name: "A", + ident: "x", + suffixed: 0, + }, + ), ), ), Stmt( @@ -172,11 +174,13 @@ Full { ), ], @250-284 Apply( - @250-254 Var { - module_name: "B", - ident: "y", - suffixed: 1, - }, + @250-253 TaskAwaitBang( + Var { + module_name: "B", + ident: "y", + suffixed: 0, + }, + ), [ @264-284 SpaceBefore( Record( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast index 02e99a7a7c..1c21de2d92 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast @@ -143,11 +143,13 @@ Full { ), ], @167-202 Apply( - @167-179 Var { - module_name: "Task", - ident: "mapErr", - suffixed: 1, - }, + @167-178 TaskAwaitBang( + Var { + module_name: "Task", + ident: "mapErr", + suffixed: 0, + }, + ), [ @180-202 Tag( "UnableToCheckJQVersion", From 1640ee1321f52ebc055546d98ef02ec306d1c949 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sat, 27 Apr 2024 12:35:53 +1000 Subject: [PATCH 54/72] update logic for Expr::TaskAwaitBang --- crates/compiler/can/src/desugar.rs | 24 +++-- crates/compiler/can/src/suffixed.rs | 116 ++++++--------------- crates/compiler/can/tests/test_suffixed.rs | 26 ++--- crates/compiler/parse/src/ast.rs | 18 ---- 4 files changed, 55 insertions(+), 129 deletions(-) diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index 8539747853..b6fb8c328f 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -9,8 +9,8 @@ use roc_module::called_via::{BinOp, CalledVia}; use roc_module::ident::ModuleName; use roc_parse::ast::Expr::{self, *}; use roc_parse::ast::{ - wrap_in_task_ok, AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, - StrSegment, ValueDef, WhenBranch, + AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, StrSegment, ValueDef, + WhenBranch, }; use roc_region::all::{LineInfo, Loc, Region}; @@ -193,13 +193,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>) arena, Body( loc_pattern, - apply_task_await( - arena, - loc_expr.region, - sub_arg, - sub_pat, - wrap_in_task_ok(arena, sub_new), - ), + apply_task_await(arena, loc_expr.region, sub_arg, sub_pat, sub_new), ), ), Err(..) => Body( @@ -241,7 +235,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>) body_expr.region, sub_arg, sub_pat, - wrap_in_task_ok(arena, sub_new), + sub_new, ), }, ), @@ -342,7 +336,15 @@ pub fn desugar_expr<'a>( arena.alloc(Loc { region, value }) } - TaskAwaitBang(_) => todo!("desugar task await bang"), + // desugar the sub_expression, but leave the TaskAwaitBang as this will + // be unwrapped later in desugar_value_def_suffixed + TaskAwaitBang(sub_expr) => { + let intermediate = arena.alloc(Loc::at(loc_expr.region, **sub_expr)); + let new_sub_loc_expr = desugar_expr(arena, intermediate, src, line_info, module_path); + let new_sub_expr = arena.alloc(new_sub_loc_expr.value); + + arena.alloc(Loc::at(loc_expr.region, TaskAwaitBang(new_sub_expr))) + } RecordAccess(sub_expr, paths) => { let region = loc_expr.region; let loc_sub_expr = Loc { diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 7829bc7065..8fe77e6e4d 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -6,10 +6,12 @@ use roc_error_macros::internal_error; use roc_module::called_via::CalledVia; use roc_module::ident::ModuleName; use roc_parse::ast::Expr::{self, *}; -use roc_parse::ast::{is_expr_suffixed, wrap_in_task_ok, Pattern, ValueDef, WhenBranch}; +use roc_parse::ast::{is_expr_suffixed, Pattern, ValueDef, WhenBranch}; use roc_region::all::{Loc, Region}; use std::cell::Cell; +static DEBUG_PRINT_UNWRAPPED: bool = false; + thread_local! { // we use a thread_local here so that tests consistently give the same pattern static SUFFIXED_ANSWER_COUNTER: Cell = Cell::new(0); @@ -95,63 +97,21 @@ pub fn unwrap_suffixed_expression<'a>( ) -> Result<&'a Loc>, EUnwrapped<'a>> { let unwrapped_expression = { match loc_expr.value { + Expr::TaskAwaitBang(sub_expr) => { + let unwrapped_sub_expr = arena.alloc(Loc::at(loc_expr.region, *sub_expr)); + + init_unwrapped_err(arena, unwrapped_sub_expr, maybe_def_pat) + } + Expr::Var { module_name, ident, suffixed, } => { - match suffixed { - 0 => Ok(loc_expr), - 1 => { - let unwrapped_var = arena.alloc(Loc::at( - loc_expr.region, - Expr::Var { - module_name, - ident, - suffixed: suffixed.saturating_sub(1), - }, - )); + // TODO remove this when we remove suffixed as no longer used + debug_assert!(suffixed == 0); - init_unwrapped_err(arena, unwrapped_var, maybe_def_pat) - } - _ => { - let unwrapped_var = arena.alloc(Loc::at( - loc_expr.region, - Expr::Var { - module_name, - ident, - suffixed: 0, - }, - )); - - // we generate an intermediate pattern `#!a0` etc - // so we dont unwrap the definition pattern - let (mut answer_var, answer_pat) = next_suffixed_answer_pattern(arena); - - // we transfer the suffix from the Var to the intermediate answer Var - // as that will need to be unwrapped in a future call - if let Expr::Var { - module_name: "", - ident: answer_ident, - suffixed: 0, - } = answer_var - { - answer_var = Expr::Var { - module_name: "", - ident: answer_ident, - suffixed: suffixed.saturating_sub(1), - } - } else { - internal_error!("expected a suffixed Var to be generated"); - } - - Err(EUnwrapped::UnwrappedSubExpr { - sub_arg: unwrapped_var, - sub_pat: arena.alloc(Loc::at(unwrapped_var.region, answer_pat)), - sub_new: arena.alloc(Loc::at(unwrapped_var.region, answer_var)), - }) - } - } + Ok(loc_expr) } Expr::Defs(..) => unwrap_suffixed_expression_defs_help(arena, loc_expr, maybe_def_pat), @@ -189,12 +149,9 @@ pub fn unwrap_suffixed_expression<'a>( } }; - // KEEP THIS HERE FOR DEBUGGING - // USEFUL TO SEE THE UNWRAPPING - // OF AST NODES AS THEY DESCEND - // if is_loc_expr_suffixed(loc_expr) { - // dbg!(&loc_expr, &unwrapped_expression); - // } + if DEBUG_PRINT_UNWRAPPED && is_expr_suffixed(&loc_expr.value) { + dbg!(&maybe_def_pat, &loc_expr, &unwrapped_expression); + } unwrapped_expression } @@ -316,21 +273,15 @@ pub fn unwrap_suffixed_expression_apply_help<'a>( } // special case for when our Apply function is a suffixed Var (but not multiple suffixed) - if let Expr::Var { module_name, ident, suffixed } = function.value { - if suffixed == 1 { - let unwrapped_function = arena.alloc(Loc::at( - loc_expr.region, - Expr::Var { - module_name, - ident, - suffixed: suffixed - 1, - }, - )); + if let Expr::TaskAwaitBang(sub_expr) = function.value { + let unwrapped_function = arena.alloc(Loc::at( + loc_expr.region, + *sub_expr, + )); - let new_apply = arena.alloc(Loc::at(loc_expr.region, Expr::Apply(unwrapped_function, local_args, called_via))); + let new_apply = arena.alloc(Loc::at(loc_expr.region, Expr::Apply(unwrapped_function, local_args, called_via))); - return init_unwrapped_err(arena, new_apply, maybe_def_pat); - } + return init_unwrapped_err(arena, new_apply, maybe_def_pat); } // function is another expression @@ -398,13 +349,8 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( sub_pat, sub_new, }) => { - let unwrapped_expression = apply_task_await( - arena, - sub_arg.region, - sub_arg, - sub_pat, - wrap_in_task_ok(arena, sub_new), - ); + let unwrapped_expression = + apply_task_await(arena, sub_arg.region, sub_arg, sub_pat, sub_new); let mut new_if_thens = Vec::new_in(arena); @@ -541,13 +487,8 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>( sub_pat, sub_new, }) => { - let unwrapped_final_else = apply_task_await( - arena, - sub_arg.region, - sub_arg, - sub_pat, - wrap_in_task_ok(arena, sub_new), - ); + let unwrapped_final_else = + apply_task_await(arena, sub_arg.region, sub_arg, sub_pat, sub_new); let new_if = arena.alloc(Loc::at( loc_expr.region, @@ -670,7 +611,7 @@ pub fn unwrap_suffixed_expression_defs_help<'a>( Ok(next_expr) => next_expr, Err(EUnwrapped::UnwrappedSubExpr { sub_arg, sub_pat, sub_new }) => { // We need to apply Task.ok here as the defs final expression was unwrapped - apply_task_await(arena,def_expr.region,sub_arg,sub_pat,wrap_in_task_ok(arena, sub_new)) + apply_task_await(arena,def_expr.region,sub_arg,sub_pat,sub_new) } Err(EUnwrapped::UnwrappedDefExpr(..)) | Err(EUnwrapped::Malformed) => { // TODO handle case when we have maybe_def_pat so can return an unwrapped up @@ -791,7 +732,8 @@ pub fn apply_task_await<'a>( // If the pattern and the new are matching answers then we don't need to unwrap anything // e.g. `Task.await foo \#!a1 -> Task.ok #!a1` is the same as `foo` - if is_matching_intermediate_answer(loc_pat, loc_new) { + dbg!(&loc_pat, &loc_new); + if dbg!(is_matching_intermediate_answer(loc_pat, loc_new)) { return loc_arg; } diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index 37a788ac66..b5ff72dc84 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -46,7 +46,7 @@ mod suffixed_tests { Task.ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-125], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @29-36 Apply(@29-36 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-36 Apply(@29-36 Var { module_name: "", ident: "line", suffixed: 0 }, [@30-36 Str(PlainLine("Ahoy"))], Space), @29-36 Closure([@29-36 RecordDestructure([])], @58-81 Apply(@58-81 Var { module_name: "Stdout", ident: "line", suffixed: 0 }, [@58-65 Str(PlainLine("There"))], BinOp(Pizza)))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-125], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @29-36 Apply(@29-36 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-36 Apply(@29-36 Var { module_name: "", ident: "line", suffixed: 0 }, [@30-36 Str(PlainLine("Ahoy"))], Space), @29-36 Closure([@29-36 RecordDestructure([])], @58-80 Apply(@58-80 Var { module_name: "Stdout", ident: "line", suffixed: 0 }, [@58-65 Str(PlainLine("There"))], BinOp(Pizza)))], BangSuffix))] }"#, ); } @@ -161,7 +161,7 @@ mod suffixed_tests { x "hi" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-118], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-118 Defs(Defs { tags: [Index(2147483649)], regions: [@27-94], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-94 Defs(Defs { tags: [Index(2147483648)], regions: [@55-67], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@55-67 RecordDestructure([]), @55-67 Apply(@62-67 Var { module_name: "", ident: "line", suffixed: 1 }, [@55-58 Var { module_name: "", ident: "msg", suffixed: 0 }], BinOp(Pizza)))] }, @89-94 Apply(@89-91 Var { module_name: "", ident: "ok", suffixed: 0 }, [@92-94 Record([])], Space)))), Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-67 Apply(@55-67 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@55-67 Apply(@55-67 Var { module_name: "", ident: "line", suffixed: 0 }, [@55-58 Var { module_name: "", ident: "msg", suffixed: 0 }], BinOp(Pizza)), @55-67 Closure([@55-67 RecordDestructure([])], @89-94 Apply(@89-91 Var { module_name: "", ident: "ok", suffixed: 0 }, [@92-94 Record([])], Space))], BangSuffix)))] }, @112-118 Apply(@112-113 Var { module_name: "", ident: "x", suffixed: 0 }, [@114-118 Str(PlainLine("hi"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-118], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-118 Defs(Defs { tags: [Index(2147483649)], regions: [@27-94], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-94 Defs(Defs { tags: [Index(2147483648)], regions: [@55-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@55-66 RecordDestructure([]), @55-66 Apply(@62-66 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@55-58 Var { module_name: "", ident: "msg", suffixed: 0 }], BinOp(Pizza)))] }, @89-94 Apply(@89-91 Var { module_name: "", ident: "ok", suffixed: 0 }, [@92-94 Record([])], Space)))), Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-66 Apply(@55-66 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@55-66 Apply(@55-66 Var { module_name: "", ident: "line", suffixed: 0 }, [@55-58 Var { module_name: "", ident: "msg", suffixed: 0 }], BinOp(Pizza)), @55-66 Closure([@55-66 RecordDestructure([])], @89-94 Apply(@89-91 Var { module_name: "", ident: "ok", suffixed: 0 }, [@92-94 Record([])], Space))], BangSuffix)))] }, @112-118 Apply(@112-113 Var { module_name: "", ident: "x", suffixed: 0 }, [@114-118 Str(PlainLine("hi"))], Space)))] }"#, ); } @@ -198,7 +198,7 @@ mod suffixed_tests { Task.ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-130], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-94 Apply(@24-94 Var { module_name: "", ident: "line", suffixed: 0 }, [@24-69 Apply(@51-61 Var { module_name: "Str", ident: "concat", suffixed: 0 }, [@24-31 Str(PlainLine("hello")), @62-69 Str(PlainLine("world"))], BinOp(Pizza))], BinOp(Pizza)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-130], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-93 Apply(@24-93 Var { module_name: "", ident: "line", suffixed: 0 }, [@24-69 Apply(@51-61 Var { module_name: "Str", ident: "concat", suffixed: 0 }, [@24-31 Str(PlainLine("hello")), @62-69 Str(PlainLine("world"))], BinOp(Pizza))], BinOp(Pizza)))] }"#, ); } @@ -228,7 +228,7 @@ mod suffixed_tests { do = (sayMultiple!) "hi" do "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-47 Apply(@28-47 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "sayMultiple", suffixed: 0 }, @28-47 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-47 Defs(Defs { tags: [Index(2147483650)], regions: [@28-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "sayMultiple", suffixed: 1 }), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@43-47 Str(PlainLine("hi"))], Space))] }, @64-66 Var { module_name: "", ident: "do", suffixed: 0 }))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-47 Apply(@28-47 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "sayMultiple", suffixed: 0 }, @28-47 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-47 Defs(Defs { tags: [Index(2147483650)], regions: [@28-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "sayMultiple", suffixed: 0 })), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@43-47 Str(PlainLine("hi"))], Space))] }, @64-66 Var { module_name: "", ident: "do", suffixed: 0 }))], BangSuffix))] }"##, ); } @@ -267,7 +267,7 @@ mod suffixed_tests { b = bar!! baz a b "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-81], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@27-31 Var { module_name: "", ident: "foo", suffixed: 0 }, @27-31 Closure([@23-24 Identifier { ident: "a", suffixed: 0 }], @48-57 Apply(@48-57 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@48-57 Var { module_name: "", ident: "bar", suffixed: 0 }, @48-57 Closure([@48-57 Identifier { ident: "#!a0", suffixed: 0 }], @48-57 Apply(@48-57 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@48-57 Var { module_name: "", ident: "#!a0", suffixed: 0 }, @48-57 Closure([@48-49 Identifier { ident: "b", suffixed: 0 }], @74-81 Apply(@74-77 Var { module_name: "", ident: "baz", suffixed: 0 }, [@78-79 Var { module_name: "", ident: "a", suffixed: 0 }, @80-81 Var { module_name: "", ident: "b", suffixed: 0 }], Space))], BangSuffix))], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-81], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@27-31 Var { module_name: "", ident: "foo", suffixed: 0 }, @27-31 Closure([@23-24 Identifier { ident: "a", suffixed: 0 }], @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@48-57 Var { module_name: "", ident: "bar", suffixed: 0 }, @27-31 Closure([@48-57 Identifier { ident: "#!a0", suffixed: 0 }], @48-57 Apply(@48-57 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@48-57 Var { module_name: "", ident: "#!a0", suffixed: 0 }, @48-57 Closure([@48-49 Identifier { ident: "b", suffixed: 0 }], @74-81 Apply(@74-77 Var { module_name: "", ident: "baz", suffixed: 0 }, [@78-79 Var { module_name: "", ident: "a", suffixed: 0 }, @80-81 Var { module_name: "", ident: "b", suffixed: 0 }], Space))], BangSuffix))], BangSuffix))], BangSuffix))] }"##, ); } @@ -299,7 +299,7 @@ mod suffixed_tests { foo!! bar "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-49], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @29-29 Apply(@29-29 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-29 Var { module_name: "", ident: "foo", suffixed: 0 }, @29-29 Closure([@29-29 Identifier { ident: "#!a0", suffixed: 0 }], @29-29 Apply(@29-29 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-29 Var { module_name: "", ident: "#!a0", suffixed: 0 }, @29-29 Closure([@29-29 RecordDestructure([])], @46-49 Var { module_name: "", ident: "bar", suffixed: 0 })], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-49], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-49 Apply(@24-49 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-29 Var { module_name: "", ident: "foo", suffixed: 0 }, @24-49 Closure([@29-29 Identifier { ident: "#!a0", suffixed: 0 }], @29-29 Apply(@29-29 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-29 Var { module_name: "", ident: "#!a0", suffixed: 0 }, @29-29 Closure([@29-29 RecordDestructure([])], @46-49 Var { module_name: "", ident: "bar", suffixed: 0 })], BangSuffix))], BangSuffix))] }"##, ); } @@ -324,7 +324,7 @@ mod suffixed_tests { x = (foo! "bar") "hello" baz x "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-48 Apply(@28-48 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "foo", suffixed: 0 }, [@34-39 Str(PlainLine("bar"))], Space), @28-48 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-48 Defs(Defs { tags: [Index(2147483650)], regions: [@28-48], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Apply(@29-33 Var { module_name: "", ident: "foo", suffixed: 1 }, [@34-39 Str(PlainLine("bar"))], Space)), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@41-48 Str(PlainLine("hello"))], Space))] }, @65-70 Apply(@65-68 Var { module_name: "", ident: "baz", suffixed: 0 }, [@69-70 Var { module_name: "", ident: "x", suffixed: 0 }], Space)))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-48 Apply(@28-48 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "foo", suffixed: 0 }, [@34-39 Str(PlainLine("bar"))], Space), @28-48 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-48 Defs(Defs { tags: [Index(2147483650)], regions: [@28-48], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Apply(@29-32 TaskAwaitBang(Var { module_name: "", ident: "foo", suffixed: 0 }), [@34-39 Str(PlainLine("bar"))], Space)), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@41-48 Str(PlainLine("hello"))], Space))] }, @65-70 Apply(@65-68 Var { module_name: "", ident: "baz", suffixed: 0 }, [@69-70 Var { module_name: "", ident: "x", suffixed: 0 }], Space)))], BangSuffix))] }"##, ); } @@ -349,7 +349,7 @@ mod suffixed_tests { x = bar (foo! "hello") baz x "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-68], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-46 Apply(@28-46 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "foo", suffixed: 0 }, [@38-45 Str(PlainLine("hello"))], Space), @28-46 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-46 Defs(Defs { tags: [Index(2147483650)], regions: [@28-46], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Apply(@33-37 Var { module_name: "", ident: "foo", suffixed: 1 }, [@38-45 Str(PlainLine("hello"))], Space))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space))] }, @63-68 Apply(@63-66 Var { module_name: "", ident: "baz", suffixed: 0 }, [@67-68 Var { module_name: "", ident: "x", suffixed: 0 }], Space)))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-68], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-46 Apply(@28-46 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "foo", suffixed: 0 }, [@38-45 Str(PlainLine("hello"))], Space), @28-46 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-46 Defs(Defs { tags: [Index(2147483650)], regions: [@28-46], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Apply(@33-36 TaskAwaitBang(Var { module_name: "", ident: "foo", suffixed: 0 }), [@38-45 Str(PlainLine("hello"))], Space))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space))] }, @63-68 Apply(@63-66 Var { module_name: "", ident: "baz", suffixed: 0 }, [@67-68 Var { module_name: "", ident: "x", suffixed: 0 }], Space)))], BangSuffix))] }"##, ); } @@ -416,7 +416,7 @@ mod suffixed_tests { x "foo" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-187], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-187 Defs(Defs { tags: [Index(2147483650)], regions: [@60-162], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred]))), AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @93-162 Defs(Defs { tags: [Index(2147483649)], regions: [@93-140], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@93-94 Identifier { ident: "y", suffixed: 0 }, @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred])), AnnotatedBody { ann_pattern: @93-94 Identifier { ident: "y", suffixed: 0 }, ann_type: @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred]), comment: None, body_pattern: @127-128 Identifier { ident: "y", suffixed: 0 }, body_expr: @127-140 Apply(@131-136 Var { module_name: "", ident: "line", suffixed: 1 }, [@137-140 Var { module_name: "", ident: "msg", suffixed: 0 }], Space) }] }, @161-162 Var { module_name: "", ident: "y", suffixed: 0 })) }, AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @127-140 Apply(@127-140 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@127-140 Apply(@127-140 Var { module_name: "", ident: "line", suffixed: 0 }, [@137-140 Var { module_name: "", ident: "msg", suffixed: 0 }], Space), @127-140 Closure([@127-128 Identifier { ident: "y", suffixed: 0 }], @161-162 Var { module_name: "", ident: "y", suffixed: 0 })], BangSuffix)) }] }, @180-187 Apply(@180-181 Var { module_name: "", ident: "x", suffixed: 0 }, [@182-187 Str(PlainLine("foo"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-187], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-187 Defs(Defs { tags: [Index(2147483650)], regions: [@60-162], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred]))), AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @93-162 Defs(Defs { tags: [Index(2147483649)], regions: [@93-140], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@93-94 Identifier { ident: "y", suffixed: 0 }, @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred])), AnnotatedBody { ann_pattern: @93-94 Identifier { ident: "y", suffixed: 0 }, ann_type: @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred]), comment: None, body_pattern: @127-128 Identifier { ident: "y", suffixed: 0 }, body_expr: @127-140 Apply(@131-135 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@137-140 Var { module_name: "", ident: "msg", suffixed: 0 }], Space) }] }, @161-162 Var { module_name: "", ident: "y", suffixed: 0 })) }, AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @127-140 Apply(@127-140 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@127-140 Apply(@127-140 Var { module_name: "", ident: "line", suffixed: 0 }, [@137-140 Var { module_name: "", ident: "msg", suffixed: 0 }], Space), @127-140 Closure([@127-128 Identifier { ident: "y", suffixed: 0 }], @161-162 Var { module_name: "", ident: "y", suffixed: 0 })], BangSuffix)) }] }, @180-187 Apply(@180-181 Var { module_name: "", ident: "x", suffixed: 0 }, [@182-187 Str(PlainLine("foo"))], Space)))] }"#, ); } @@ -514,7 +514,7 @@ mod suffixed_tests { foo "bar" {} "baz" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-249], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @25-249 Defs(Defs { tags: [Index(2147483650)], regions: [@81-193], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@25-28 Identifier { ident: "foo", suffixed: 0 }, @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])]))), AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @114-193 Defs(Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@119-121, @142-149], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@119-121 RecordDestructure([]), @119-121 Apply(@114-119 Var { module_name: "", ident: "line", suffixed: 1 }, [@120-121 Var { module_name: "", ident: "a", suffixed: 0 }], Space)), Body(@142-149 RecordDestructure([]), @142-149 Apply(@142-147 Var { module_name: "", ident: "line", suffixed: 1 }, [@148-149 Var { module_name: "", ident: "b", suffixed: 0 }], Space))] }, @183-193 Apply(@183-190 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@191-193 Record([])], Space))) }, AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @119-121 Apply(@119-121 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@119-121 Apply(@119-121 Var { module_name: "", ident: "line", suffixed: 0 }, [@120-121 Var { module_name: "", ident: "a", suffixed: 0 }], Space), @119-121 Closure([@119-121 RecordDestructure([])], @142-149 Apply(@142-149 Var { module_name: "", ident: "line", suffixed: 0 }, [@148-149 Var { module_name: "", ident: "b", suffixed: 0 }], Space))], BangSuffix)) }] }, @231-249 Apply(@231-234 Var { module_name: "", ident: "foo", suffixed: 0 }, [@235-240 Str(PlainLine("bar")), @241-243 Record([]), @244-249 Str(PlainLine("baz"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-249], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @25-249 Defs(Defs { tags: [Index(2147483650)], regions: [@81-193], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@25-28 Identifier { ident: "foo", suffixed: 0 }, @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])]))), AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @114-193 Defs(Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@119-121, @142-149], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@119-121 RecordDestructure([]), @119-121 Apply(@114-118 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@120-121 Var { module_name: "", ident: "a", suffixed: 0 }], Space)), Body(@142-149 RecordDestructure([]), @142-149 Apply(@142-146 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@148-149 Var { module_name: "", ident: "b", suffixed: 0 }], Space))] }, @183-193 Apply(@183-190 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@191-193 Record([])], Space))) }, AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @119-121 Apply(@119-121 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@119-121 Apply(@119-121 Var { module_name: "", ident: "line", suffixed: 0 }, [@120-121 Var { module_name: "", ident: "a", suffixed: 0 }], Space), @119-121 Closure([@119-121 RecordDestructure([])], @142-149 Apply(@142-149 Var { module_name: "", ident: "line", suffixed: 0 }, [@148-149 Var { module_name: "", ident: "b", suffixed: 0 }], Space))], BangSuffix)) }] }, @231-249 Apply(@231-234 Var { module_name: "", ident: "foo", suffixed: 0 }, [@235-240 Str(PlainLine("bar")), @241-243 Record([]), @244-249 Str(PlainLine("baz"))], Space)))] }"#, ); } @@ -650,7 +650,7 @@ mod suffixed_tests { msg "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "isTrue", suffixed: 1 })], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-218 Var { module_name: "", ident: "line", suffixed: 1 }, [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-295 Var { module_name: "", ident: "isFalsey", suffixed: 1 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-343 Var { module_name: "", ident: "line", suffixed: 1 }, [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-435 Var { module_name: "", ident: "line", suffixed: 1 }, [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "isTrue", suffixed: 0 }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line", suffixed: 0 }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "isFalsey", suffixed: 0 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1", suffixed: 0 }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line", suffixed: 0 }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "", ident: "line", suffixed: 0 }, [@436-445 Str(PlainLine("success"))], Space)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg", suffixed: 0 }))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "isTrue", suffixed: 0 }))], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-217 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-294 TaskAwaitBang(Var { module_name: "", ident: "isFalsey", suffixed: 0 }), [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-342 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-434 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "isTrue", suffixed: 0 }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line", suffixed: 0 }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "isFalsey", suffixed: 0 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1", suffixed: 0 }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line", suffixed: 0 }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "", ident: "line", suffixed: 0 }, [@436-445 Str(PlainLine("success"))], Space)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg", suffixed: 0 }))] }"##, ); } @@ -709,7 +709,7 @@ mod suffixed_tests { [] -> "empty" _ -> "non-empty" "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @24-111 Apply(@24-111 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @24-111 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @24-111 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-111 Apply(@0-111 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @0-111 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-111 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, ); } @@ -754,7 +754,7 @@ mod suffixed_tests { _ -> ok {} "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @24-195 Apply(@24-195 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @24-195 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @24-195 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line", suffixed: 0 }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line", suffixed: 0 }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok", suffixed: 0 }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-195 Apply(@0-195 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @0-195 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-195 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line", suffixed: 0 }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line", suffixed: 0 }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok", suffixed: 0 }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, ); } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 71dbc458f7..71a03f1f10 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -521,24 +521,6 @@ fn is_record_builder_field_suffixed(field: &RecordBuilderField<'_>) -> bool { } } -pub fn wrap_in_task_ok<'a>(arena: &'a Bump, loc_expr: &'a Loc>) -> &'a Loc> { - arena.alloc(Loc::at( - loc_expr.region, - Expr::Apply( - arena.alloc(Loc::at( - loc_expr.region, - Expr::Var { - module_name: ModuleName::TASK, - ident: "ok", - suffixed: 0, - }, - )), - arena.alloc([loc_expr]), - CalledVia::BangSuffix, - ), - )) -} - pub fn split_around(items: &[T], target: usize) -> (&[T], &[T]) { let (before, rest) = items.split_at(target); let after = &rest[1..]; From 2fe03e6c91d8fbf250b5ae548e3d600b97cf1b03 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sat, 27 Apr 2024 13:06:19 +1000 Subject: [PATCH 55/72] remove suffixed from Expr::Var --- crates/compiler/can/src/annotation.rs | 9 ++-- crates/compiler/can/src/def.rs | 13 ++---- crates/compiler/can/src/derive.rs | 20 --------- crates/compiler/can/src/desugar.rs | 12 +---- crates/compiler/can/src/expr.rs | 8 ++-- crates/compiler/can/src/suffixed.rs | 27 +++--------- crates/compiler/can/tests/test_suffixed.rs | 44 +++++++++---------- crates/compiler/fmt/src/expr.rs | 11 +---- crates/compiler/fmt/src/spaces.rs | 10 +---- crates/compiler/parse/src/ast.rs | 23 +--------- crates/compiler/parse/src/expr.rs | 20 +++------ crates/compiler/parse/src/pattern.rs | 16 +++---- crates/compiler/parse/tests/test_parse.rs | 7 --- .../test_syntax/tests/test_snapshots.rs | 5 --- crates/repl_eval/src/eval.rs | 2 - 15 files changed, 60 insertions(+), 167 deletions(-) diff --git a/crates/compiler/can/src/annotation.rs b/crates/compiler/can/src/annotation.rs index 0b926f35ba..2eeac35fdc 100644 --- a/crates/compiler/can/src/annotation.rs +++ b/crates/compiler/can/src/annotation.rs @@ -748,10 +748,11 @@ fn can_annotation_help( for loc_var in *loc_vars { let var = match loc_var.value { - Pattern::Identifier { - ident: name, - suffixed: _, - } if name.chars().next().unwrap().is_lowercase() => name, + Pattern::Identifier { ident: name, .. } + if name.chars().next().unwrap().is_lowercase() => + { + name + } _ => unreachable!("I thought this was validated during parsing"), }; let var_name = Lowercase::from(var); diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 15bd3294f0..f5c78172a0 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -547,11 +547,7 @@ fn canonicalize_claimed_ability_impl<'a>( } AssignedField::RequiredValue(label, _spaces, value) => { let impl_ident = match value.value { - ast::Expr::Var { - module_name, - ident, - suffixed: _, - } => { + ast::Expr::Var { module_name, ident } => { if module_name.is_empty() { ident } else { @@ -2574,10 +2570,9 @@ fn to_pending_alias_or_opaque<'a>( for loc_var in vars.iter() { match loc_var.value { - ast::Pattern::Identifier { - ident: name, - suffixed: _, - } if name.chars().next().unwrap().is_lowercase() => { + ast::Pattern::Identifier { ident: name, .. } + if name.chars().next().unwrap().is_lowercase() => + { let lowercase = Lowercase::from(name); can_rigids.push(Loc { value: lowercase, diff --git a/crates/compiler/can/src/derive.rs b/crates/compiler/can/src/derive.rs index afa5209a15..6250ee4af4 100644 --- a/crates/compiler/can/src/derive.rs +++ b/crates/compiler/can/src/derive.rs @@ -37,12 +37,10 @@ fn to_encoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Encode", ident: "toEncoder", - suffixed: 0, }), &*env.arena.alloc([&*alloc_expr(ast::Expr::Var { module_name: "", ident: payload, - suffixed: 0, })]), roc_module::called_via::CalledVia::Space, )); @@ -67,23 +65,19 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Decode", ident: "decodeWith", - suffixed: 0, }), env.arena.alloc([ &*alloc_expr(ast::Expr::Var { module_name: "", ident: bytes, - suffixed: 0, }), alloc_expr(ast::Expr::Var { module_name: "Decode", ident: "decoder", - suffixed: 0, }), alloc_expr(ast::Expr::Var { module_name: "", ident: fmt, - suffixed: 0, }), ]), CalledVia::Space, @@ -94,7 +88,6 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Decode", ident: "mapResult", - suffixed: 0, }), env.arena.alloc([ &*alloc_expr(call_decode_with), @@ -130,7 +123,6 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Decode", ident: "custom", - suffixed: 0, }), env.arena.alloc([&*alloc_expr(custom_closure)]), CalledVia::Space, @@ -165,18 +157,15 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Hash", ident: "hash", - suffixed: 0, }), &*env.arena.alloc([ &*alloc_expr(ast::Expr::Var { module_name: "", ident: hasher, - suffixed: 0, }), &*alloc_expr(ast::Expr::Var { module_name: "", ident: payload, - suffixed: 0, }), ]), roc_module::called_via::CalledVia::Space, @@ -234,18 +223,15 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Bool", ident: "isEq", - suffixed: 0, }), &*env.arena.alloc([ &*alloc_expr(ast::Expr::Var { module_name: "", ident: payload1, - suffixed: 0, }), &*alloc_expr(ast::Expr::Var { module_name: "", ident: payload2, - suffixed: 0, }), ]), roc_module::called_via::CalledVia::Space, @@ -286,12 +272,10 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Inspect", ident: "toInspector", - suffixed: 0, }), &*env.arena.alloc([&*alloc_expr(ast::Expr::Var { module_name: "", ident: payload, - suffixed: 0, })]), roc_module::called_via::CalledVia::Space, )); @@ -306,7 +290,6 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Inspect", ident: "tag", - suffixed: 0, }), &*env.arena.alloc([&*opaque_name, &*to_inspector_list]), roc_module::called_via::CalledVia::Space, @@ -319,14 +302,12 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Inspect", ident: "apply", - suffixed: 0, }), &*env.arena.alloc([ &*opaque_inspector, &*alloc_expr(ast::Expr::Var { module_name: "", ident: fmt, - suffixed: 0, }), ]), roc_module::called_via::CalledVia::Space, @@ -348,7 +329,6 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { alloc_expr(ast::Expr::Var { module_name: "Inspect", ident: "custom", - suffixed: 0, }), env.arena.alloc([&*custom_closure]), CalledVia::Space, diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index b6fb8c328f..3b2ff618d0 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -57,11 +57,7 @@ fn new_op_call_expr<'a>( let args = arena.alloc([left, right]); let loc_expr = arena.alloc(Loc { - value: Expr::Var { - module_name, - ident, - suffixed: 0, - }, + value: Expr::Var { module_name, ident }, region: loc_op.region, }); @@ -604,12 +600,10 @@ pub fn desugar_expr<'a>( Negate => Var { module_name: ModuleName::NUM, ident: "neg", - suffixed: 0, }, Not => Var { module_name: ModuleName::BOOL, ident: "not", - suffixed: 0, }, }; let loc_fn_var = arena.alloc(Loc { region, value }); @@ -707,7 +701,6 @@ pub fn desugar_expr<'a>( let inspect_fn = Var { module_name: ModuleName::INSPECT, ident: "toStr", - suffixed: 0, }; let loc_inspect_fn_var = arena.alloc(Loc { value: inspect_fn, @@ -762,7 +755,6 @@ pub fn desugar_expr<'a>( Expr::Var { module_name: ModuleName::TASK, ident: "ok", - suffixed: 0, }, )), arena.alloc(apply_args), @@ -858,7 +850,6 @@ fn desugar_field<'a>( value: Var { module_name: "", ident: loc_str.value, - suffixed: 0, }, region: loc_str.region, }; @@ -1039,7 +1030,6 @@ fn record_builder_arg<'a>( value: Expr::Var { module_name: "", ident: arena.alloc("#".to_owned() + label.value), - suffixed: 0, }, }); diff --git a/crates/compiler/can/src/expr.rs b/crates/compiler/can/src/expr.rs index 4854b8024c..db395cc404 100644 --- a/crates/compiler/can/src/expr.rs +++ b/crates/compiler/can/src/expr.rs @@ -1019,11 +1019,9 @@ pub fn canonicalize_expr<'a>( (expr, output) } } - ast::Expr::Var { - module_name, - ident, - suffixed: _, // TODO should we use suffixed here? - } => canonicalize_var_lookup(env, var_store, scope, module_name, ident, region), + ast::Expr::Var { module_name, ident } => { + canonicalize_var_lookup(env, var_store, scope, module_name, ident, region) + } ast::Expr::Underscore(name) => { // we parse underscores, but they are not valid expression syntax diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 8fe77e6e4d..9de32b71c3 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -10,8 +10,6 @@ use roc_parse::ast::{is_expr_suffixed, Pattern, ValueDef, WhenBranch}; use roc_region::all::{Loc, Region}; use std::cell::Cell; -static DEBUG_PRINT_UNWRAPPED: bool = false; - thread_local! { // we use a thread_local here so that tests consistently give the same pattern static SUFFIXED_ANSWER_COUNTER: Cell = Cell::new(0); @@ -33,7 +31,6 @@ fn next_suffixed_answer_pattern(arena: &Bump) -> (Expr, Pattern) { Expr::Var { module_name: "", ident: answer_ident, - suffixed: 0, }, Pattern::Identifier { ident: answer_ident.as_str(), @@ -103,17 +100,6 @@ pub fn unwrap_suffixed_expression<'a>( init_unwrapped_err(arena, unwrapped_sub_expr, maybe_def_pat) } - Expr::Var { - module_name, - ident, - suffixed, - } => { - // TODO remove this when we remove suffixed as no longer used - debug_assert!(suffixed == 0); - - Ok(loc_expr) - } - Expr::Defs(..) => unwrap_suffixed_expression_defs_help(arena, loc_expr, maybe_def_pat), Expr::Apply(..) => { @@ -149,9 +135,12 @@ pub fn unwrap_suffixed_expression<'a>( } }; - if DEBUG_PRINT_UNWRAPPED && is_expr_suffixed(&loc_expr.value) { - dbg!(&maybe_def_pat, &loc_expr, &unwrapped_expression); - } + // KEEP THIS HERE FOR DEBUGGING + // USEFUL TO SEE THE UNWRAPPING + // OF AST NODES AS THEY DESCEND + // if is_expr_suffixed(&loc_expr.value) { + // dbg!(&maybe_def_pat, &loc_expr, &unwrapped_expression); + // } unwrapped_expression } @@ -732,8 +721,7 @@ pub fn apply_task_await<'a>( // If the pattern and the new are matching answers then we don't need to unwrap anything // e.g. `Task.await foo \#!a1 -> Task.ok #!a1` is the same as `foo` - dbg!(&loc_pat, &loc_new); - if dbg!(is_matching_intermediate_answer(loc_pat, loc_new)) { + if is_matching_intermediate_answer(loc_pat, loc_new) { return loc_arg; } @@ -758,7 +746,6 @@ pub fn apply_task_await<'a>( value: Var { module_name: ModuleName::TASK, ident: "await", - suffixed: 0, }, }), arena.alloc(task_await_apply_args), diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index b5ff72dc84..0a6024cf66 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -46,7 +46,7 @@ mod suffixed_tests { Task.ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-125], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @29-36 Apply(@29-36 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-36 Apply(@29-36 Var { module_name: "", ident: "line", suffixed: 0 }, [@30-36 Str(PlainLine("Ahoy"))], Space), @29-36 Closure([@29-36 RecordDestructure([])], @58-80 Apply(@58-80 Var { module_name: "Stdout", ident: "line", suffixed: 0 }, [@58-65 Str(PlainLine("There"))], BinOp(Pizza)))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-125], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @29-36 Apply(@29-36 Var { module_name: "Task", ident: "await" }, [@29-36 Apply(@29-36 Var { module_name: "", ident: "line" }, [@30-36 Str(PlainLine("Ahoy"))], Space), @29-36 Closure([@29-36 RecordDestructure([])], @58-80 Apply(@58-80 Var { module_name: "Stdout", ident: "line" }, [@58-65 Str(PlainLine("There"))], BinOp(Pizza)))], BangSuffix))] }"#, ); } @@ -74,7 +74,7 @@ mod suffixed_tests { ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-24 Apply(@24-24 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@24-24 Var { module_name: "", ident: "foo", suffixed: 0 }, @24-24 Closure([@24-24 RecordDestructure([])], @42-47 Apply(@42-44 Var { module_name: "", ident: "ok", suffixed: 0 }, [@45-47 Record([])], Space))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-24 Apply(@24-24 Var { module_name: "Task", ident: "await" }, [@24-24 Var { module_name: "", ident: "foo" }, @24-24 Closure([@24-24 RecordDestructure([])], @42-47 Apply(@42-44 Var { module_name: "", ident: "ok" }, [@45-47 Record([])], Space))], BangSuffix))] }"#, ); } @@ -93,7 +93,7 @@ mod suffixed_tests { r#" main = foo! "bar" {} "baz" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-26], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-26 Apply(@0-26 Var { module_name: "", ident: "foo", suffixed: 0 }, [@12-17 Str(PlainLine("bar")), @18-20 Record([]), @21-26 Str(PlainLine("baz"))], Space))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-26], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-26 Apply(@0-26 Var { module_name: "", ident: "foo" }, [@12-17 Str(PlainLine("bar")), @18-20 Record([]), @21-26 Str(PlainLine("baz"))], Space))] }"#, ); } @@ -127,7 +127,7 @@ mod suffixed_tests { bar! baz! "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-28 Apply(@28-28 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@28-28 Var { module_name: "", ident: "foo", suffixed: 0 }, @28-28 Closure([@28-28 RecordDestructure([])], @45-49 Apply(@45-49 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@45-49 Var { module_name: "", ident: "bar", suffixed: 0 }, @45-49 Closure([@45-49 RecordDestructure([])], @66-70 Var { module_name: "", ident: "baz", suffixed: 0 })], BangSuffix))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-28 Apply(@28-28 Var { module_name: "Task", ident: "await" }, [@28-28 Var { module_name: "", ident: "foo" }, @28-28 Closure([@28-28 RecordDestructure([])], @45-49 Apply(@45-49 Var { module_name: "Task", ident: "await" }, [@45-49 Var { module_name: "", ident: "bar" }, @45-49 Closure([@45-49 RecordDestructure([])], @66-70 Var { module_name: "", ident: "baz" })], BangSuffix))], BangSuffix))] }"#, ); } @@ -161,7 +161,7 @@ mod suffixed_tests { x "hi" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-118], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-118 Defs(Defs { tags: [Index(2147483649)], regions: [@27-94], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-94 Defs(Defs { tags: [Index(2147483648)], regions: [@55-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@55-66 RecordDestructure([]), @55-66 Apply(@62-66 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@55-58 Var { module_name: "", ident: "msg", suffixed: 0 }], BinOp(Pizza)))] }, @89-94 Apply(@89-91 Var { module_name: "", ident: "ok", suffixed: 0 }, [@92-94 Record([])], Space)))), Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-66 Apply(@55-66 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@55-66 Apply(@55-66 Var { module_name: "", ident: "line", suffixed: 0 }, [@55-58 Var { module_name: "", ident: "msg", suffixed: 0 }], BinOp(Pizza)), @55-66 Closure([@55-66 RecordDestructure([])], @89-94 Apply(@89-91 Var { module_name: "", ident: "ok", suffixed: 0 }, [@92-94 Record([])], Space))], BangSuffix)))] }, @112-118 Apply(@112-113 Var { module_name: "", ident: "x", suffixed: 0 }, [@114-118 Str(PlainLine("hi"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-118], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-118 Defs(Defs { tags: [Index(2147483649)], regions: [@27-94], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-94 Defs(Defs { tags: [Index(2147483648)], regions: [@55-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@55-66 RecordDestructure([]), @55-66 Apply(@62-66 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@55-58 Var { module_name: "", ident: "msg" }], BinOp(Pizza)))] }, @89-94 Apply(@89-91 Var { module_name: "", ident: "ok" }, [@92-94 Record([])], Space)))), Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-66 Apply(@55-66 Var { module_name: "Task", ident: "await" }, [@55-66 Apply(@55-66 Var { module_name: "", ident: "line" }, [@55-58 Var { module_name: "", ident: "msg" }], BinOp(Pizza)), @55-66 Closure([@55-66 RecordDestructure([])], @89-94 Apply(@89-91 Var { module_name: "", ident: "ok" }, [@92-94 Record([])], Space))], BangSuffix)))] }, @112-118 Apply(@112-113 Var { module_name: "", ident: "x" }, [@114-118 Str(PlainLine("hi"))], Space)))] }"#, ); } @@ -198,7 +198,7 @@ mod suffixed_tests { Task.ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-130], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-93 Apply(@24-93 Var { module_name: "", ident: "line", suffixed: 0 }, [@24-69 Apply(@51-61 Var { module_name: "Str", ident: "concat", suffixed: 0 }, [@24-31 Str(PlainLine("hello")), @62-69 Str(PlainLine("world"))], BinOp(Pizza))], BinOp(Pizza)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-130], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-93 Apply(@24-93 Var { module_name: "", ident: "line" }, [@24-69 Apply(@51-61 Var { module_name: "Str", ident: "concat" }, [@24-31 Str(PlainLine("hello")), @62-69 Str(PlainLine("world"))], BinOp(Pizza))], BinOp(Pizza)))] }"#, ); } @@ -228,7 +228,7 @@ mod suffixed_tests { do = (sayMultiple!) "hi" do "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-47 Apply(@28-47 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "sayMultiple", suffixed: 0 }, @28-47 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-47 Defs(Defs { tags: [Index(2147483650)], regions: [@28-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "sayMultiple", suffixed: 0 })), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@43-47 Str(PlainLine("hi"))], Space))] }, @64-66 Var { module_name: "", ident: "do", suffixed: 0 }))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-47 Apply(@28-47 Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "sayMultiple" }, @28-47 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-47 Defs(Defs { tags: [Index(2147483650)], regions: [@28-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "sayMultiple" })), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0" }), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0" }), [@43-47 Str(PlainLine("hi"))], Space))] }, @64-66 Var { module_name: "", ident: "do" }))], BangSuffix))] }"##, ); } @@ -267,7 +267,7 @@ mod suffixed_tests { b = bar!! baz a b "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-81], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@27-31 Var { module_name: "", ident: "foo", suffixed: 0 }, @27-31 Closure([@23-24 Identifier { ident: "a", suffixed: 0 }], @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@48-57 Var { module_name: "", ident: "bar", suffixed: 0 }, @27-31 Closure([@48-57 Identifier { ident: "#!a0", suffixed: 0 }], @48-57 Apply(@48-57 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@48-57 Var { module_name: "", ident: "#!a0", suffixed: 0 }, @48-57 Closure([@48-49 Identifier { ident: "b", suffixed: 0 }], @74-81 Apply(@74-77 Var { module_name: "", ident: "baz", suffixed: 0 }, [@78-79 Var { module_name: "", ident: "a", suffixed: 0 }, @80-81 Var { module_name: "", ident: "b", suffixed: 0 }], Space))], BangSuffix))], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-81], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await" }, [@27-31 Var { module_name: "", ident: "foo" }, @27-31 Closure([@23-24 Identifier { ident: "a", suffixed: 0 }], @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await" }, [@48-57 Var { module_name: "", ident: "bar" }, @27-31 Closure([@48-57 Identifier { ident: "#!a0", suffixed: 0 }], @48-57 Apply(@48-57 Var { module_name: "Task", ident: "await" }, [@48-57 Var { module_name: "", ident: "#!a0" }, @48-57 Closure([@48-49 Identifier { ident: "b", suffixed: 0 }], @74-81 Apply(@74-77 Var { module_name: "", ident: "baz" }, [@78-79 Var { module_name: "", ident: "a" }, @80-81 Var { module_name: "", ident: "b" }], Space))], BangSuffix))], BangSuffix))], BangSuffix))] }"##, ); } @@ -299,7 +299,7 @@ mod suffixed_tests { foo!! bar "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-49], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-49 Apply(@24-49 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-29 Var { module_name: "", ident: "foo", suffixed: 0 }, @24-49 Closure([@29-29 Identifier { ident: "#!a0", suffixed: 0 }], @29-29 Apply(@29-29 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-29 Var { module_name: "", ident: "#!a0", suffixed: 0 }, @29-29 Closure([@29-29 RecordDestructure([])], @46-49 Var { module_name: "", ident: "bar", suffixed: 0 })], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-49], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-49 Apply(@24-49 Var { module_name: "Task", ident: "await" }, [@29-29 Var { module_name: "", ident: "foo" }, @24-49 Closure([@29-29 Identifier { ident: "#!a0", suffixed: 0 }], @29-29 Apply(@29-29 Var { module_name: "Task", ident: "await" }, [@29-29 Var { module_name: "", ident: "#!a0" }, @29-29 Closure([@29-29 RecordDestructure([])], @46-49 Var { module_name: "", ident: "bar" })], BangSuffix))], BangSuffix))] }"##, ); } @@ -324,7 +324,7 @@ mod suffixed_tests { x = (foo! "bar") "hello" baz x "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-48 Apply(@28-48 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "foo", suffixed: 0 }, [@34-39 Str(PlainLine("bar"))], Space), @28-48 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-48 Defs(Defs { tags: [Index(2147483650)], regions: [@28-48], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Apply(@29-32 TaskAwaitBang(Var { module_name: "", ident: "foo", suffixed: 0 }), [@34-39 Str(PlainLine("bar"))], Space)), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), [@41-48 Str(PlainLine("hello"))], Space))] }, @65-70 Apply(@65-68 Var { module_name: "", ident: "baz", suffixed: 0 }, [@69-70 Var { module_name: "", ident: "x", suffixed: 0 }], Space)))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-48 Apply(@28-48 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "foo" }, [@34-39 Str(PlainLine("bar"))], Space), @28-48 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-48 Defs(Defs { tags: [Index(2147483650)], regions: [@28-48], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Apply(@29-32 TaskAwaitBang(Var { module_name: "", ident: "foo" }), [@34-39 Str(PlainLine("bar"))], Space)), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0" }), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0" }), [@41-48 Str(PlainLine("hello"))], Space))] }, @65-70 Apply(@65-68 Var { module_name: "", ident: "baz" }, [@69-70 Var { module_name: "", ident: "x" }], Space)))], BangSuffix))] }"##, ); } @@ -349,7 +349,7 @@ mod suffixed_tests { x = bar (foo! "hello") baz x "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-68], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-46 Apply(@28-46 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "foo", suffixed: 0 }, [@38-45 Str(PlainLine("hello"))], Space), @28-46 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-46 Defs(Defs { tags: [Index(2147483650)], regions: [@28-46], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Apply(@33-36 TaskAwaitBang(Var { module_name: "", ident: "foo", suffixed: 0 }), [@38-45 Str(PlainLine("hello"))], Space))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar", suffixed: 0 }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space))] }, @63-68 Apply(@63-66 Var { module_name: "", ident: "baz", suffixed: 0 }, [@67-68 Var { module_name: "", ident: "x", suffixed: 0 }], Space)))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-68], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-46 Apply(@28-46 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "foo" }, [@38-45 Str(PlainLine("hello"))], Space), @28-46 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-46 Defs(Defs { tags: [Index(2147483650)], regions: [@28-46], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Apply(@33-36 TaskAwaitBang(Var { module_name: "", ident: "foo" }), [@38-45 Str(PlainLine("hello"))], Space))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0" })], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0" })], Space))] }, @63-68 Apply(@63-66 Var { module_name: "", ident: "baz" }, [@67-68 Var { module_name: "", ident: "x" }], Space)))], BangSuffix))] }"##, ); } @@ -375,7 +375,7 @@ mod suffixed_tests { x = foo! msg bar x "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-88], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-88 Defs(Defs { tags: [Index(2147483649)], regions: [@30-37], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-27 Identifier { ident: "msg", suffixed: 0 }, @30-37 Str(PlainLine("hello"))), Body(@24-27 Identifier { ident: "msg", suffixed: 0 }, @30-37 Str(PlainLine("hello")))] }, @0-88 Apply(@0-88 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@54-66 Apply(@54-66 Var { module_name: "", ident: "foo", suffixed: 0 }, [@63-66 Var { module_name: "", ident: "msg", suffixed: 0 }], Space), @0-88 Closure([@54-55 Identifier { ident: "x", suffixed: 0 }], @83-88 Apply(@83-86 Var { module_name: "", ident: "bar", suffixed: 0 }, [@87-88 Var { module_name: "", ident: "x", suffixed: 0 }], Space))], BangSuffix)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-88], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-88 Defs(Defs { tags: [Index(2147483649)], regions: [@30-37], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-27 Identifier { ident: "msg", suffixed: 0 }, @30-37 Str(PlainLine("hello"))), Body(@24-27 Identifier { ident: "msg", suffixed: 0 }, @30-37 Str(PlainLine("hello")))] }, @0-88 Apply(@0-88 Var { module_name: "Task", ident: "await" }, [@54-66 Apply(@54-66 Var { module_name: "", ident: "foo" }, [@63-66 Var { module_name: "", ident: "msg" }], Space), @0-88 Closure([@54-55 Identifier { ident: "x", suffixed: 0 }], @83-88 Apply(@83-86 Var { module_name: "", ident: "bar" }, [@87-88 Var { module_name: "", ident: "x" }], Space))], BangSuffix)))] }"#, ); } @@ -416,7 +416,7 @@ mod suffixed_tests { x "foo" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-187], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-187 Defs(Defs { tags: [Index(2147483650)], regions: [@60-162], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred]))), AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @93-162 Defs(Defs { tags: [Index(2147483649)], regions: [@93-140], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@93-94 Identifier { ident: "y", suffixed: 0 }, @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred])), AnnotatedBody { ann_pattern: @93-94 Identifier { ident: "y", suffixed: 0 }, ann_type: @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred]), comment: None, body_pattern: @127-128 Identifier { ident: "y", suffixed: 0 }, body_expr: @127-140 Apply(@131-135 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@137-140 Var { module_name: "", ident: "msg", suffixed: 0 }], Space) }] }, @161-162 Var { module_name: "", ident: "y", suffixed: 0 })) }, AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @127-140 Apply(@127-140 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@127-140 Apply(@127-140 Var { module_name: "", ident: "line", suffixed: 0 }, [@137-140 Var { module_name: "", ident: "msg", suffixed: 0 }], Space), @127-140 Closure([@127-128 Identifier { ident: "y", suffixed: 0 }], @161-162 Var { module_name: "", ident: "y", suffixed: 0 })], BangSuffix)) }] }, @180-187 Apply(@180-181 Var { module_name: "", ident: "x", suffixed: 0 }, [@182-187 Str(PlainLine("foo"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-187], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-187 Defs(Defs { tags: [Index(2147483650)], regions: [@60-162], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred]))), AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @93-162 Defs(Defs { tags: [Index(2147483649)], regions: [@93-140], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@93-94 Identifier { ident: "y", suffixed: 0 }, @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred])), AnnotatedBody { ann_pattern: @93-94 Identifier { ident: "y", suffixed: 0 }, ann_type: @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred]), comment: None, body_pattern: @127-128 Identifier { ident: "y", suffixed: 0 }, body_expr: @127-140 Apply(@131-135 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@137-140 Var { module_name: "", ident: "msg" }], Space) }] }, @161-162 Var { module_name: "", ident: "y" })) }, AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @127-140 Apply(@127-140 Var { module_name: "Task", ident: "await" }, [@127-140 Apply(@127-140 Var { module_name: "", ident: "line" }, [@137-140 Var { module_name: "", ident: "msg" }], Space), @127-140 Closure([@127-128 Identifier { ident: "y", suffixed: 0 }], @161-162 Var { module_name: "", ident: "y" })], BangSuffix)) }] }, @180-187 Apply(@180-181 Var { module_name: "", ident: "x" }, [@182-187 Str(PlainLine("foo"))], Space)))] }"#, ); } @@ -436,7 +436,7 @@ mod suffixed_tests { r#" run = line! (nextMsg!) "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-22], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-3 Identifier { ident: "run", suffixed: 0 }, @0-22 Apply(@0-22 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "nextMsg", suffixed: 0 }, @0-22 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @0-22 Apply(@0-22 Var { module_name: "", ident: "line", suffixed: 0 }, [@13-21 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], Space))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-22], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-3 Identifier { ident: "run", suffixed: 0 }, @0-22 Apply(@0-22 Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "nextMsg" }, @0-22 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @0-22 Apply(@0-22 Var { module_name: "", ident: "line" }, [@13-21 ParensAround(Var { module_name: "", ident: "#!a0" })], Space))], BangSuffix))] }"##, ); } @@ -465,7 +465,7 @@ mod suffixed_tests { z = foo! (bar! baz) (blah stuff) doSomething z "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-86], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "bar", suffixed: 0 }, [@39-42 Var { module_name: "", ident: "baz", suffixed: 0 }], Space), @28-56 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@28-56 Apply(@28-56 Var { module_name: "", ident: "foo", suffixed: 0 }, [@34-42 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 }), @45-55 ParensAround(Apply(@45-49 Var { module_name: "", ident: "blah", suffixed: 0 }, [@50-55 Var { module_name: "", ident: "stuff", suffixed: 0 }], Space))], Space), @28-56 Closure([@24-25 Identifier { ident: "z", suffixed: 0 }], @73-86 Apply(@73-84 Var { module_name: "", ident: "doSomething", suffixed: 0 }, [@85-86 Var { module_name: "", ident: "z", suffixed: 0 }], Space))], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-86], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "bar" }, [@39-42 Var { module_name: "", ident: "baz" }], Space), @28-56 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await" }, [@28-56 Apply(@28-56 Var { module_name: "", ident: "foo" }, [@34-42 ParensAround(Var { module_name: "", ident: "#!a0" }), @45-55 ParensAround(Apply(@45-49 Var { module_name: "", ident: "blah" }, [@50-55 Var { module_name: "", ident: "stuff" }], Space))], Space), @28-56 Closure([@24-25 Identifier { ident: "z", suffixed: 0 }], @73-86 Apply(@73-84 Var { module_name: "", ident: "doSomething" }, [@85-86 Var { module_name: "", ident: "z" }], Space))], BangSuffix))], BangSuffix))] }"##, ); } @@ -514,7 +514,7 @@ mod suffixed_tests { foo "bar" {} "baz" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-249], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @25-249 Defs(Defs { tags: [Index(2147483650)], regions: [@81-193], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@25-28 Identifier { ident: "foo", suffixed: 0 }, @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])]))), AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @114-193 Defs(Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@119-121, @142-149], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@119-121 RecordDestructure([]), @119-121 Apply(@114-118 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@120-121 Var { module_name: "", ident: "a", suffixed: 0 }], Space)), Body(@142-149 RecordDestructure([]), @142-149 Apply(@142-146 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@148-149 Var { module_name: "", ident: "b", suffixed: 0 }], Space))] }, @183-193 Apply(@183-190 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@191-193 Record([])], Space))) }, AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @119-121 Apply(@119-121 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@119-121 Apply(@119-121 Var { module_name: "", ident: "line", suffixed: 0 }, [@120-121 Var { module_name: "", ident: "a", suffixed: 0 }], Space), @119-121 Closure([@119-121 RecordDestructure([])], @142-149 Apply(@142-149 Var { module_name: "", ident: "line", suffixed: 0 }, [@148-149 Var { module_name: "", ident: "b", suffixed: 0 }], Space))], BangSuffix)) }] }, @231-249 Apply(@231-234 Var { module_name: "", ident: "foo", suffixed: 0 }, [@235-240 Str(PlainLine("bar")), @241-243 Record([]), @244-249 Str(PlainLine("baz"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-249], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @25-249 Defs(Defs { tags: [Index(2147483650)], regions: [@81-193], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@25-28 Identifier { ident: "foo", suffixed: 0 }, @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])]))), AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @114-193 Defs(Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@119-121, @142-149], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@119-121 RecordDestructure([]), @119-121 Apply(@114-118 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@120-121 Var { module_name: "", ident: "a" }], Space)), Body(@142-149 RecordDestructure([]), @142-149 Apply(@142-146 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@148-149 Var { module_name: "", ident: "b" }], Space))] }, @183-193 Apply(@183-190 Var { module_name: "Task", ident: "ok" }, [@191-193 Record([])], Space))) }, AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @119-121 Apply(@119-121 Var { module_name: "Task", ident: "await" }, [@119-121 Apply(@119-121 Var { module_name: "", ident: "line" }, [@120-121 Var { module_name: "", ident: "a" }], Space), @119-121 Closure([@119-121 RecordDestructure([])], @142-149 Apply(@142-149 Var { module_name: "", ident: "line" }, [@148-149 Var { module_name: "", ident: "b" }], Space))], BangSuffix)) }] }, @231-249 Apply(@231-234 Var { module_name: "", ident: "foo" }, [@235-240 Str(PlainLine("bar")), @241-243 Record([]), @244-249 Str(PlainLine("baz"))], Space)))] }"#, ); } @@ -562,7 +562,7 @@ mod suffixed_tests { b = "Bar" Stdout.line b "#, - r#"Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@0-90, @120-186], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 2)], space_after: [Slice(start = 0, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-90 Defs(Defs { tags: [Index(2147483649)], regions: [@27-32], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "a", suffixed: 0 }, @27-32 Str(PlainLine("Foo"))), Body(@23-24 Identifier { ident: "a", suffixed: 0 }, @27-32 Str(PlainLine("Foo")))] }, @23-90 Apply(@23-90 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@49-63 Apply(@49-63 Var { module_name: "Stdout", ident: "line", suffixed: 0 }, [@62-63 Var { module_name: "", ident: "a", suffixed: 0 }], Space), @23-90 Closure([@49-63 RecordDestructure([])], @81-90 Var { module_name: "", ident: "printBar", suffixed: 0 })], BangSuffix))), Body(@120-128 Identifier { ident: "printBar", suffixed: 0 }, @147-186 Defs(Defs { tags: [Index(2147483649)], regions: [@151-156], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@147-148 Identifier { ident: "b", suffixed: 0 }, @151-156 Str(PlainLine("Bar"))), Body(@147-148 Identifier { ident: "b", suffixed: 0 }, @151-156 Str(PlainLine("Bar")))] }, @173-186 Apply(@173-184 Var { module_name: "Stdout", ident: "line", suffixed: 0 }, [@185-186 Var { module_name: "", ident: "b", suffixed: 0 }], Space)))] }"#, + r#"Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@0-90, @120-186], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 2)], space_after: [Slice(start = 0, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-90 Defs(Defs { tags: [Index(2147483649)], regions: [@27-32], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "a", suffixed: 0 }, @27-32 Str(PlainLine("Foo"))), Body(@23-24 Identifier { ident: "a", suffixed: 0 }, @27-32 Str(PlainLine("Foo")))] }, @23-90 Apply(@23-90 Var { module_name: "Task", ident: "await" }, [@49-63 Apply(@49-63 Var { module_name: "Stdout", ident: "line" }, [@62-63 Var { module_name: "", ident: "a" }], Space), @23-90 Closure([@49-63 RecordDestructure([])], @81-90 Var { module_name: "", ident: "printBar" })], BangSuffix))), Body(@120-128 Identifier { ident: "printBar", suffixed: 0 }, @147-186 Defs(Defs { tags: [Index(2147483649)], regions: [@151-156], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@147-148 Identifier { ident: "b", suffixed: 0 }, @151-156 Str(PlainLine("Bar"))), Body(@147-148 Identifier { ident: "b", suffixed: 0 }, @151-156 Str(PlainLine("Bar")))] }, @173-186 Apply(@173-184 Var { module_name: "Stdout", ident: "line" }, [@185-186 Var { module_name: "", ident: "b" }], Space)))] }"#, ); } @@ -610,7 +610,7 @@ mod suffixed_tests { else line "fail" "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-286], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-286 Defs(Defs { tags: [Index(2147483650), Index(2147483651)], regions: [@32-49, @76-94], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0)], spaces: [Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-73 Identifier { ident: "isFalse", suffixed: 0 }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@84-94 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space)), Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-73 Identifier { ident: "isFalse", suffixed: 0 }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@84-94 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space))] }, @115-123 Apply(@115-123 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@115-123 Var { module_name: "", ident: "isFalse", suffixed: 0 }, @115-123 Closure([@115-123 Identifier { ident: "#!a0", suffixed: 0 }], @112-286 If([(@115-123 Var { module_name: "", ident: "#!a0", suffixed: 0 }, @149-160 Apply(@149-153 Var { module_name: "", ident: "line", suffixed: 0 }, [@154-160 Str(PlainLine("fail"))], Space))], @185-192 Apply(@185-192 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@185-192 Var { module_name: "", ident: "isTrue", suffixed: 0 }, @185-192 Closure([@185-192 Identifier { ident: "#!a1", suffixed: 0 }], @112-286 If([(@185-192 Var { module_name: "", ident: "#!a1", suffixed: 0 }, @219-233 Apply(@219-223 Var { module_name: "", ident: "line", suffixed: 0 }, [@224-233 Str(PlainLine("success"))], Space))], @275-286 Apply(@275-279 Var { module_name: "", ident: "line", suffixed: 0 }, [@280-286 Str(PlainLine("fail"))], Space)))], BangSuffix)))], BangSuffix)))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-286], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-286 Defs(Defs { tags: [Index(2147483650), Index(2147483651)], regions: [@32-49, @76-94], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0)], spaces: [Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-73 Identifier { ident: "isFalse", suffixed: 0 }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok" }, [@84-94 Var { module_name: "Bool", ident: "false" }], Space)), Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-73 Identifier { ident: "isFalse", suffixed: 0 }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok" }, [@84-94 Var { module_name: "Bool", ident: "false" }], Space))] }, @115-123 Apply(@115-123 Var { module_name: "Task", ident: "await" }, [@115-123 Var { module_name: "", ident: "isFalse" }, @115-123 Closure([@115-123 Identifier { ident: "#!a0", suffixed: 0 }], @112-286 If([(@115-123 Var { module_name: "", ident: "#!a0" }, @149-160 Apply(@149-153 Var { module_name: "", ident: "line" }, [@154-160 Str(PlainLine("fail"))], Space))], @185-192 Apply(@185-192 Var { module_name: "Task", ident: "await" }, [@185-192 Var { module_name: "", ident: "isTrue" }, @185-192 Closure([@185-192 Identifier { ident: "#!a1", suffixed: 0 }], @112-286 If([(@185-192 Var { module_name: "", ident: "#!a1" }, @219-233 Apply(@219-223 Var { module_name: "", ident: "line" }, [@224-233 Str(PlainLine("success"))], Space))], @275-286 Apply(@275-279 Var { module_name: "", ident: "line" }, [@280-286 Str(PlainLine("fail"))], Space)))], BangSuffix)))], BangSuffix)))] }"##, ); } @@ -650,7 +650,7 @@ mod suffixed_tests { msg "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "isTrue", suffixed: 0 }))], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-217 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-294 TaskAwaitBang(Var { module_name: "", ident: "isFalsey", suffixed: 0 }), [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-342 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-434 TaskAwaitBang(Var { module_name: "", ident: "line", suffixed: 0 }), [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@40-49 Var { module_name: "Bool", ident: "true", suffixed: 0 }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@91-92 Var { module_name: "", ident: "x", suffixed: 0 }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Var { module_name: "", ident: "isTrue", suffixed: 0 }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not", suffixed: 0 }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0", suffixed: 0 })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line", suffixed: 0 }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err", suffixed: 0 }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await", suffixed: 0 }, [Apply(Var { module_name: "", ident: "isFalsey", suffixed: 0 }, [@296-306 Var { module_name: "Bool", ident: "false", suffixed: 0 }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1", suffixed: 0 }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line", suffixed: 0 }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok", suffixed: 0 }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "", ident: "line", suffixed: 0 }, [@436-445 Str(PlainLine("success"))], Space)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg", suffixed: 0 }))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok" }, [@91-92 Var { module_name: "", ident: "x" }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not" }, [@175-182 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "isTrue" }))], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-217 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err" }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-294 TaskAwaitBang(Var { module_name: "", ident: "isFalsey" }), [@296-306 Var { module_name: "Bool", ident: "false" }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-342 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok" }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-434 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok" }, [@91-92 Var { module_name: "", ident: "x" }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "isTrue" }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not" }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0" })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await" }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line" }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err" }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "isFalsey" }, [@296-306 Var { module_name: "Bool", ident: "false" }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1" }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await" }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line" }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok" }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "", ident: "line" }, [@436-445 Str(PlainLine("success"))], Space)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg" }))] }"##, ); } @@ -681,7 +681,7 @@ mod suffixed_tests { CMD.new "cp" |> mapErr! ERR "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-103], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "copy", suffixed: 0 }, @7-103 Closure([@8-9 Identifier { ident: "a", suffixed: 0 }, @10-11 Identifier { ident: "b", suffixed: 0 }], @36-42 Apply(@36-42 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@36-42 Apply(@36-42 Var { module_name: "", ident: "line", suffixed: 0 }, [@37-42 Str(PlainLine("FOO"))], Space), @36-42 Closure([@36-42 RecordDestructure([])], @60-103 Apply(@60-103 Var { module_name: "", ident: "mapErr", suffixed: 0 }, [@60-72 Apply(@60-67 Var { module_name: "CMD", ident: "new", suffixed: 0 }, [@68-72 Str(PlainLine("cp"))], Space), @100-103 Tag("ERR")], BinOp(Pizza)))], BangSuffix)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-103], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "copy", suffixed: 0 }, @7-103 Closure([@8-9 Identifier { ident: "a", suffixed: 0 }, @10-11 Identifier { ident: "b", suffixed: 0 }], @36-42 Apply(@36-42 Var { module_name: "Task", ident: "await" }, [@36-42 Apply(@36-42 Var { module_name: "", ident: "line" }, [@37-42 Str(PlainLine("FOO"))], Space), @36-42 Closure([@36-42 RecordDestructure([])], @60-103 Apply(@60-103 Var { module_name: "", ident: "mapErr" }, [@60-72 Apply(@60-67 Var { module_name: "CMD", ident: "new" }, [@68-72 Str(PlainLine("cp"))], Space), @100-103 Tag("ERR")], BinOp(Pizza)))], BangSuffix)))] }"#, ); } @@ -709,7 +709,7 @@ mod suffixed_tests { [] -> "empty" _ -> "non-empty" "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-111 Apply(@0-111 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @0-111 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-111 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-111 Apply(@0-111 Var { module_name: "Task", ident: "await" }, [@29-37 Var { module_name: "", ident: "getList" }, @0-111 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-111 When(@29-37 Var { module_name: "", ident: "#!a0" }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, ); } @@ -754,7 +754,7 @@ mod suffixed_tests { _ -> ok {} "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-195 Apply(@0-195 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@29-37 Var { module_name: "", ident: "getList", suffixed: 0 }, @0-195 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-195 When(@29-37 Var { module_name: "", ident: "#!a0", suffixed: 0 }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line", suffixed: 0 }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line", suffixed: 0 }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok", suffixed: 0 }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-195 Apply(@0-195 Var { module_name: "Task", ident: "await" }, [@29-37 Var { module_name: "", ident: "getList" }, @0-195 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-195 When(@29-37 Var { module_name: "", ident: "#!a0" }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await" }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line" }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line" }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok" }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, ); } diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs index 72996d8e17..619375fd1a 100644 --- a/crates/compiler/fmt/src/expr.rs +++ b/crates/compiler/fmt/src/expr.rs @@ -172,11 +172,7 @@ impl<'a> Formattable for Expr<'a> { Str(literal) => { fmt_str_literal(buf, *literal, indent); } - Var { - module_name, - ident, - suffixed, - } => { + Var { module_name, ident } => { buf.indent(indent); if !module_name.is_empty() { buf.push_str(module_name); @@ -184,11 +180,6 @@ impl<'a> Formattable for Expr<'a> { } buf.push_str(ident); - - let count: u8 = *suffixed; - for _ in 0..count { - buf.push('!'); - } } Underscore(name) => { buf.indent(indent); diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index af21f85c08..2b43a915ce 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -695,15 +695,7 @@ impl<'a> RemoveSpaces<'a> for Expr<'a> { Expr::Record(a) => Expr::Record(a.remove_spaces(arena)), Expr::RecordBuilder(a) => Expr::RecordBuilder(a.remove_spaces(arena)), Expr::Tuple(a) => Expr::Tuple(a.remove_spaces(arena)), - Expr::Var { - module_name, - ident, - suffixed, - } => Expr::Var { - module_name, - ident, - suffixed, - }, + Expr::Var { module_name, ident } => Expr::Var { module_name, ident }, Expr::Underscore(a) => Expr::Underscore(a), Expr::Tag(a) => Expr::Tag(a), Expr::OpaqueRef(a) => Expr::OpaqueRef(a), diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 71a03f1f10..191717108b 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -9,7 +9,6 @@ use bumpalo::Bump; use roc_collections::soa::{EitherIndex, Index, Slice}; use roc_error_macros::internal_error; use roc_module::called_via::{BinOp, CalledVia, UnaryOp}; -use roc_module::ident::ModuleName; use roc_region::all::{Loc, Position, Region}; #[derive(Debug, Clone, PartialEq, Eq)] @@ -291,7 +290,6 @@ pub enum Expr<'a> { Var { module_name: &'a str, // module_name will only be filled if the original Roc code stated something like `5 + SomeModule.myVar`, module_name will be blank if it was `5 + myVar` ident: &'a str, - suffixed: u8, // how many `!` suffixes, for example `doTheThing!!` executes a Task that returns a Task }, Underscore(&'a str), @@ -358,17 +356,6 @@ pub enum Expr<'a> { } impl Expr<'_> { - pub fn increment_var_suffix(&mut self, count: u8) { - match self { - Expr::Var { suffixed, .. } => { - *suffixed += count; - } - _ => { - internal_error!("increment_var_suffix called on non-Var expression"); - } - } - } - pub fn get_region_spanning_binops(&self) -> Region { match self { Expr::BinOps(firsts, last) => { @@ -398,7 +385,7 @@ pub fn split_loc_exprs_around<'a>( pub fn is_expr_suffixed(expr: &Expr) -> bool { match expr { // expression without arguments, `read!` - Expr::Var { suffixed, .. } => false, + Expr::Var { .. } => false, Expr::TaskAwaitBang(..) => true, @@ -449,11 +436,7 @@ pub fn is_expr_suffixed(expr: &Expr) -> bool { } Expr::Float(_) => false, Expr::Num(_) => false, - Expr::NonBase10Int { - string, - base, - is_negative, - } => false, + Expr::NonBase10Int { .. } => false, Expr::Str(_) => false, Expr::SingleQuote(_) => false, Expr::RecordAccess(a, _) => is_expr_suffixed(a), @@ -1684,13 +1667,11 @@ impl<'a> Expr<'a> { pub const REPL_OPAQUE_FUNCTION: Self = Expr::Var { module_name: "", ident: "", - suffixed: 0, }; pub const REPL_RUNTIME_CRASH: Self = Expr::Var { module_name: "", ident: "*", - suffixed: 0, }; pub fn loc_ref(&'a self, region: Region) -> Loc<&'a Self> { diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index e8f4703823..ddb88309bf 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -244,7 +244,7 @@ fn parse_ident_seq<'a>( state: State<'a>, min_indent: u32, ) -> ParseResult<'a, Loc>, EExpr<'a>> { - let (p, loc_ident, state) = + let (_, loc_ident, state) = loc!(assign_or_destructure_identifier()).parse(arena, state, min_indent)?; let expr = ident_to_expr(arena, loc_ident.value); let (_p, suffixes, state) = record_field_access_chain() @@ -2184,18 +2184,14 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result { + Expr::Var { module_name, ident } => { if module_name.is_empty() { - Pattern::Identifier { ident, suffixed } + Pattern::Identifier { ident, suffixed: 0 } } else { Pattern::QualifiedIdentifier { module_name, ident, - suffixed, + suffixed: 0, } } } @@ -2830,18 +2826,14 @@ fn ident_to_expr<'a>(arena: &'a Bump, src: Ident<'a>) -> Expr<'a> { Ident::Access { module_name, parts, - suffixed, + suffixed: _, } => { let mut iter = parts.iter(); // The first value in the iterator is the variable name, // e.g. `foo` in `foo.bar.baz` let mut answer = match iter.next() { - Some(Accessor::RecordField(ident)) => Expr::Var { - module_name, - ident, - suffixed, - }, + Some(Accessor::RecordField(ident)) => Expr::Var { module_name, ident }, Some(Accessor::TupleIndex(_)) => { // TODO: make this state impossible to represent in Ident::Access, // by splitting out parts[0] into a separate field with a type of `&'a str`, diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index 65319495c5..8e41b42b93 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -51,12 +51,12 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> let pattern_state = state.clone(); // Return early with the suffixed statement - match pattern.value { - Pattern::Identifier { suffixed, .. } if suffixed > 0 => { - return Ok((MadeProgress, pattern, pattern_state)) - } - _ => {} - } + // match pattern.value { + // Pattern::Identifier { .. } if suffixed > 0 => { + // return Ok((MadeProgress, pattern, pattern_state)) + // } + // _ => {} + // } let (pattern_spaces, state) = match space0_e(EPattern::AsKeyword).parse(arena, state, min_indent) { @@ -408,7 +408,7 @@ fn loc_ident_pattern_help<'a>( region: loc_ident.region, value: Pattern::Identifier { ident: var, - suffixed, + suffixed: 0, }, }, state, @@ -424,7 +424,7 @@ fn loc_ident_pattern_help<'a>( value: Pattern::QualifiedIdentifier { module_name, ident: var, - suffixed, + suffixed: 0, }, }, state, diff --git a/crates/compiler/parse/tests/test_parse.rs b/crates/compiler/parse/tests/test_parse.rs index 8019a8a772..93e92728aa 100644 --- a/crates/compiler/parse/tests/test_parse.rs +++ b/crates/compiler/parse/tests/test_parse.rs @@ -175,7 +175,6 @@ mod test_parse { let expr = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); bumpalo::vec![in arena; @@ -192,7 +191,6 @@ mod test_parse { let expr = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); bumpalo::vec![in arena; @@ -238,7 +236,6 @@ mod test_parse { let expr = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); bumpalo::vec![in arena; @@ -254,13 +251,11 @@ mod test_parse { let expr1 = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); let expr2 = arena.alloc(Var { module_name: "", ident: "project", - suffixed: 0, }); bumpalo::vec![in arena; @@ -281,13 +276,11 @@ mod test_parse { let expr1 = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); let expr2 = arena.alloc(Var { module_name: "", ident: "project", - suffixed: 0, }); bumpalo::vec![in arena; diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs index 4cefbbe3dc..37db6e2042 100644 --- a/crates/compiler/test_syntax/tests/test_snapshots.rs +++ b/crates/compiler/test_syntax/tests/test_snapshots.rs @@ -741,7 +741,6 @@ mod test_snapshots { let expr = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); bumpalo::vec![in arena; @@ -758,7 +757,6 @@ mod test_snapshots { let expr = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); bumpalo::vec![in arena; @@ -774,7 +772,6 @@ mod test_snapshots { let expr = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); bumpalo::vec![in arena; @@ -790,13 +787,11 @@ mod test_snapshots { let expr1 = arena.alloc(Var { module_name: "", ident: "name", - suffixed: 0, }); let expr2 = arena.alloc(Var { module_name: "", ident: "project", - suffixed: 0, }); bumpalo::vec![in arena; diff --git a/crates/repl_eval/src/eval.rs b/crates/repl_eval/src/eval.rs index b911abd9f1..79964cc538 100644 --- a/crates/repl_eval/src/eval.rs +++ b/crates/repl_eval/src/eval.rs @@ -791,7 +791,6 @@ fn addr_to_ast<'a, M: ReplAppMemory>( let box_box = env.arena.alloc(Loc::at_zero(Expr::Var { module_name: "Box", ident: "box", - suffixed: 0, })); let box_box_arg = &*env.arena.alloc(Loc::at_zero(inner_expr)); let box_box_args = env.arena.alloc([box_box_arg]); @@ -1355,7 +1354,6 @@ fn bool_to_ast<'a>(env: &Env<'a, '_>, value: bool, content: &Content) -> Expr<'a Alias(Symbol::BOOL_BOOL, _, _, _) => Expr::Var { module_name: "Bool", ident: if value { "true" } else { "false" }, - suffixed: 0, }, Alias(_, _, var, _) => { let content = env.subs.get_content_without_compacting(*var); From db4607125b97fd5454be7c7bf31ecc8e9e4a7f73 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sat, 27 Apr 2024 13:20:51 +1000 Subject: [PATCH 56/72] remove suffixed from Pattern --- crates/compiler/can/src/derive.rs | 54 ++++---------------- crates/compiler/can/src/desugar.rs | 5 +- crates/compiler/can/src/pattern.rs | 23 +++------ crates/compiler/can/src/suffixed.rs | 13 ----- crates/compiler/can/tests/test_suffixed.rs | 44 ++++++++-------- crates/compiler/fmt/src/pattern.rs | 19 +------ crates/compiler/fmt/src/spaces.rs | 14 ++--- crates/compiler/load_internal/src/docs.rs | 38 +++----------- crates/compiler/load_internal/src/file.rs | 8 +-- crates/compiler/parse/src/ast.rs | 31 ++--------- crates/compiler/parse/src/expr.rs | 13 ++--- crates/compiler/parse/src/pattern.rs | 24 ++------- crates/compiler/parse/src/type_annotation.rs | 8 +-- crates/repl_ui/src/repl_state.rs | 6 +-- 14 files changed, 69 insertions(+), 231 deletions(-) diff --git a/crates/compiler/can/src/derive.rs b/crates/compiler/can/src/derive.rs index 6250ee4af4..8e45c06146 100644 --- a/crates/compiler/can/src/derive.rs +++ b/crates/compiler/can/src/derive.rs @@ -25,10 +25,7 @@ fn to_encoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { opaque_ref, &*env.arena.alloc([Loc::at( DERIVED_REGION, - ast::Pattern::Identifier { - ident: payload, - suffixed: 0, - }, + ast::Pattern::Identifier { ident: payload }, )]), ); @@ -100,20 +97,8 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { // Decode.mapResult (Decode.decodeWith bytes Decode.decoder fmt) @Opaq let custom_closure = ast::Expr::Closure( env.arena.alloc([ - Loc::at( - DERIVED_REGION, - ast::Pattern::Identifier { - ident: bytes, - suffixed: 0, - }, - ), - Loc::at( - DERIVED_REGION, - ast::Pattern::Identifier { - ident: fmt, - suffixed: 0, - }, - ), + Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: bytes }), + Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: fmt }), ]), alloc_expr(call_map_result), ); @@ -145,10 +130,7 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { opaque_ref, &*env.arena.alloc([Loc::at( DERIVED_REGION, - ast::Pattern::Identifier { - ident: payload, - suffixed: 0, - }, + ast::Pattern::Identifier { ident: payload }, )]), ); @@ -174,13 +156,7 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { // \hasher, @Opaq payload -> Hash.hash hasher payload ast::Expr::Closure( env.arena.alloc([ - Loc::at( - DERIVED_REGION, - ast::Pattern::Identifier { - ident: hasher, - suffixed: 0, - }, - ), + Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: hasher }), Loc::at(DERIVED_REGION, opaque_apply_pattern), ]), call_member, @@ -200,10 +176,7 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { opaque_ref, &*env.arena.alloc([Loc::at( DERIVED_REGION, - ast::Pattern::Identifier { - ident: payload1, - suffixed: 0, - }, + ast::Pattern::Identifier { ident: payload1 }, )]), ); // \@Opaq payload2 @@ -211,10 +184,7 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { opaque_ref, &*env.arena.alloc([Loc::at( DERIVED_REGION, - ast::Pattern::Identifier { - ident: payload2, - suffixed: 0, - }, + ast::Pattern::Identifier { ident: payload2 }, )]), ); @@ -260,10 +230,7 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { opaque_ref, &*env.arena.alloc([Loc::at( DERIVED_REGION, - ast::Pattern::Identifier { - ident: payload, - suffixed: 0, - }, + ast::Pattern::Identifier { ident: payload }, )]), ); @@ -316,10 +283,7 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> { let custom_closure = alloc_expr(ast::Expr::Closure( env.arena.alloc([Loc::at( DERIVED_REGION, - ast::Pattern::Identifier { - ident: fmt, - suffixed: 0, - }, + ast::Pattern::Identifier { ident: fmt }, )]), apply_opaque_inspector, )); diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index 3b2ff618d0..744eed0119 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -1069,10 +1069,7 @@ fn record_builder_arg<'a>( for label in apply_field_names.iter().rev() { let name = arena.alloc("#".to_owned() + label.value); - let ident = roc_parse::ast::Pattern::Identifier { - ident: name, - suffixed: 0, - }; + let ident = roc_parse::ast::Pattern::Identifier { ident: name }; let arg_pattern = arena.alloc(Loc { value: ident, diff --git a/crates/compiler/can/src/pattern.rs b/crates/compiler/can/src/pattern.rs index fa02da81ee..d056e2b59c 100644 --- a/crates/compiler/can/src/pattern.rs +++ b/crates/compiler/can/src/pattern.rs @@ -265,10 +265,7 @@ pub fn canonicalize_def_header_pattern<'a>( match pattern { // Identifiers that shadow ability members may appear (and may only appear) at the header of a def. - Identifier { - ident: name, - suffixed: _, - } => { + Identifier { ident: name } => { match scope.introduce_or_shadow_ability_member( pending_abilities_in_scope, (*name).into(), @@ -376,13 +373,12 @@ pub fn canonicalize_pattern<'a>( use PatternType::*; let can_pattern = match pattern { - Identifier { - ident: name, - suffixed: _, - } => match canonicalize_pattern_symbol(env, scope, output, region, permit_shadows, name) { - Ok(symbol) => Pattern::Identifier(symbol), - Err(pattern) => pattern, - }, + Identifier { ident: name } => { + match canonicalize_pattern_symbol(env, scope, output, region, permit_shadows, name) { + Ok(symbol) => Pattern::Identifier(symbol), + Err(pattern) => pattern, + } + } Underscore(name) => { // An underscored identifier can't be used, but we'll still add it to the scope // for better error messages if someone tries to use it. @@ -632,10 +628,7 @@ pub fn canonicalize_pattern<'a>( for loc_pattern in patterns.iter() { match loc_pattern.value { - Identifier { - ident: label, - suffixed: _, - } => { + Identifier { ident: label } => { match scope.introduce(label.into(), region) { Ok(symbol) => { output.references.insert_bound(symbol); diff --git a/crates/compiler/can/src/suffixed.rs b/crates/compiler/can/src/suffixed.rs index 9de32b71c3..addf4da4bd 100644 --- a/crates/compiler/can/src/suffixed.rs +++ b/crates/compiler/can/src/suffixed.rs @@ -34,7 +34,6 @@ fn next_suffixed_answer_pattern(arena: &Bump) -> (Expr, Pattern) { }, Pattern::Identifier { ident: answer_ident.as_str(), - suffixed: 0, }, ) }) @@ -194,18 +193,6 @@ pub fn unwrap_suffixed_expression_closure_help<'a>( ) -> Result<&'a Loc>, EUnwrapped<'a>> { match loc_expr.value { Expr::Closure(closure_args, closure_loc_ret) => { - - // Check to make sure that arguments are not suffixed - let suffixed_arg_count = closure_args - .iter() - .filter(|loc_pat| loc_pat.value.is_suffixed()) - .count(); - - if suffixed_arg_count > 0 { - debug_assert!(false,"closure arguments should not be suffixed"); - return Err(EUnwrapped::Malformed); - } - // note we use `None` here as we don't want to pass a DefExpr up and // unwrap the definition pattern for the closure match unwrap_suffixed_expression(arena, closure_loc_ret, None) { diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index 0a6024cf66..61e0508fa1 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -46,7 +46,7 @@ mod suffixed_tests { Task.ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-125], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @29-36 Apply(@29-36 Var { module_name: "Task", ident: "await" }, [@29-36 Apply(@29-36 Var { module_name: "", ident: "line" }, [@30-36 Str(PlainLine("Ahoy"))], Space), @29-36 Closure([@29-36 RecordDestructure([])], @58-80 Apply(@58-80 Var { module_name: "Stdout", ident: "line" }, [@58-65 Str(PlainLine("There"))], BinOp(Pizza)))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-125], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @29-36 Apply(@29-36 Var { module_name: "Task", ident: "await" }, [@29-36 Apply(@29-36 Var { module_name: "", ident: "line" }, [@30-36 Str(PlainLine("Ahoy"))], Space), @29-36 Closure([@29-36 RecordDestructure([])], @58-80 Apply(@58-80 Var { module_name: "Stdout", ident: "line" }, [@58-65 Str(PlainLine("There"))], BinOp(Pizza)))], BangSuffix))] }"#, ); } @@ -74,7 +74,7 @@ mod suffixed_tests { ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-24 Apply(@24-24 Var { module_name: "Task", ident: "await" }, [@24-24 Var { module_name: "", ident: "foo" }, @24-24 Closure([@24-24 RecordDestructure([])], @42-47 Apply(@42-44 Var { module_name: "", ident: "ok" }, [@45-47 Record([])], Space))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @24-24 Apply(@24-24 Var { module_name: "Task", ident: "await" }, [@24-24 Var { module_name: "", ident: "foo" }, @24-24 Closure([@24-24 RecordDestructure([])], @42-47 Apply(@42-44 Var { module_name: "", ident: "ok" }, [@45-47 Record([])], Space))], BangSuffix))] }"#, ); } @@ -93,7 +93,7 @@ mod suffixed_tests { r#" main = foo! "bar" {} "baz" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-26], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-26 Apply(@0-26 Var { module_name: "", ident: "foo" }, [@12-17 Str(PlainLine("bar")), @18-20 Record([]), @21-26 Str(PlainLine("baz"))], Space))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-26], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @0-26 Apply(@0-26 Var { module_name: "", ident: "foo" }, [@12-17 Str(PlainLine("bar")), @18-20 Record([]), @21-26 Str(PlainLine("baz"))], Space))] }"#, ); } @@ -127,7 +127,7 @@ mod suffixed_tests { bar! baz! "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-28 Apply(@28-28 Var { module_name: "Task", ident: "await" }, [@28-28 Var { module_name: "", ident: "foo" }, @28-28 Closure([@28-28 RecordDestructure([])], @45-49 Apply(@45-49 Var { module_name: "Task", ident: "await" }, [@45-49 Var { module_name: "", ident: "bar" }, @45-49 Closure([@45-49 RecordDestructure([])], @66-70 Var { module_name: "", ident: "baz" })], BangSuffix))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @28-28 Apply(@28-28 Var { module_name: "Task", ident: "await" }, [@28-28 Var { module_name: "", ident: "foo" }, @28-28 Closure([@28-28 RecordDestructure([])], @45-49 Apply(@45-49 Var { module_name: "Task", ident: "await" }, [@45-49 Var { module_name: "", ident: "bar" }, @45-49 Closure([@45-49 RecordDestructure([])], @66-70 Var { module_name: "", ident: "baz" })], BangSuffix))], BangSuffix))] }"#, ); } @@ -161,7 +161,7 @@ mod suffixed_tests { x "hi" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-118], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-118 Defs(Defs { tags: [Index(2147483649)], regions: [@27-94], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-94 Defs(Defs { tags: [Index(2147483648)], regions: [@55-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@55-66 RecordDestructure([]), @55-66 Apply(@62-66 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@55-58 Var { module_name: "", ident: "msg" }], BinOp(Pizza)))] }, @89-94 Apply(@89-91 Var { module_name: "", ident: "ok" }, [@92-94 Record([])], Space)))), Body(@23-24 Identifier { ident: "x", suffixed: 0 }, @27-94 Closure([@28-31 Identifier { ident: "msg", suffixed: 0 }], @55-66 Apply(@55-66 Var { module_name: "Task", ident: "await" }, [@55-66 Apply(@55-66 Var { module_name: "", ident: "line" }, [@55-58 Var { module_name: "", ident: "msg" }], BinOp(Pizza)), @55-66 Closure([@55-66 RecordDestructure([])], @89-94 Apply(@89-91 Var { module_name: "", ident: "ok" }, [@92-94 Record([])], Space))], BangSuffix)))] }, @112-118 Apply(@112-113 Var { module_name: "", ident: "x" }, [@114-118 Str(PlainLine("hi"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-118], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @23-118 Defs(Defs { tags: [Index(2147483649)], regions: [@27-94], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "x" }, @27-94 Closure([@28-31 Identifier { ident: "msg" }], @55-94 Defs(Defs { tags: [Index(2147483648)], regions: [@55-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@55-66 RecordDestructure([]), @55-66 Apply(@62-66 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@55-58 Var { module_name: "", ident: "msg" }], BinOp(Pizza)))] }, @89-94 Apply(@89-91 Var { module_name: "", ident: "ok" }, [@92-94 Record([])], Space)))), Body(@23-24 Identifier { ident: "x" }, @27-94 Closure([@28-31 Identifier { ident: "msg" }], @55-66 Apply(@55-66 Var { module_name: "Task", ident: "await" }, [@55-66 Apply(@55-66 Var { module_name: "", ident: "line" }, [@55-58 Var { module_name: "", ident: "msg" }], BinOp(Pizza)), @55-66 Closure([@55-66 RecordDestructure([])], @89-94 Apply(@89-91 Var { module_name: "", ident: "ok" }, [@92-94 Record([])], Space))], BangSuffix)))] }, @112-118 Apply(@112-113 Var { module_name: "", ident: "x" }, [@114-118 Str(PlainLine("hi"))], Space)))] }"#, ); } @@ -198,7 +198,7 @@ mod suffixed_tests { Task.ok {} "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-130], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-93 Apply(@24-93 Var { module_name: "", ident: "line" }, [@24-69 Apply(@51-61 Var { module_name: "Str", ident: "concat" }, [@24-31 Str(PlainLine("hello")), @62-69 Str(PlainLine("world"))], BinOp(Pizza))], BinOp(Pizza)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-130], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @24-93 Apply(@24-93 Var { module_name: "", ident: "line" }, [@24-69 Apply(@51-61 Var { module_name: "Str", ident: "concat" }, [@24-31 Str(PlainLine("hello")), @62-69 Str(PlainLine("world"))], BinOp(Pizza))], BinOp(Pizza)))] }"#, ); } @@ -228,7 +228,7 @@ mod suffixed_tests { do = (sayMultiple!) "hi" do "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-47 Apply(@28-47 Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "sayMultiple" }, @28-47 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-47 Defs(Defs { tags: [Index(2147483650)], regions: [@28-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "sayMultiple" })), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0" }), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do", suffixed: 0 }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0" }), [@43-47 Str(PlainLine("hi"))], Space))] }, @64-66 Var { module_name: "", ident: "do" }))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-66], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @28-47 Apply(@28-47 Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "sayMultiple" }, @28-47 Closure([Identifier { ident: "#!a0" }], @28-47 Defs(Defs { tags: [Index(2147483650)], regions: [@28-47], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-25 Identifier { ident: "do" }, @28-47 Apply(@29-41 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "sayMultiple" })), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do" }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0" }), [@43-47 Str(PlainLine("hi"))], Space)), Body(@23-25 Identifier { ident: "do" }, @28-47 Apply(@29-41 ParensAround(Var { module_name: "", ident: "#!a0" }), [@43-47 Str(PlainLine("hi"))], Space))] }, @64-66 Var { module_name: "", ident: "do" }))], BangSuffix))] }"##, ); } @@ -267,7 +267,7 @@ mod suffixed_tests { b = bar!! baz a b "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-81], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await" }, [@27-31 Var { module_name: "", ident: "foo" }, @27-31 Closure([@23-24 Identifier { ident: "a", suffixed: 0 }], @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await" }, [@48-57 Var { module_name: "", ident: "bar" }, @27-31 Closure([@48-57 Identifier { ident: "#!a0", suffixed: 0 }], @48-57 Apply(@48-57 Var { module_name: "Task", ident: "await" }, [@48-57 Var { module_name: "", ident: "#!a0" }, @48-57 Closure([@48-49 Identifier { ident: "b", suffixed: 0 }], @74-81 Apply(@74-77 Var { module_name: "", ident: "baz" }, [@78-79 Var { module_name: "", ident: "a" }, @80-81 Var { module_name: "", ident: "b" }], Space))], BangSuffix))], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-81], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await" }, [@27-31 Var { module_name: "", ident: "foo" }, @27-31 Closure([@23-24 Identifier { ident: "a" }], @27-31 Apply(@27-31 Var { module_name: "Task", ident: "await" }, [@48-57 Var { module_name: "", ident: "bar" }, @27-31 Closure([@48-57 Identifier { ident: "#!a0" }], @48-57 Apply(@48-57 Var { module_name: "Task", ident: "await" }, [@48-57 Var { module_name: "", ident: "#!a0" }, @48-57 Closure([@48-49 Identifier { ident: "b" }], @74-81 Apply(@74-77 Var { module_name: "", ident: "baz" }, [@78-79 Var { module_name: "", ident: "a" }, @80-81 Var { module_name: "", ident: "b" }], Space))], BangSuffix))], BangSuffix))], BangSuffix))] }"##, ); } @@ -299,7 +299,7 @@ mod suffixed_tests { foo!! bar "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-49], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @24-49 Apply(@24-49 Var { module_name: "Task", ident: "await" }, [@29-29 Var { module_name: "", ident: "foo" }, @24-49 Closure([@29-29 Identifier { ident: "#!a0", suffixed: 0 }], @29-29 Apply(@29-29 Var { module_name: "Task", ident: "await" }, [@29-29 Var { module_name: "", ident: "#!a0" }, @29-29 Closure([@29-29 RecordDestructure([])], @46-49 Var { module_name: "", ident: "bar" })], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-49], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @24-49 Apply(@24-49 Var { module_name: "Task", ident: "await" }, [@29-29 Var { module_name: "", ident: "foo" }, @24-49 Closure([@29-29 Identifier { ident: "#!a0" }], @29-29 Apply(@29-29 Var { module_name: "Task", ident: "await" }, [@29-29 Var { module_name: "", ident: "#!a0" }, @29-29 Closure([@29-29 RecordDestructure([])], @46-49 Var { module_name: "", ident: "bar" })], BangSuffix))], BangSuffix))] }"##, ); } @@ -324,7 +324,7 @@ mod suffixed_tests { x = (foo! "bar") "hello" baz x "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-48 Apply(@28-48 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "foo" }, [@34-39 Str(PlainLine("bar"))], Space), @28-48 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-48 Defs(Defs { tags: [Index(2147483650)], regions: [@28-48], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Apply(@29-32 TaskAwaitBang(Var { module_name: "", ident: "foo" }), [@34-39 Str(PlainLine("bar"))], Space)), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0" }), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0" }), [@41-48 Str(PlainLine("hello"))], Space))] }, @65-70 Apply(@65-68 Var { module_name: "", ident: "baz" }, [@69-70 Var { module_name: "", ident: "x" }], Space)))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-70], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @28-48 Apply(@28-48 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "foo" }, [@34-39 Str(PlainLine("bar"))], Space), @28-48 Closure([Identifier { ident: "#!a0" }], @28-48 Defs(Defs { tags: [Index(2147483650)], regions: [@28-48], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x" }, @28-48 Apply(@29-39 ParensAround(Apply(@29-32 TaskAwaitBang(Var { module_name: "", ident: "foo" }), [@34-39 Str(PlainLine("bar"))], Space)), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x" }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0" }), [@41-48 Str(PlainLine("hello"))], Space)), Body(@24-25 Identifier { ident: "x" }, @28-48 Apply(@29-39 ParensAround(Var { module_name: "", ident: "#!a0" }), [@41-48 Str(PlainLine("hello"))], Space))] }, @65-70 Apply(@65-68 Var { module_name: "", ident: "baz" }, [@69-70 Var { module_name: "", ident: "x" }], Space)))], BangSuffix))] }"##, ); } @@ -349,7 +349,7 @@ mod suffixed_tests { x = bar (foo! "hello") baz x "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-68], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-46 Apply(@28-46 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "foo" }, [@38-45 Str(PlainLine("hello"))], Space), @28-46 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-46 Defs(Defs { tags: [Index(2147483650)], regions: [@28-46], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Apply(@33-36 TaskAwaitBang(Var { module_name: "", ident: "foo" }), [@38-45 Str(PlainLine("hello"))], Space))], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0" })], Space)), Body(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0" })], Space))] }, @63-68 Apply(@63-66 Var { module_name: "", ident: "baz" }, [@67-68 Var { module_name: "", ident: "x" }], Space)))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-68], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @28-46 Apply(@28-46 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "foo" }, [@38-45 Str(PlainLine("hello"))], Space), @28-46 Closure([Identifier { ident: "#!a0" }], @28-46 Defs(Defs { tags: [Index(2147483650)], regions: [@28-46], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-25 Identifier { ident: "x" }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Apply(@33-36 TaskAwaitBang(Var { module_name: "", ident: "foo" }), [@38-45 Str(PlainLine("hello"))], Space))], Space)), Body(@24-25 Identifier { ident: "x" }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0" })], Space)), Body(@24-25 Identifier { ident: "x" }, @28-46 Apply(@28-31 Var { module_name: "", ident: "bar" }, [@33-45 ParensAround(Var { module_name: "", ident: "#!a0" })], Space))] }, @63-68 Apply(@63-66 Var { module_name: "", ident: "baz" }, [@67-68 Var { module_name: "", ident: "x" }], Space)))], BangSuffix))] }"##, ); } @@ -375,7 +375,7 @@ mod suffixed_tests { x = foo! msg bar x "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-88], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-88 Defs(Defs { tags: [Index(2147483649)], regions: [@30-37], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-27 Identifier { ident: "msg", suffixed: 0 }, @30-37 Str(PlainLine("hello"))), Body(@24-27 Identifier { ident: "msg", suffixed: 0 }, @30-37 Str(PlainLine("hello")))] }, @0-88 Apply(@0-88 Var { module_name: "Task", ident: "await" }, [@54-66 Apply(@54-66 Var { module_name: "", ident: "foo" }, [@63-66 Var { module_name: "", ident: "msg" }], Space), @0-88 Closure([@54-55 Identifier { ident: "x", suffixed: 0 }], @83-88 Apply(@83-86 Var { module_name: "", ident: "bar" }, [@87-88 Var { module_name: "", ident: "x" }], Space))], BangSuffix)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-88], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @0-88 Defs(Defs { tags: [Index(2147483649)], regions: [@30-37], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@24-27 Identifier { ident: "msg" }, @30-37 Str(PlainLine("hello"))), Body(@24-27 Identifier { ident: "msg" }, @30-37 Str(PlainLine("hello")))] }, @0-88 Apply(@0-88 Var { module_name: "Task", ident: "await" }, [@54-66 Apply(@54-66 Var { module_name: "", ident: "foo" }, [@63-66 Var { module_name: "", ident: "msg" }], Space), @0-88 Closure([@54-55 Identifier { ident: "x" }], @83-88 Apply(@83-86 Var { module_name: "", ident: "bar" }, [@87-88 Var { module_name: "", ident: "x" }], Space))], BangSuffix)))] }"#, ); } @@ -416,7 +416,7 @@ mod suffixed_tests { x "foo" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-187], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-187 Defs(Defs { tags: [Index(2147483650)], regions: [@60-162], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@24-25 Identifier { ident: "x", suffixed: 0 }, @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred]))), AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @93-162 Defs(Defs { tags: [Index(2147483649)], regions: [@93-140], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@93-94 Identifier { ident: "y", suffixed: 0 }, @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred])), AnnotatedBody { ann_pattern: @93-94 Identifier { ident: "y", suffixed: 0 }, ann_type: @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred]), comment: None, body_pattern: @127-128 Identifier { ident: "y", suffixed: 0 }, body_expr: @127-140 Apply(@131-135 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@137-140 Var { module_name: "", ident: "msg" }], Space) }] }, @161-162 Var { module_name: "", ident: "y" })) }, AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x", suffixed: 0 }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x", suffixed: 0 }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg", suffixed: 0 }], @127-140 Apply(@127-140 Var { module_name: "Task", ident: "await" }, [@127-140 Apply(@127-140 Var { module_name: "", ident: "line" }, [@137-140 Var { module_name: "", ident: "msg" }], Space), @127-140 Closure([@127-128 Identifier { ident: "y", suffixed: 0 }], @161-162 Var { module_name: "", ident: "y" })], BangSuffix)) }] }, @180-187 Apply(@180-181 Var { module_name: "", ident: "x" }, [@182-187 Str(PlainLine("foo"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-187], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @0-187 Defs(Defs { tags: [Index(2147483650)], regions: [@60-162], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@24-25 Identifier { ident: "x" }, @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred]))), AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x" }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x" }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg" }], @93-162 Defs(Defs { tags: [Index(2147483649)], regions: [@93-140], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@93-94 Identifier { ident: "y" }, @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred])), AnnotatedBody { ann_pattern: @93-94 Identifier { ident: "y" }, ann_type: @97-106 Apply("", "Task", [@102-104 Record { fields: [], ext: None }, @105-106 Inferred]), comment: None, body_pattern: @127-128 Identifier { ident: "y" }, body_expr: @127-140 Apply(@131-135 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@137-140 Var { module_name: "", ident: "msg" }], Space) }] }, @161-162 Var { module_name: "", ident: "y" })) }, AnnotatedBody { ann_pattern: @24-25 Identifier { ident: "x" }, ann_type: @28-43 Function([@28-31 Apply("", "Str", [])], @35-43 Apply("", "Task", [@40-41 Inferred, @42-43 Inferred])), comment: None, body_pattern: @60-61 Identifier { ident: "x" }, body_expr: @60-162 Closure([@65-68 Identifier { ident: "msg" }], @127-140 Apply(@127-140 Var { module_name: "Task", ident: "await" }, [@127-140 Apply(@127-140 Var { module_name: "", ident: "line" }, [@137-140 Var { module_name: "", ident: "msg" }], Space), @127-140 Closure([@127-128 Identifier { ident: "y" }], @161-162 Var { module_name: "", ident: "y" })], BangSuffix)) }] }, @180-187 Apply(@180-181 Var { module_name: "", ident: "x" }, [@182-187 Str(PlainLine("foo"))], Space)))] }"#, ); } @@ -436,7 +436,7 @@ mod suffixed_tests { r#" run = line! (nextMsg!) "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-22], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-3 Identifier { ident: "run", suffixed: 0 }, @0-22 Apply(@0-22 Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "nextMsg" }, @0-22 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @0-22 Apply(@0-22 Var { module_name: "", ident: "line" }, [@13-21 ParensAround(Var { module_name: "", ident: "#!a0" })], Space))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-22], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-3 Identifier { ident: "run" }, @0-22 Apply(@0-22 Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "nextMsg" }, @0-22 Closure([Identifier { ident: "#!a0" }], @0-22 Apply(@0-22 Var { module_name: "", ident: "line" }, [@13-21 ParensAround(Var { module_name: "", ident: "#!a0" })], Space))], BangSuffix))] }"##, ); } @@ -465,7 +465,7 @@ mod suffixed_tests { z = foo! (bar! baz) (blah stuff) doSomething z "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-86], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "bar" }, [@39-42 Var { module_name: "", ident: "baz" }], Space), @28-56 Closure([Identifier { ident: "#!a0", suffixed: 0 }], @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await" }, [@28-56 Apply(@28-56 Var { module_name: "", ident: "foo" }, [@34-42 ParensAround(Var { module_name: "", ident: "#!a0" }), @45-55 ParensAround(Apply(@45-49 Var { module_name: "", ident: "blah" }, [@50-55 Var { module_name: "", ident: "stuff" }], Space))], Space), @28-56 Closure([@24-25 Identifier { ident: "z", suffixed: 0 }], @73-86 Apply(@73-84 Var { module_name: "", ident: "doSomething" }, [@85-86 Var { module_name: "", ident: "z" }], Space))], BangSuffix))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-86], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "bar" }, [@39-42 Var { module_name: "", ident: "baz" }], Space), @28-56 Closure([Identifier { ident: "#!a0" }], @28-56 Apply(@28-56 Var { module_name: "Task", ident: "await" }, [@28-56 Apply(@28-56 Var { module_name: "", ident: "foo" }, [@34-42 ParensAround(Var { module_name: "", ident: "#!a0" }), @45-55 ParensAround(Apply(@45-49 Var { module_name: "", ident: "blah" }, [@50-55 Var { module_name: "", ident: "stuff" }], Space))], Space), @28-56 Closure([@24-25 Identifier { ident: "z" }], @73-86 Apply(@73-84 Var { module_name: "", ident: "doSomething" }, [@85-86 Var { module_name: "", ident: "z" }], Space))], BangSuffix))], BangSuffix))] }"##, ); } @@ -514,7 +514,7 @@ mod suffixed_tests { foo "bar" {} "baz" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-249], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @25-249 Defs(Defs { tags: [Index(2147483650)], regions: [@81-193], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@25-28 Identifier { ident: "foo", suffixed: 0 }, @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])]))), AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @114-193 Defs(Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@119-121, @142-149], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@119-121 RecordDestructure([]), @119-121 Apply(@114-118 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@120-121 Var { module_name: "", ident: "a" }], Space)), Body(@142-149 RecordDestructure([]), @142-149 Apply(@142-146 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@148-149 Var { module_name: "", ident: "b" }], Space))] }, @183-193 Apply(@183-190 Var { module_name: "Task", ident: "ok" }, [@191-193 Record([])], Space))) }, AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo", suffixed: 0 }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo", suffixed: 0 }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a", suffixed: 0 }, @85-86 Underscore(""), @88-89 Identifier { ident: "b", suffixed: 0 }], @119-121 Apply(@119-121 Var { module_name: "Task", ident: "await" }, [@119-121 Apply(@119-121 Var { module_name: "", ident: "line" }, [@120-121 Var { module_name: "", ident: "a" }], Space), @119-121 Closure([@119-121 RecordDestructure([])], @142-149 Apply(@142-149 Var { module_name: "", ident: "line" }, [@148-149 Var { module_name: "", ident: "b" }], Space))], BangSuffix)) }] }, @231-249 Apply(@231-234 Var { module_name: "", ident: "foo" }, [@235-240 Str(PlainLine("bar")), @241-243 Record([]), @244-249 Str(PlainLine("baz"))], Space)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-249], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @25-249 Defs(Defs { tags: [Index(2147483650)], regions: [@81-193], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Annotation(@25-28 Identifier { ident: "foo" }, @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])]))), AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo" }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo" }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a" }, @85-86 Underscore(""), @88-89 Identifier { ident: "b" }], @114-193 Defs(Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@119-121, @142-149], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0), Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@119-121 RecordDestructure([]), @119-121 Apply(@114-118 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@120-121 Var { module_name: "", ident: "a" }], Space)), Body(@142-149 RecordDestructure([]), @142-149 Apply(@142-146 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@148-149 Var { module_name: "", ident: "b" }], Space))] }, @183-193 Apply(@183-190 Var { module_name: "Task", ident: "ok" }, [@191-193 Record([])], Space))) }, AnnotatedBody { ann_pattern: @25-28 Identifier { ident: "foo" }, ann_type: @31-58 Function([@31-34 Apply("", "Str", []), @36-38 Record { fields: [], ext: None }, @40-43 Apply("", "Str", [])], @47-58 Apply("", "Task", [@52-54 Record { fields: [], ext: None }, @55-58 Apply("", "I32", [])])), comment: None, body_pattern: @75-78 Identifier { ident: "foo" }, body_expr: @81-193 Closure([@82-83 Identifier { ident: "a" }, @85-86 Underscore(""), @88-89 Identifier { ident: "b" }], @119-121 Apply(@119-121 Var { module_name: "Task", ident: "await" }, [@119-121 Apply(@119-121 Var { module_name: "", ident: "line" }, [@120-121 Var { module_name: "", ident: "a" }], Space), @119-121 Closure([@119-121 RecordDestructure([])], @142-149 Apply(@142-149 Var { module_name: "", ident: "line" }, [@148-149 Var { module_name: "", ident: "b" }], Space))], BangSuffix)) }] }, @231-249 Apply(@231-234 Var { module_name: "", ident: "foo" }, [@235-240 Str(PlainLine("bar")), @241-243 Record([]), @244-249 Str(PlainLine("baz"))], Space)))] }"#, ); } @@ -562,7 +562,7 @@ mod suffixed_tests { b = "Bar" Stdout.line b "#, - r#"Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@0-90, @120-186], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 2)], space_after: [Slice(start = 0, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-90 Defs(Defs { tags: [Index(2147483649)], regions: [@27-32], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "a", suffixed: 0 }, @27-32 Str(PlainLine("Foo"))), Body(@23-24 Identifier { ident: "a", suffixed: 0 }, @27-32 Str(PlainLine("Foo")))] }, @23-90 Apply(@23-90 Var { module_name: "Task", ident: "await" }, [@49-63 Apply(@49-63 Var { module_name: "Stdout", ident: "line" }, [@62-63 Var { module_name: "", ident: "a" }], Space), @23-90 Closure([@49-63 RecordDestructure([])], @81-90 Var { module_name: "", ident: "printBar" })], BangSuffix))), Body(@120-128 Identifier { ident: "printBar", suffixed: 0 }, @147-186 Defs(Defs { tags: [Index(2147483649)], regions: [@151-156], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@147-148 Identifier { ident: "b", suffixed: 0 }, @151-156 Str(PlainLine("Bar"))), Body(@147-148 Identifier { ident: "b", suffixed: 0 }, @151-156 Str(PlainLine("Bar")))] }, @173-186 Apply(@173-184 Var { module_name: "Stdout", ident: "line" }, [@185-186 Var { module_name: "", ident: "b" }], Space)))] }"#, + r#"Defs { tags: [Index(2147483648), Index(2147483649)], regions: [@0-90, @120-186], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 2)], space_after: [Slice(start = 0, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @23-90 Defs(Defs { tags: [Index(2147483649)], regions: [@27-32], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@23-24 Identifier { ident: "a" }, @27-32 Str(PlainLine("Foo"))), Body(@23-24 Identifier { ident: "a" }, @27-32 Str(PlainLine("Foo")))] }, @23-90 Apply(@23-90 Var { module_name: "Task", ident: "await" }, [@49-63 Apply(@49-63 Var { module_name: "Stdout", ident: "line" }, [@62-63 Var { module_name: "", ident: "a" }], Space), @23-90 Closure([@49-63 RecordDestructure([])], @81-90 Var { module_name: "", ident: "printBar" })], BangSuffix))), Body(@120-128 Identifier { ident: "printBar" }, @147-186 Defs(Defs { tags: [Index(2147483649)], regions: [@151-156], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@147-148 Identifier { ident: "b" }, @151-156 Str(PlainLine("Bar"))), Body(@147-148 Identifier { ident: "b" }, @151-156 Str(PlainLine("Bar")))] }, @173-186 Apply(@173-184 Var { module_name: "Stdout", ident: "line" }, [@185-186 Var { module_name: "", ident: "b" }], Space)))] }"#, ); } @@ -610,7 +610,7 @@ mod suffixed_tests { else line "fail" "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-286], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @23-286 Defs(Defs { tags: [Index(2147483650), Index(2147483651)], regions: [@32-49, @76-94], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0)], spaces: [Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-73 Identifier { ident: "isFalse", suffixed: 0 }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok" }, [@84-94 Var { module_name: "Bool", ident: "false" }], Space)), Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-73 Identifier { ident: "isFalse", suffixed: 0 }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok" }, [@84-94 Var { module_name: "Bool", ident: "false" }], Space))] }, @115-123 Apply(@115-123 Var { module_name: "Task", ident: "await" }, [@115-123 Var { module_name: "", ident: "isFalse" }, @115-123 Closure([@115-123 Identifier { ident: "#!a0", suffixed: 0 }], @112-286 If([(@115-123 Var { module_name: "", ident: "#!a0" }, @149-160 Apply(@149-153 Var { module_name: "", ident: "line" }, [@154-160 Str(PlainLine("fail"))], Space))], @185-192 Apply(@185-192 Var { module_name: "Task", ident: "await" }, [@185-192 Var { module_name: "", ident: "isTrue" }, @185-192 Closure([@185-192 Identifier { ident: "#!a1", suffixed: 0 }], @112-286 If([(@185-192 Var { module_name: "", ident: "#!a1" }, @219-233 Apply(@219-223 Var { module_name: "", ident: "line" }, [@224-233 Str(PlainLine("success"))], Space))], @275-286 Apply(@275-279 Var { module_name: "", ident: "line" }, [@280-286 Str(PlainLine("fail"))], Space)))], BangSuffix)))], BangSuffix)))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-286], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @23-286 Defs(Defs { tags: [Index(2147483650), Index(2147483651)], regions: [@32-49, @76-94], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0)], spaces: [Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue" }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-73 Identifier { ident: "isFalse" }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok" }, [@84-94 Var { module_name: "Bool", ident: "false" }], Space)), Body(@23-29 Identifier { ident: "isTrue" }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-73 Identifier { ident: "isFalse" }, @76-94 Apply(@76-83 Var { module_name: "Task", ident: "ok" }, [@84-94 Var { module_name: "Bool", ident: "false" }], Space))] }, @115-123 Apply(@115-123 Var { module_name: "Task", ident: "await" }, [@115-123 Var { module_name: "", ident: "isFalse" }, @115-123 Closure([@115-123 Identifier { ident: "#!a0" }], @112-286 If([(@115-123 Var { module_name: "", ident: "#!a0" }, @149-160 Apply(@149-153 Var { module_name: "", ident: "line" }, [@154-160 Str(PlainLine("fail"))], Space))], @185-192 Apply(@185-192 Var { module_name: "Task", ident: "await" }, [@185-192 Var { module_name: "", ident: "isTrue" }, @185-192 Closure([@185-192 Identifier { ident: "#!a1" }], @112-286 If([(@185-192 Var { module_name: "", ident: "#!a1" }, @219-233 Apply(@219-223 Var { module_name: "", ident: "line" }, [@224-233 Str(PlainLine("success"))], Space))], @275-286 Apply(@275-279 Var { module_name: "", ident: "line" }, [@280-286 Str(PlainLine("fail"))], Space)))], BangSuffix)))], BangSuffix)))] }"##, ); } @@ -650,7 +650,7 @@ mod suffixed_tests { msg "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok" }, [@91-92 Var { module_name: "", ident: "x" }], Space))), Annotation(@109-112 Identifier { ident: "msg", suffixed: 0 }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not" }, [@175-182 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "isTrue" }))], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-217 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err" }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-294 TaskAwaitBang(Var { module_name: "", ident: "isFalsey" }), [@296-306 Var { module_name: "Bool", ident: "false" }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-342 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok" }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-434 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue", suffixed: 0 }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-74 Identifier { ident: "isFalsey", suffixed: 0 }, @77-92 Closure([@78-79 Identifier { ident: "x", suffixed: 0 }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok" }, [@91-92 Var { module_name: "", ident: "x" }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg", suffixed: 0 }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg", suffixed: 0 }, body_expr: Apply(Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "isTrue" }, Closure([Identifier { ident: "#!a0", suffixed: 0 }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not" }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0" })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await" }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line" }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err" }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "isFalsey" }, [@296-306 Var { module_name: "Bool", ident: "false" }], Space), Closure([Identifier { ident: "#!a1", suffixed: 0 }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1" }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await" }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line" }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok" }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "", ident: "line" }, [@436-445 Str(PlainLine("success"))], Space)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg" }))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-466], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @0-466 Defs(Defs { tags: [Index(2147483652), Index(2147483653), Index(2147483654)], regions: [@32-49, @77-92, @143-445], space_before: [Slice(start = 0, length = 0), Slice(start = 0, length = 1), Slice(start = 1, length = 1)], space_after: [Slice(start = 0, length = 0), Slice(start = 1, length = 0), Slice(start = 2, length = 0)], spaces: [Newline, Newline], type_defs: [], value_defs: [Body(@23-29 Identifier { ident: "isTrue" }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-74 Identifier { ident: "isFalsey" }, @77-92 Closure([@78-79 Identifier { ident: "x" }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok" }, [@91-92 Var { module_name: "", ident: "x" }], Space))), Annotation(@109-112 Identifier { ident: "msg" }, @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])])), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg" }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg" }, body_expr: @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not" }, [@175-182 ParensAround(TaskAwaitBang(Var { module_name: "", ident: "isTrue" }))], UnaryOp(Not)), @213-256 Defs(Defs { tags: [Index(2147483648)], regions: [@218-225], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@218-225 RecordDestructure([]), @218-225 Apply(@213-217 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@219-225 Str(PlainLine("fail"))], Space))] }, @251-256 Apply(@251-254 Var { module_name: "", ident: "err" }, [@255-256 Num("1")], Space))), (@285-307 ParensAround(Apply(@286-294 TaskAwaitBang(Var { module_name: "", ident: "isFalsey" }), [@296-306 Var { module_name: "Bool", ident: "false" }], Space)), @338-380 Defs(Defs { tags: [Index(2147483648)], regions: [@343-350], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@343-350 RecordDestructure([]), @343-350 Apply(@338-342 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@344-350 Str(PlainLine("nope"))], Space))] }, @375-380 Apply(@375-377 Var { module_name: "", ident: "ok" }, [@378-380 Record([])], Space)))], @430-445 Apply(@430-434 TaskAwaitBang(Var { module_name: "", ident: "line" }), [@436-445 Str(PlainLine("success"))], Space)) }, Body(@23-29 Identifier { ident: "isTrue" }, @32-49 Apply(@32-39 Var { module_name: "Task", ident: "ok" }, [@40-49 Var { module_name: "Bool", ident: "true" }], Space)), Body(@66-74 Identifier { ident: "isFalsey" }, @77-92 Closure([@78-79 Identifier { ident: "x" }], @83-92 Apply(@83-90 Var { module_name: "Task", ident: "ok" }, [@91-92 Var { module_name: "", ident: "x" }], Space))), AnnotatedBody { ann_pattern: @109-112 Identifier { ident: "msg" }, ann_type: @115-126 Apply("", "Task", [@120-122 Record { fields: [], ext: None }, @123-126 Apply("", "I32", [])]), comment: None, body_pattern: @143-146 Identifier { ident: "msg" }, body_expr: Apply(Var { module_name: "Task", ident: "await" }, [Var { module_name: "", ident: "isTrue" }, Closure([Identifier { ident: "#!a0" }], @143-445 If([(@173-183 Apply(@173-174 Var { module_name: "Bool", ident: "not" }, [@175-182 ParensAround(Var { module_name: "", ident: "#!a0" })], UnaryOp(Not)), @218-225 Apply(@218-225 Var { module_name: "Task", ident: "await" }, [@218-225 Apply(@218-225 Var { module_name: "", ident: "line" }, [@219-225 Str(PlainLine("fail"))], Space), @218-225 Closure([@218-225 RecordDestructure([])], @251-256 Apply(@251-254 Var { module_name: "", ident: "err" }, [@255-256 Num("1")], Space))], BangSuffix))], Apply(Var { module_name: "Task", ident: "await" }, [Apply(Var { module_name: "", ident: "isFalsey" }, [@296-306 Var { module_name: "Bool", ident: "false" }], Space), Closure([Identifier { ident: "#!a1" }], @143-445 If([(@285-307 ParensAround(Var { module_name: "", ident: "#!a1" }), @343-350 Apply(@343-350 Var { module_name: "Task", ident: "await" }, [@343-350 Apply(@343-350 Var { module_name: "", ident: "line" }, [@344-350 Str(PlainLine("nope"))], Space), @343-350 Closure([@343-350 RecordDestructure([])], @375-380 Apply(@375-377 Var { module_name: "", ident: "ok" }, [@378-380 Record([])], Space))], BangSuffix))], @430-445 Apply(@430-445 Var { module_name: "", ident: "line" }, [@436-445 Str(PlainLine("success"))], Space)))], BangSuffix)))], BangSuffix) }] }, @463-466 Var { module_name: "", ident: "msg" }))] }"##, ); } @@ -681,7 +681,7 @@ mod suffixed_tests { CMD.new "cp" |> mapErr! ERR "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-103], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "copy", suffixed: 0 }, @7-103 Closure([@8-9 Identifier { ident: "a", suffixed: 0 }, @10-11 Identifier { ident: "b", suffixed: 0 }], @36-42 Apply(@36-42 Var { module_name: "Task", ident: "await" }, [@36-42 Apply(@36-42 Var { module_name: "", ident: "line" }, [@37-42 Str(PlainLine("FOO"))], Space), @36-42 Closure([@36-42 RecordDestructure([])], @60-103 Apply(@60-103 Var { module_name: "", ident: "mapErr" }, [@60-72 Apply(@60-67 Var { module_name: "CMD", ident: "new" }, [@68-72 Str(PlainLine("cp"))], Space), @100-103 Tag("ERR")], BinOp(Pizza)))], BangSuffix)))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-103], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "copy" }, @7-103 Closure([@8-9 Identifier { ident: "a" }, @10-11 Identifier { ident: "b" }], @36-42 Apply(@36-42 Var { module_name: "Task", ident: "await" }, [@36-42 Apply(@36-42 Var { module_name: "", ident: "line" }, [@37-42 Str(PlainLine("FOO"))], Space), @36-42 Closure([@36-42 RecordDestructure([])], @60-103 Apply(@60-103 Var { module_name: "", ident: "mapErr" }, [@60-72 Apply(@60-67 Var { module_name: "CMD", ident: "new" }, [@68-72 Str(PlainLine("cp"))], Space), @100-103 Tag("ERR")], BinOp(Pizza)))], BangSuffix)))] }"#, ); } @@ -709,7 +709,7 @@ mod suffixed_tests { [] -> "empty" _ -> "non-empty" "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-111 Apply(@0-111 Var { module_name: "Task", ident: "await" }, [@29-37 Var { module_name: "", ident: "getList" }, @0-111 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-111 When(@29-37 Var { module_name: "", ident: "#!a0" }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-111], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list" }, @0-111 Apply(@0-111 Var { module_name: "Task", ident: "await" }, [@29-37 Var { module_name: "", ident: "getList" }, @0-111 Closure([@29-37 Identifier { ident: "#!a0" }], @0-111 When(@29-37 Var { module_name: "", ident: "#!a0" }, [WhenBranch { patterns: [@61-63 List([])], value: @67-74 Str(PlainLine("empty")), guard: None }, WhenBranch { patterns: [@95-96 Underscore("")], value: @100-111 Str(PlainLine("non-empty")), guard: None }]))], BangSuffix))] }"##, ); } @@ -754,7 +754,7 @@ mod suffixed_tests { _ -> ok {} "#, - r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list", suffixed: 0 }, @0-195 Apply(@0-195 Var { module_name: "Task", ident: "await" }, [@29-37 Var { module_name: "", ident: "getList" }, @0-195 Closure([@29-37 Identifier { ident: "#!a0", suffixed: 0 }], @0-195 When(@29-37 Var { module_name: "", ident: "#!a0" }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await" }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line" }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line" }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok" }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, + r##"Defs { tags: [Index(2147483648)], regions: [@0-195], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "list" }, @0-195 Apply(@0-195 Var { module_name: "Task", ident: "await" }, [@29-37 Var { module_name: "", ident: "getList" }, @0-195 Closure([@29-37 Identifier { ident: "#!a0" }], @0-195 When(@29-37 Var { module_name: "", ident: "#!a0" }, [WhenBranch { patterns: [@61-63 List([])], value: @97-103 Apply(@97-103 Var { module_name: "Task", ident: "await" }, [@97-103 Apply(@97-103 Var { module_name: "", ident: "line" }, [@98-103 Str(PlainLine("foo"))], Space), @97-103 Closure([@97-103 RecordDestructure([])], @128-139 Apply(@128-139 Var { module_name: "", ident: "line" }, [@134-139 Str(PlainLine("bar"))], Space))], BangSuffix), guard: None }, WhenBranch { patterns: [@160-161 Underscore("")], value: @190-195 Apply(@190-192 Var { module_name: "", ident: "ok" }, [@193-195 Record([])], Space), guard: None }]))], BangSuffix))] }"##, ); } diff --git a/crates/compiler/fmt/src/pattern.rs b/crates/compiler/fmt/src/pattern.rs index 61d49ddeff..d18cabd383 100644 --- a/crates/compiler/fmt/src/pattern.rs +++ b/crates/compiler/fmt/src/pattern.rs @@ -88,16 +88,9 @@ impl<'a> Formattable for Pattern<'a> { use self::Pattern::*; match self { - Identifier { - ident: string, - suffixed, - } => { + Identifier { ident: string } => { buf.indent(indent); buf.push_str(string); - - for _ in 0..*suffixed { - buf.push('!'); - } } Tag(name) | OpaqueRef(name) => { buf.indent(indent); @@ -277,21 +270,13 @@ impl<'a> Formattable for Pattern<'a> { buf.indent(indent); buf.push_str(string); } - QualifiedIdentifier { - module_name, - ident, - suffixed, - } => { + QualifiedIdentifier { module_name, ident } => { buf.indent(indent); if !module_name.is_empty() { buf.push_str(module_name); buf.push('.'); } - for _ in 0..*suffixed { - buf.push('!'); - } - buf.push_str(ident); } } diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index 2b43a915ce..90f884be99 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -795,7 +795,7 @@ fn remove_spaces_bad_ident(ident: BadIdent) -> BadIdent { impl<'a> RemoveSpaces<'a> for Pattern<'a> { fn remove_spaces(&self, arena: &'a Bump) -> Self { match *self { - Pattern::Identifier { ident, suffixed } => Pattern::Identifier { ident, suffixed }, + Pattern::Identifier { ident } => Pattern::Identifier { ident }, Pattern::Tag(a) => Pattern::Tag(a), Pattern::OpaqueRef(a) => Pattern::OpaqueRef(a), Pattern::Apply(a, b) => Pattern::Apply( @@ -828,15 +828,9 @@ impl<'a> RemoveSpaces<'a> for Pattern<'a> { Pattern::Underscore(a) => Pattern::Underscore(a), Pattern::Malformed(a) => Pattern::Malformed(a), Pattern::MalformedIdent(a, b) => Pattern::MalformedIdent(a, remove_spaces_bad_ident(b)), - Pattern::QualifiedIdentifier { - module_name, - ident, - suffixed, - } => Pattern::QualifiedIdentifier { - module_name, - ident, - suffixed, - }, + Pattern::QualifiedIdentifier { module_name, ident } => { + Pattern::QualifiedIdentifier { module_name, ident } + } Pattern::SpaceBefore(a, _) => a.remove_spaces(arena), Pattern::SpaceAfter(a, _) => a.remove_spaces(arena), Pattern::SingleQuote(a) => Pattern::SingleQuote(a), diff --git a/crates/compiler/load_internal/src/docs.rs b/crates/compiler/load_internal/src/docs.rs index 52e668feeb..2114d35fe6 100644 --- a/crates/compiler/load_internal/src/docs.rs +++ b/crates/compiler/load_internal/src/docs.rs @@ -212,11 +212,7 @@ fn generate_entry_docs( match either_index.split() { Err(value_index) => match &defs.value_defs[value_index.index()] { ValueDef::Annotation(loc_pattern, loc_ann) => { - if let Pattern::Identifier { - ident: identifier, - suffixed: _, - } = loc_pattern.value - { + if let Pattern::Identifier { ident: identifier } = loc_pattern.value { // Check if this module exposes the def if let Some(ident_id) = ident_ids.get_id(identifier) { let name = identifier.to_string(); @@ -237,11 +233,7 @@ fn generate_entry_docs( ann_type, .. } => { - if let Pattern::Identifier { - ident: identifier, - suffixed: _, - } = ann_pattern.value - { + if let Pattern::Identifier { ident: identifier } = ann_pattern.value { // Check if this module exposes the def if let Some(ident_id) = ident_ids.get_id(identifier) { let doc_def = DocDef { @@ -257,11 +249,7 @@ fn generate_entry_docs( } ValueDef::Body(pattern, _) => { - if let Pattern::Identifier { - ident: identifier, - suffixed: _, - } = pattern.value - { + if let Pattern::Identifier { ident: identifier } = pattern.value { // Check if this module exposes the def if let Some(ident_id) = ident_ids.get_id(identifier) { let doc_def = DocDef { @@ -316,11 +304,7 @@ fn generate_entry_docs( let mut type_vars = Vec::new(); for var in vars.iter() { - if let Pattern::Identifier { - ident: ident_name, - suffixed: _, - } = var.value - { + if let Pattern::Identifier { ident: ident_name } = var.value { type_vars.push(ident_name.to_string()); } } @@ -354,11 +338,7 @@ fn generate_entry_docs( let mut type_vars = Vec::new(); for var in vars.iter() { - if let Pattern::Identifier { - ident: ident_name, - suffixed: _, - } = var.value - { + if let Pattern::Identifier { ident: ident_name } = var.value { type_vars.push(ident_name.to_string()); } } @@ -382,11 +362,7 @@ fn generate_entry_docs( let mut type_vars = Vec::new(); for var in vars.iter() { - if let Pattern::Identifier { - ident: ident_name, - suffixed: _, - } = var.value - { + if let Pattern::Identifier { ident: ident_name } = var.value { type_vars.push(ident_name.to_string()); } } @@ -648,7 +624,7 @@ fn type_to_docs(in_func_type_ann: bool, type_annotation: ast::TypeAnnotation) -> .vars .iter() .filter_map(|loc_pattern| match loc_pattern.value { - ast::Pattern::Identifier { ident, suffixed: _ } => Some(ident.to_string()), + ast::Pattern::Identifier { ident } => Some(ident.to_string()), _ => None, }) .collect(), diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 24e1aa6f9d..d11a003138 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -5663,13 +5663,7 @@ fn value_def_from_imports<'a>( }; let typed_ident = typed_ident.extract_spaces().item; let Loc { region, value } = typed_ident.ident; - let ident = arena.alloc(Loc::at( - region, - Pattern::Identifier { - ident: value, - suffixed: 0, - }, - )); + let ident = arena.alloc(Loc::at(region, Pattern::Identifier { ident: value })); let ann_type = arena.alloc(typed_ident.ann); Some(ValueDef::AnnotatedBody { diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 191717108b..9b502991f0 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -1130,12 +1130,10 @@ pub enum Pattern<'a> { // Identifier Identifier { ident: &'a str, - suffixed: u8, }, QualifiedIdentifier { module_name: &'a str, ident: &'a str, - suffixed: u8, }, Tag(&'a str), @@ -1253,21 +1251,11 @@ impl<'a> Pattern<'a> { // { x, y } : { x : Int, y ? Bool } // { x, y ? False } = rec OptionalField(x, _) => match other { - Identifier { - ident: y, - suffixed: 0, - } - | OptionalField(y, _) => x == y, + Identifier { ident: y } | OptionalField(y, _) => x == y, _ => false, }, - Identifier { - ident: x, - suffixed: a, - } => match other { - Identifier { - ident: y, - suffixed: b, - } => x == y && a == b, + Identifier { ident: x } => match other { + Identifier { ident: y } => x == y, OptionalField(y, _) => x == y, _ => false, }, @@ -1329,15 +1317,13 @@ impl<'a> Pattern<'a> { QualifiedIdentifier { module_name: a, ident: x, - suffixed: i, } => { if let QualifiedIdentifier { module_name: b, ident: y, - suffixed: j, } = other { - a == b && x == y && i == j + a == b && x == y } else { false } @@ -1402,15 +1388,6 @@ impl<'a> Pattern<'a> { } } } - - // used to check if a pattern is suffixed to report as an error - pub fn is_suffixed(&self) -> bool { - match self { - Pattern::Identifier { suffixed, .. } => *suffixed > 0, - Pattern::QualifiedIdentifier { suffixed, .. } => *suffixed > 0, - _ => false, - } - } } #[derive(Copy, Clone)] pub struct Collection<'a, T> { diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index ddb88309bf..561db5fa50 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -2186,13 +2186,9 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result { if module_name.is_empty() { - Pattern::Identifier { ident, suffixed: 0 } + Pattern::Identifier { ident } } else { - Pattern::QualifiedIdentifier { - module_name, - ident, - suffixed: 0, - } + Pattern::QualifiedIdentifier { module_name, ident } } } Expr::Underscore(opt_name) => Pattern::Underscore(opt_name), @@ -2328,10 +2324,7 @@ fn assigned_expr_field_to_pattern_help<'a>( ) } } - AssignedField::LabelOnly(name) => Pattern::Identifier { - ident: name.value, - suffixed: 0, - }, + AssignedField::LabelOnly(name) => Pattern::Identifier { ident: name.value }, AssignedField::SpaceBefore(nested, spaces) => Pattern::SpaceBefore( arena.alloc(assigned_expr_field_to_pattern_help(arena, nested)?), spaces, diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index 8e41b42b93..f32e11782b 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -406,10 +406,7 @@ fn loc_ident_pattern_help<'a>( MadeProgress, Loc { region: loc_ident.region, - value: Pattern::Identifier { - ident: var, - suffixed: 0, - }, + value: Pattern::Identifier { ident: var }, }, state, )) @@ -424,7 +421,6 @@ fn loc_ident_pattern_help<'a>( value: Pattern::QualifiedIdentifier { module_name, ident: var, - suffixed: 0, }, }, state, @@ -451,10 +447,7 @@ fn loc_ident_pattern_help<'a>( MadeProgress, Loc { region: loc_ident.region, - value: Pattern::Identifier { - ident: var, - suffixed: 0, - }, + value: Pattern::Identifier { ident: var }, }, state, )); @@ -615,18 +608,9 @@ fn record_pattern_field<'a>() -> impl Parser<'a, Loc>, PRecord<'a>> None => { let Loc { value, region } = loc_label; let value = if !spaces.is_empty() { - Pattern::SpaceAfter( - arena.alloc(Pattern::Identifier { - ident: value, - suffixed: 0, - }), - spaces, - ) + Pattern::SpaceAfter(arena.alloc(Pattern::Identifier { ident: value }), spaces) } else { - Pattern::Identifier { - ident: value, - suffixed: 0, - } + Pattern::Identifier { ident: value } }; Ok((MadeProgress, Loc::at(region, value), state)) diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 806bdd7ff8..da9c461f78 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -70,13 +70,7 @@ fn check_type_alias<'a>( var_names.reserve(vars.len()); for var in vars { if let TypeAnnotation::BoundVariable(v) = var.value { - var_names.push(Loc::at( - var.region, - Pattern::Identifier { - ident: v, - suffixed: 0, - }, - )); + var_names.push(Loc::at(var.region, Pattern::Identifier { ident: v })); } else { return Err(ETypeInlineAlias::ArgumentNotLowercase(var.region.start())); } diff --git a/crates/repl_ui/src/repl_state.rs b/crates/repl_ui/src/repl_state.rs index d468713f7a..fbb4f99475 100644 --- a/crates/repl_ui/src/repl_state.rs +++ b/crates/repl_ui/src/repl_state.rs @@ -74,7 +74,7 @@ impl ReplState { ValueDef::Annotation( Loc { // TODO is this right for suffixed - value: Pattern::Identifier { ident, suffixed: _ }, + value: Pattern::Identifier { ident }, .. }, _, @@ -89,7 +89,7 @@ impl ReplState { ValueDef::Body( Loc { // TODO is this right for suffixed - value: Pattern::Identifier { ident, suffixed: _ }, + value: Pattern::Identifier { ident }, .. }, _, @@ -98,7 +98,7 @@ impl ReplState { body_pattern: Loc { // TODO is this right for suffixed - value: Pattern::Identifier { ident, suffixed: _ }, + value: Pattern::Identifier { ident }, .. }, .. From 8d88e3ab7f6d58276687130593027f672bc6347f Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sat, 27 Apr 2024 13:21:44 +1000 Subject: [PATCH 57/72] update snapshots --- .../malformed_pattern_field_access.expr.result-ast | 1 - .../malformed_pattern_module_name.expr.result-ast | 1 - .../snapshots/pass/add_var_with_spaces.expr.result-ast | 1 - .../snapshots/pass/ann_closed_union.expr.result-ast | 3 --- .../snapshots/pass/ann_open_union.expr.result-ast | 3 --- .../pass/annotated_record_destructure.expr.result-ast | 7 ------- .../pass/annotated_tag_destructure.expr.result-ast | 4 ---- .../pass/annotated_tuple_destructure.expr.result-ast | 7 ------- .../snapshots/pass/apply_three_args.expr.result-ast | 4 ---- .../snapshots/pass/apply_two_args.expr.result-ast | 1 - .../pass/apply_unary_negation.expr.result-ast | 2 -- .../snapshots/pass/apply_unary_not.expr.result-ast | 2 -- .../tests/snapshots/pass/basic_apply.expr.result-ast | 1 - .../tests/snapshots/pass/basic_docs.expr.result-ast | 1 - .../tests/snapshots/pass/basic_field.expr.result-ast | 1 - .../tests/snapshots/pass/basic_var.expr.result-ast | 1 - .../snapshots/pass/bound_variable.expr.result-ast | 1 - .../snapshots/pass/call_with_newlines.expr.result-ast | 1 - .../snapshots/pass/closure_in_binop.expr.result-ast | 3 --- .../pass/closure_in_binop_with_spaces.expr.result-ast | 4 ---- .../pass/comment_after_annotation.expr.result-ast | 1 - .../pass/comment_after_def.moduledefs.result-ast | 1 - .../pass/comment_after_expr_in_parens.expr.result-ast | 1 - .../pass/comment_after_tag_in_def.expr.result-ast | 2 -- .../pass/comment_before_colon_def.expr.result-ast | 1 - .../pass/comment_before_equals_def.expr.result-ast | 2 -- .../tests/snapshots/pass/crash.expr.result-ast | 2 -- .../snapshots/pass/def_without_newline.expr.result-ast | 2 -- .../pass/destructure_tag_assignment.expr.result-ast | 2 -- .../tests/snapshots/pass/docs.expr.result-ast | 1 - .../snapshots/pass/empty_record_update.expr.result-ast | 1 - .../tests/snapshots/pass/equals.expr.result-ast | 2 -- .../snapshots/pass/equals_with_spaces.expr.result-ast | 2 -- .../pass/extra_newline_in_parens.expr.result-ast | 1 - .../snapshots/pass/fn_with_record_arg.expr.result-ast | 5 ----- .../pass/function_with_tuple_ext_type.expr.result-ast | 6 ------ .../pass/function_with_tuple_type.expr.result-ast | 7 ------- .../tests/snapshots/pass/if_def.expr.result-ast | 1 - .../snapshots/pass/lambda_in_chain.expr.result-ast | 5 ----- .../tests/snapshots/pass/lambda_indent.expr.result-ast | 1 - .../list_closing_indent_not_enough.expr.result-ast | 3 --- ...osing_same_indent_no_trailing_comma.expr.result-ast | 1 - ...ing_same_indent_with_trailing_comma.expr.result-ast | 1 - .../snapshots/pass/list_minus_newlines.expr.result-ast | 1 - .../tests/snapshots/pass/list_patterns.expr.result-ast | 10 ---------- .../tests/snapshots/pass/mixed_docs.expr.result-ast | 1 - .../pass/module_def_newline.moduledefs.result-ast | 3 --- .../snapshots/pass/multi_backpassing.expr.result-ast | 5 ----- .../multi_backpassing_in_def.moduledefs.result-ast | 4 ---- .../pass/multi_backpassing_with_apply.expr.result-ast | 2 -- .../snapshots/pass/multiline_string.expr.result-ast | 3 --- .../pass/multiline_string_in_apply.expr.result-ast | 1 - .../pass/multiline_type_signature.expr.result-ast | 1 - ...ltiline_type_signature_with_comment.expr.result-ast | 1 - .../snapshots/pass/multiple_fields.expr.result-ast | 1 - .../tests/snapshots/pass/neg_inf_float.expr.result-ast | 1 - .../pass/negative_in_apply_def.expr.result-ast | 4 ---- ...ested_backpassing_no_newline_before.expr.result-ast | 6 ------ .../pass/nested_def_annotation.moduledefs.result-ast | 9 --------- .../pass/nested_def_without_newline.expr.result-ast | 2 -- .../tests/snapshots/pass/nested_if.expr.result-ast | 2 -- .../pass/newline_after_equals.expr.result-ast | 1 - ...newline_and_spaces_before_less_than.expr.result-ast | 1 - .../snapshots/pass/newline_in_packages.full.result-ast | 2 -- .../newline_in_type_alias_application.expr.result-ast | 1 - .../snapshots/pass/newline_in_type_def.expr.result-ast | 1 - .../snapshots/pass/one_backpassing.expr.result-ast | 4 ---- .../tests/snapshots/pass/one_def.expr.result-ast | 1 - .../snapshots/pass/one_spaced_def.expr.result-ast | 1 - ...aque_destructure_first_item_in_body.expr.result-ast | 3 --- ...paque_reference_expr_with_arguments.expr.result-ast | 2 -- .../pass/opaque_reference_pattern.expr.result-ast | 1 - ...ue_reference_pattern_with_arguments.expr.result-ast | 5 ----- .../pass/opaque_type_def_with_newline.expr.result-ast | 2 -- .../opaque_with_type_arguments.moduledefs.result-ast | 1 - .../pass/outdented_app_with_record.expr.result-ast | 5 ----- .../pass/outdented_colon_in_record.expr.result-ast | 4 ---- .../snapshots/pass/outdented_list.expr.result-ast | 2 -- .../snapshots/pass/outdented_record.expr.result-ast | 4 ---- .../pass/parens_in_type_def_apply.expr.result-ast | 3 --- .../parens_in_value_def_annotation.expr.result-ast | 2 -- .../pass/parenthesized_type_def.expr.result-ast | 1 - ...parenthesized_type_def_space_before.expr.result-ast | 1 - .../snapshots/pass/parenthetical_apply.expr.result-ast | 1 - .../pass/parenthetical_basic_field.expr.result-ast | 1 - .../parenthetical_field_qualified_var.expr.result-ast | 1 - .../snapshots/pass/parenthetical_var.expr.result-ast | 1 - .../tests/snapshots/pass/parse_alias.expr.result-ast | 2 -- .../tests/snapshots/pass/parse_as_ann.expr.result-ast | 3 --- .../tests/snapshots/pass/pattern_as.expr.result-ast | 1 - .../pass/pattern_as_list_rest.expr.result-ast | 2 -- .../pass/pattern_with_space_in_parens.expr.result-ast | 4 ---- .../tests/snapshots/pass/plus_if.expr.result-ast | 1 - .../tests/snapshots/pass/pos_inf_float.expr.result-ast | 1 - .../snapshots/pass/qualified_field.expr.result-ast | 1 - .../tests/snapshots/pass/qualified_var.expr.result-ast | 1 - .../pass/record_destructure_def.expr.result-ast | 3 --- .../pass/record_func_type_decl.expr.result-ast | 1 - .../pass/record_type_with_function.expr.result-ast | 1 - .../tests/snapshots/pass/record_update.expr.result-ast | 1 - .../snapshots/pass/record_with_if.expr.result-ast | 1 - .../snapshots/pass/single_arg_closure.expr.result-ast | 1 - .../snapshots/pass/space_before_colon.full.result-ast | 2 -- .../pass/space_only_after_minus.expr.result-ast | 2 -- .../pass/standalone_module_defs.moduledefs.result-ast | 3 --- .../snapshots/pass/sub_var_with_spaces.expr.result-ast | 1 - .../tests/snapshots/pass/suffixed.expr.result-ast | 1 - .../pass/suffixed_multiple_defs.moduledefs.result-ast | 6 ------ .../snapshots/pass/suffixed_nested.expr.result-ast | 5 ----- .../snapshots/pass/suffixed_one_def.full.result-ast | 4 ---- .../pass/suffixed_optional_last.full.result-ast | 4 ---- .../snapshots/pass/three_arg_closure.expr.result-ast | 3 --- .../pass/tuple_access_after_ident.expr.result-ast | 2 -- .../tests/snapshots/pass/tuple_type.expr.result-ast | 6 ------ .../snapshots/pass/tuple_type_ext.expr.result-ast | 6 ------ .../snapshots/pass/two_arg_closure.expr.result-ast | 2 -- .../snapshots/pass/two_backpassing.expr.result-ast | 5 ----- .../snapshots/pass/two_branch_when.expr.result-ast | 1 - .../snapshots/pass/two_spaced_def.expr.result-ast | 2 -- .../pass/type_decl_with_underscore.expr.result-ast | 1 - .../snapshots/pass/type_signature_def.expr.result-ast | 3 --- .../pass/type_signature_function_def.expr.result-ast | 4 ---- .../snapshots/pass/unary_negation.expr.result-ast | 1 - .../pass/unary_negation_access.expr.result-ast | 1 - .../snapshots/pass/unary_negation_arg.expr.result-ast | 2 -- .../pass/unary_negation_with_parens.expr.result-ast | 2 -- .../tests/snapshots/pass/unary_not.expr.result-ast | 1 - .../pass/unary_not_with_parens.expr.result-ast | 2 -- .../pass/underscore_backpassing.expr.result-ast | 2 -- .../underscore_in_assignment_pattern.expr.result-ast | 4 ---- .../snapshots/pass/value_def_confusion.expr.result-ast | 2 -- .../tests/snapshots/pass/var_else.expr.result-ast | 1 - .../tests/snapshots/pass/var_if.expr.result-ast | 1 - .../tests/snapshots/pass/var_is.expr.result-ast | 1 - .../tests/snapshots/pass/var_minus_two.expr.result-ast | 1 - .../tests/snapshots/pass/var_then.expr.result-ast | 1 - .../tests/snapshots/pass/var_when.expr.result-ast | 1 - .../tests/snapshots/pass/when_if_guard.expr.result-ast | 1 - .../snapshots/pass/when_in_assignment.expr.result-ast | 2 -- .../snapshots/pass/when_in_function.expr.result-ast | 3 --- ...hen_in_function_python_style_indent.expr.result-ast | 3 --- .../snapshots/pass/when_in_parens.expr.result-ast | 1 - .../pass/when_in_parens_indented.expr.result-ast | 1 - .../when_with_alternative_patterns.expr.result-ast | 1 - .../when_with_function_application.expr.result-ast | 2 -- .../pass/when_with_negative_numbers.expr.result-ast | 1 - .../snapshots/pass/when_with_numbers.expr.result-ast | 1 - .../snapshots/pass/when_with_records.expr.result-ast | 4 ---- .../pass/when_with_tuple_in_record.expr.result-ast | 4 ---- .../snapshots/pass/when_with_tuples.expr.result-ast | 4 ---- .../pass/where_clause_function.expr.result-ast | 2 -- ...ere_clause_multiple_bound_abilities.expr.result-ast | 3 --- .../pass/where_clause_multiple_has.expr.result-ast | 2 -- ...clause_multiple_has_across_newlines.expr.result-ast | 2 -- .../pass/where_clause_non_function.expr.result-ast | 2 -- .../pass/where_clause_on_newline.expr.result-ast | 2 -- .../tests/snapshots/pass/where_ident.expr.result-ast | 4 ---- 157 files changed, 364 deletions(-) diff --git a/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_field_access.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_field_access.expr.result-ast index abec750456..526bf8a5cd 100644 --- a/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_field_access.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_field_access.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_module_name.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_module_name.expr.result-ast index b1117a9db1..fa23b429e9 100644 --- a/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_module_name.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/malformed/malformed_pattern_module_name.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/add_var_with_spaces.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/add_var_with_spaces.expr.result-ast index d43c4e9673..cd27503529 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/add_var_with_spaces.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/add_var_with_spaces.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "x", - suffixed: 0, }, @2-3 Plus, ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ann_closed_union.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/ann_closed_union.expr.result-ast index 430110e4ba..4237351435 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ann_closed_union.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ann_closed_union.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-3 Identifier { ident: "foo", - suffixed: 0, }, @6-27 TagUnion { ext: None, @@ -43,7 +42,6 @@ Defs( AnnotatedBody { ann_pattern: @0-3 Identifier { ident: "foo", - suffixed: 0, }, ann_type: @6-27 TagUnion { ext: None, @@ -67,7 +65,6 @@ Defs( comment: None, body_pattern: @28-31 Identifier { ident: "foo", - suffixed: 0, }, body_expr: @34-38 Tag( "True", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ann_open_union.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/ann_open_union.expr.result-ast index 765570eaf8..2cee1cd11c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ann_open_union.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ann_open_union.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-3 Identifier { ident: "foo", - suffixed: 0, }, @6-28 TagUnion { ext: Some( @@ -45,7 +44,6 @@ Defs( AnnotatedBody { ann_pattern: @0-3 Identifier { ident: "foo", - suffixed: 0, }, ann_type: @6-28 TagUnion { ext: Some( @@ -71,7 +69,6 @@ Defs( comment: None, body_pattern: @29-32 Identifier { ident: "foo", - suffixed: 0, }, body_expr: @35-39 Tag( "True", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/annotated_record_destructure.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/annotated_record_destructure.expr.result-ast index 30e6bfa6ec..73eb83e070 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/annotated_record_destructure.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/annotated_record_destructure.expr.result-ast @@ -20,11 +20,9 @@ Defs( [ @2-3 Identifier { ident: "x", - suffixed: 0, }, @5-7 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -39,11 +37,9 @@ Defs( [ @2-3 Identifier { ident: "x", - suffixed: 0, }, @5-7 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -57,11 +53,9 @@ Defs( [ @17-18 Identifier { ident: "x", - suffixed: 0, }, @20-21 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -92,7 +86,6 @@ Defs( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tag_destructure.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tag_destructure.expr.result-ast index 8e342f0c71..34cc726541 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tag_destructure.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tag_destructure.expr.result-ast @@ -20,7 +20,6 @@ Defs( vars: [ @7-8 Identifier { ident: "x", - suffixed: 0, }, ], }, @@ -50,7 +49,6 @@ Defs( [ @7-8 Identifier { ident: "x", - suffixed: 0, }, ], ), @@ -77,7 +75,6 @@ Defs( [ @33-34 Identifier { ident: "x", - suffixed: 0, }, ], ), @@ -99,7 +96,6 @@ Defs( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tuple_destructure.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tuple_destructure.expr.result-ast index c543b815a9..7b7c34b6b6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tuple_destructure.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/annotated_tuple_destructure.expr.result-ast @@ -20,11 +20,9 @@ Defs( [ @2-3 Identifier { ident: "x", - suffixed: 0, }, @5-6 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -39,11 +37,9 @@ Defs( [ @2-3 Identifier { ident: "x", - suffixed: 0, }, @5-6 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -57,11 +53,9 @@ Defs( [ @17-18 Identifier { ident: "x", - suffixed: 0, }, @20-21 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -84,7 +78,6 @@ Defs( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/apply_three_args.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/apply_three_args.expr.result-ast index 2edc8ee01e..bdf0bf721a 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/apply_three_args.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/apply_three_args.expr.result-ast @@ -2,23 +2,19 @@ Apply( @0-1 Var { module_name: "", ident: "a", - suffixed: 0, }, [ @2-3 Var { module_name: "", ident: "b", - suffixed: 0, }, @4-5 Var { module_name: "", ident: "c", - suffixed: 0, }, @6-7 Var { module_name: "", ident: "d", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/apply_two_args.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/apply_two_args.expr.result-ast index 657af27087..882b37c09d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/apply_two_args.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/apply_two_args.expr.result-ast @@ -2,7 +2,6 @@ Apply( @0-4 Var { module_name: "", ident: "whee", - suffixed: 0, }, [ @6-8 Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_negation.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_negation.expr.result-ast index dc17c10200..d74301a614 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_negation.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_negation.expr.result-ast @@ -3,7 +3,6 @@ Apply( @1-5 Var { module_name: "", ident: "whee", - suffixed: 0, }, @0-1 Negate, ), @@ -14,7 +13,6 @@ Apply( @10-13 Var { module_name: "", ident: "foo", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_not.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_not.expr.result-ast index d4cb059869..7a50a7af86 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_not.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/apply_unary_not.expr.result-ast @@ -3,7 +3,6 @@ Apply( @1-5 Var { module_name: "", ident: "whee", - suffixed: 0, }, @0-1 Not, ), @@ -14,7 +13,6 @@ Apply( @10-13 Var { module_name: "", ident: "foo", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/basic_apply.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/basic_apply.expr.result-ast index 8222e64482..ae21012711 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/basic_apply.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/basic_apply.expr.result-ast @@ -2,7 +2,6 @@ Apply( @0-4 Var { module_name: "", ident: "whee", - suffixed: 0, }, [ @5-6 Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/basic_docs.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/basic_docs.expr.result-ast index d014439990..c74acaf899 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/basic_docs.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/basic_docs.expr.result-ast @@ -19,7 +19,6 @@ SpaceBefore( Body( @107-108 Identifier { ident: "x", - suffixed: 0, }, @111-112 Num( "5", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/basic_field.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/basic_field.expr.result-ast index ec4785f8ef..40c572be2e 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/basic_field.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/basic_field.expr.result-ast @@ -2,7 +2,6 @@ RecordAccess( Var { module_name: "", ident: "rec", - suffixed: 0, }, "field", ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/basic_var.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/basic_var.expr.result-ast index 1147c32572..ade68e0ead 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/basic_var.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/basic_var.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "", ident: "whee", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/bound_variable.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/bound_variable.expr.result-ast index 2ad0468fa0..c5b57b1c72 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/bound_variable.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/bound_variable.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "a", - suffixed: 0, }, @3-4 SpaceBefore( BoundVariable( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/call_with_newlines.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/call_with_newlines.expr.result-ast index dbe5b8bc40..1fb8443efb 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/call_with_newlines.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/call_with_newlines.expr.result-ast @@ -3,7 +3,6 @@ Apply( Var { module_name: "", ident: "f", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop.expr.result-ast index 0a5e3c8134..73825d7211 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "a", - suffixed: 0, }, @2-4 And, ), @@ -14,13 +13,11 @@ BinOps( [ @6-7 Identifier { ident: "x", - suffixed: 0, }, ], @9-10 Var { module_name: "", ident: "x", - suffixed: 0, }, ), [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop_with_spaces.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop_with_spaces.expr.result-ast index e466e52a99..8f28d9c753 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop_with_spaces.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/closure_in_binop_with_spaces.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "i", - suffixed: 0, }, @1-2 GreaterThan, ), @@ -15,13 +14,11 @@ BinOps( [ @3-4 Identifier { ident: "s", - suffixed: 0, }, ], @6-7 Var { module_name: "", ident: "s", - suffixed: 0, }, ), [ @@ -33,7 +30,6 @@ BinOps( @9-10 Var { module_name: "", ident: "a", - suffixed: 0, }, @8-9 Negate, ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_annotation.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_annotation.expr.result-ast index c2f019e00c..c389718463 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_annotation.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_annotation.expr.result-ast @@ -30,7 +30,6 @@ Defs( Var { module_name: "", ident: "q", - suffixed: 0, }, [ LineComment( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_def.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_def.moduledefs.result-ast index 409e302339..e7191ddbd3 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_def.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_def.moduledefs.result-ast @@ -21,7 +21,6 @@ Defs { Body( @0-3 Identifier { ident: "foo", - suffixed: 0, }, @6-7 Num( "1", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_expr_in_parens.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_expr_in_parens.expr.result-ast index 2a25a18fee..d4280e0b8b 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_expr_in_parens.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_expr_in_parens.expr.result-ast @@ -3,7 +3,6 @@ ParensAround( Var { module_name: "", ident: "i", - suffixed: 0, }, [ LineComment( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_tag_in_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_tag_in_def.expr.result-ast index 99d13eb900..e7bb56f766 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_tag_in_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/comment_after_tag_in_def.expr.result-ast @@ -22,7 +22,6 @@ Defs( SpaceBefore( Identifier { ident: "h", - suffixed: 0, }, [ LineComment( @@ -47,7 +46,6 @@ Defs( Var { module_name: "", ident: "j", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_colon_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_colon_def.expr.result-ast index d4e8786d12..2c37b21ab6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_colon_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_colon_def.expr.result-ast @@ -19,7 +19,6 @@ Defs( @0-1 SpaceAfter( Identifier { ident: "w", - suffixed: 0, }, [ LineComment( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_equals_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_equals_def.expr.result-ast index a1a738d72d..633f8a91c7 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_equals_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/comment_before_equals_def.expr.result-ast @@ -19,7 +19,6 @@ Defs( @0-1 SpaceAfter( Identifier { ident: "t", - suffixed: 0, }, [ LineComment( @@ -37,7 +36,6 @@ Defs( Var { module_name: "", ident: "e", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/crash.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/crash.expr.result-ast index 1e5b8c5ca9..88b452be8a 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/crash.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/crash.expr.result-ast @@ -98,13 +98,11 @@ Defs( @50-53 Var { module_name: "", ident: "try", - suffixed: 0, }, [ @54-57 Var { module_name: "", ident: "foo", - suffixed: 0, }, @59-73 ParensAround( Closure( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/def_without_newline.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/def_without_newline.expr.result-ast index 05b28b453a..6d30592907 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/def_without_newline.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/def_without_newline.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "a", - suffixed: 0, }, @2-3 BoundVariable( "b", @@ -29,6 +28,5 @@ Defs( @4-5 Var { module_name: "", ident: "i", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/destructure_tag_assignment.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/destructure_tag_assignment.expr.result-ast index 9a31651b2f..1adeb71343 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/destructure_tag_assignment.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/destructure_tag_assignment.expr.result-ast @@ -23,7 +23,6 @@ Defs( [ @6-9 Identifier { ident: "str", - suffixed: 0, }, ], ), @@ -47,7 +46,6 @@ Defs( Var { module_name: "", ident: "str", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/docs.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/docs.expr.result-ast index 478e67cb58..49f839bc4d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/docs.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/docs.expr.result-ast @@ -19,7 +19,6 @@ SpaceBefore( Body( @48-49 Identifier { ident: "x", - suffixed: 0, }, @52-53 Num( "5", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_update.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_update.expr.result-ast index 1fed85b8e0..f80fadf9a5 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_update.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_update.expr.result-ast @@ -2,7 +2,6 @@ RecordUpdate { update: @1-2 Var { module_name: "", ident: "e", - suffixed: 0, }, fields: [], } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/equals.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/equals.expr.result-ast index e4c4f015b4..76f314ce4f 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/equals.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/equals.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "x", - suffixed: 0, }, @1-3 Equals, ), @@ -12,6 +11,5 @@ BinOps( @3-4 Var { module_name: "", ident: "y", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/equals_with_spaces.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/equals_with_spaces.expr.result-ast index 1b83c1633e..420f432778 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/equals_with_spaces.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/equals_with_spaces.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "x", - suffixed: 0, }, @2-4 Equals, ), @@ -12,6 +11,5 @@ BinOps( @5-6 Var { module_name: "", ident: "y", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/extra_newline_in_parens.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/extra_newline_in_parens.expr.result-ast index a48fdc496b..9e696ac3a9 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/extra_newline_in_parens.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/extra_newline_in_parens.expr.result-ast @@ -33,7 +33,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/fn_with_record_arg.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/fn_with_record_arg.expr.result-ast index 408b7d5ae9..f33f093a01 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/fn_with_record_arg.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/fn_with_record_arg.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-5 Identifier { ident: "table", - suffixed: 0, }, @8-44 Function( [ @@ -57,7 +56,6 @@ Defs( AnnotatedBody { ann_pattern: @0-5 Identifier { ident: "table", - suffixed: 0, }, ann_type: @8-44 Function( [ @@ -95,7 +93,6 @@ Defs( comment: None, body_pattern: @45-50 Identifier { ident: "table", - suffixed: 0, }, body_expr: @53-89 Closure( [ @@ -103,7 +100,6 @@ Defs( [ @55-61 Identifier { ident: "height", - suffixed: 0, }, ], ), @@ -127,7 +123,6 @@ Defs( Var { module_name: "", ident: "table", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_ext_type.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_ext_type.expr.result-ast index 3e43d0515d..257d20d6eb 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_ext_type.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_ext_type.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-20 Function( [ @@ -56,7 +55,6 @@ Defs( AnnotatedBody { ann_pattern: @0-1 Identifier { ident: "f", - suffixed: 0, }, ann_type: @4-20 Function( [ @@ -93,19 +91,16 @@ Defs( comment: None, body_pattern: @21-22 Identifier { ident: "f", - suffixed: 0, }, body_expr: @25-32 Closure( [ @26-27 Identifier { ident: "x", - suffixed: 0, }, ], @31-32 Var { module_name: "", ident: "x", - suffixed: 0, }, ), }, @@ -116,7 +111,6 @@ Defs( @34-35 Var { module_name: "", ident: "f", - suffixed: 0, }, [ @36-47 Tuple( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_type.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_type.expr.result-ast index e2dfab3aa5..ef21c826a8 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_type.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/function_with_tuple_type.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-21 Function( [ @@ -48,7 +47,6 @@ Defs( AnnotatedBody { ann_pattern: @0-1 Identifier { ident: "f", - suffixed: 0, }, ann_type: @4-21 Function( [ @@ -77,13 +75,11 @@ Defs( comment: None, body_pattern: @22-23 Identifier { ident: "f", - suffixed: 0, }, body_expr: @26-42 Closure( [ @27-28 Identifier { ident: "x", - suffixed: 0, }, ], @32-42 Tuple( @@ -91,7 +87,6 @@ Defs( @33-34 Var { module_name: "", ident: "x", - suffixed: 0, }, @36-41 BinOps( [ @@ -99,7 +94,6 @@ Defs( @36-37 Var { module_name: "", ident: "x", - suffixed: 0, }, @38-39 Plus, ), @@ -119,7 +113,6 @@ Defs( @44-45 Var { module_name: "", ident: "f", - suffixed: 0, }, [ @46-48 Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/if_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/if_def.expr.result-ast index 06a07173dc..b5f729a47a 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/if_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/if_def.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-4 Identifier { ident: "iffy", - suffixed: 0, }, @5-6 Num( "5", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/lambda_in_chain.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/lambda_in_chain.expr.result-ast index e0beaaca98..60a1e1f6c9 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/lambda_in_chain.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/lambda_in_chain.expr.result-ast @@ -18,7 +18,6 @@ BinOps( Var { module_name: "Str", ident: "toUtf8", - suffixed: 0, }, [ Newline, @@ -32,14 +31,12 @@ BinOps( @28-36 Var { module_name: "List", ident: "map", - suffixed: 0, }, [ @37-54 Closure( [ @38-42 Identifier { ident: "byte", - suffixed: 0, }, ], @46-54 BinOps( @@ -48,7 +45,6 @@ BinOps( @46-50 Var { module_name: "", ident: "byte", - suffixed: 0, }, @51-52 Plus, ), @@ -71,6 +67,5 @@ BinOps( @58-70 Var { module_name: "List", ident: "reverse", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/lambda_indent.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/lambda_indent.expr.result-ast index b084e428a6..7e6382ca70 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/lambda_indent.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/lambda_indent.expr.result-ast @@ -2,7 +2,6 @@ Closure( [ @1-2 Identifier { ident: "x", - suffixed: 0, }, ], @8-9 SpaceBefore( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_indent_not_enough.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_indent_not_enough.expr.result-ast index 7150b56369..48f73696b8 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_indent_not_enough.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_indent_not_enough.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-6 Identifier { ident: "myList", - suffixed: 0, }, @9-57 List( Collection { @@ -39,7 +38,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, @@ -49,7 +47,6 @@ Defs( Var { module_name: "", ident: "b", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_no_trailing_comma.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_no_trailing_comma.expr.result-ast index 238c7e64d2..f9f33d2f02 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_no_trailing_comma.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_no_trailing_comma.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-6 Identifier { ident: "myList", - suffixed: 0, }, @9-25 List( [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_with_trailing_comma.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_with_trailing_comma.expr.result-ast index 5e5391dced..622b1b9d9d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_with_trailing_comma.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/list_closing_same_indent_with_trailing_comma.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-6 Identifier { ident: "myList", - suffixed: 0, }, @9-26 List( Collection { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/list_minus_newlines.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/list_minus_newlines.expr.result-ast index f45bd3f8e4..89d20368d7 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/list_minus_newlines.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/list_minus_newlines.expr.result-ast @@ -19,6 +19,5 @@ BinOps( @6-7 Var { module_name: "", ident: "i", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/list_patterns.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/list_patterns.expr.result-ast index d0ef7ccd87..99f74fc8cb 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/list_patterns.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/list_patterns.expr.result-ast @@ -75,19 +75,15 @@ When( [ @61-62 Identifier { ident: "a", - suffixed: 0, }, @64-65 Identifier { ident: "b", - suffixed: 0, }, @67-68 Identifier { ident: "c", - suffixed: 0, }, @70-71 Identifier { ident: "d", - suffixed: 0, }, ], ), @@ -108,11 +104,9 @@ When( [ @82-83 Identifier { ident: "a", - suffixed: 0, }, @85-86 Identifier { ident: "b", - suffixed: 0, }, @88-90 ListRest( None, @@ -139,11 +133,9 @@ When( ), @105-106 Identifier { ident: "c", - suffixed: 0, }, @108-109 Identifier { ident: "d", - suffixed: 0, }, ], ), @@ -180,7 +172,6 @@ When( [ @132-133 Identifier { ident: "a", - suffixed: 0, }, ], ), @@ -218,7 +209,6 @@ When( ), @160-161 Identifier { ident: "x", - suffixed: 0, }, ], ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/mixed_docs.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/mixed_docs.expr.result-ast index eafa5c4e61..ec6f2288f3 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/mixed_docs.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/mixed_docs.expr.result-ast @@ -19,7 +19,6 @@ SpaceBefore( Body( @113-114 Identifier { ident: "x", - suffixed: 0, }, @117-118 Num( "5", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/module_def_newline.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/module_def_newline.moduledefs.result-ast index 1dc714efb1..e333a08770 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/module_def_newline.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/module_def_newline.moduledefs.result-ast @@ -17,7 +17,6 @@ Defs { Body( @0-4 Identifier { ident: "main", - suffixed: 0, }, @11-24 SpaceBefore( Defs( @@ -40,7 +39,6 @@ Defs { Body( @11-12 Identifier { ident: "i", - suffixed: 0, }, @15-17 Num( "64", @@ -52,7 +50,6 @@ Defs { Var { module_name: "", ident: "i", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing.expr.result-ast index 9c39991e6b..ba2df50c34 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing.expr.result-ast @@ -2,18 +2,15 @@ Backpassing( [ @0-1 Identifier { ident: "x", - suffixed: 0, }, @3-4 Identifier { ident: "y", - suffixed: 0, }, ], @8-23 Apply( @8-17 Var { module_name: "List", ident: "map2", - suffixed: 0, }, [ @18-20 List( @@ -32,7 +29,6 @@ Backpassing( @25-26 Var { module_name: "", ident: "x", - suffixed: 0, }, @27-28 Plus, ), @@ -40,7 +36,6 @@ Backpassing( @29-30 Var { module_name: "", ident: "y", - suffixed: 0, }, ), [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_in_def.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_in_def.moduledefs.result-ast index 2dd61eaf94..a94ee98745 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_in_def.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_in_def.moduledefs.result-ast @@ -17,25 +17,21 @@ Defs { Body( @0-4 Identifier { ident: "main", - suffixed: 0, }, @12-50 SpaceBefore( Backpassing( [ @12-16 Identifier { ident: "arg1", - suffixed: 0, }, @18-22 Identifier { ident: "arg2", - suffixed: 0, }, ], @26-30 Apply( @26-27 Var { module_name: "", ident: "f", - suffixed: 0, }, [ @28-30 Record( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_with_apply.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_with_apply.expr.result-ast index b02b069b12..95b0dae500 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_with_apply.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multi_backpassing_with_apply.expr.result-ast @@ -12,13 +12,11 @@ Backpassing( ), @5-6 Identifier { ident: "r", - suffixed: 0, }, ], @10-11 Var { module_name: "", ident: "a", - suffixed: 0, }, @12-13 SpaceBefore( Tag( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string.expr.result-ast index 7024b68ada..708bdb8a46 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string.expr.result-ast @@ -29,7 +29,6 @@ Defs( Body( @0-1 Identifier { ident: "a", - suffixed: 0, }, @4-22 Str( Line( @@ -53,7 +52,6 @@ Defs( Body( @23-24 Identifier { ident: "b", - suffixed: 0, }, @27-49 Str( Block( @@ -79,7 +77,6 @@ Defs( Body( @50-51 Identifier { ident: "c", - suffixed: 0, }, @58-92 SpaceBefore( Str( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string_in_apply.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string_in_apply.expr.result-ast index ccc923d944..16882ddfcc 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string_in_apply.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_string_in_apply.expr.result-ast @@ -2,7 +2,6 @@ Apply( @0-1 Var { module_name: "", ident: "e", - suffixed: 0, }, [ @1-10 Str( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature.expr.result-ast index 5df9570956..a9bc089be5 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @8-10 SpaceBefore( Record { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature_with_comment.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature_with_comment.expr.result-ast index be8e41d37e..94891b4ff3 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature_with_comment.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multiline_type_signature_with_comment.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @17-19 SpaceBefore( Record { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/multiple_fields.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/multiple_fields.expr.result-ast index 1652a4e2e3..856d51e722 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/multiple_fields.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/multiple_fields.expr.result-ast @@ -4,7 +4,6 @@ RecordAccess( Var { module_name: "", ident: "rec", - suffixed: 0, }, "abc", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/neg_inf_float.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/neg_inf_float.expr.result-ast index 44f4c1fe30..8ef03b6192 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/neg_inf_float.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/neg_inf_float.expr.result-ast @@ -2,7 +2,6 @@ UnaryOp( @1-4 Var { module_name: "", ident: "inf", - suffixed: 0, }, @0-1 Negate, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/negative_in_apply_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/negative_in_apply_def.expr.result-ast index be0aa246bb..3cd40840d1 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/negative_in_apply_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/negative_in_apply_def.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-1 Identifier { ident: "a", - suffixed: 0, }, @2-9 Apply( @2-3 SpaceAfter( @@ -34,14 +33,12 @@ Defs( @6-7 Var { module_name: "", ident: "g", - suffixed: 0, }, @5-6 Negate, ), @8-9 Var { module_name: "", ident: "a", - suffixed: 0, }, ], Space, @@ -53,7 +50,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/nested_backpassing_no_newline_before.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/nested_backpassing_no_newline_before.expr.result-ast index f0d70cdcdf..ace33dc1fe 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/nested_backpassing_no_newline_before.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/nested_backpassing_no_newline_before.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-4 Identifier { ident: "main", - suffixed: 0, }, @11-71 SpaceBefore( Defs( @@ -41,20 +40,17 @@ Defs( Body( @11-15 Identifier { ident: "task", - suffixed: 0, }, @18-62 Backpassing( [ @18-22 Identifier { ident: "file", - suffixed: 0, }, ], @43-46 SpaceBefore( Var { module_name: "", ident: "foo", - suffixed: 0, }, [ Newline, @@ -64,7 +60,6 @@ Defs( Var { module_name: "", ident: "bar", - suffixed: 0, }, [ Newline, @@ -78,7 +73,6 @@ Defs( Var { module_name: "", ident: "task", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_annotation.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_annotation.moduledefs.result-ast index 10532ec2bf..50d2f14b0d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_annotation.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_annotation.moduledefs.result-ast @@ -17,7 +17,6 @@ Defs { Body( @0-4 Identifier { ident: "main", - suffixed: 0, }, @11-115 SpaceBefore( Defs( @@ -40,7 +39,6 @@ Defs { Annotation( @11-23 Identifier { ident: "wrappedNotEq", - suffixed: 0, }, @26-38 Function( [ @@ -61,7 +59,6 @@ Defs { AnnotatedBody { ann_pattern: @11-23 Identifier { ident: "wrappedNotEq", - suffixed: 0, }, ann_type: @26-38 Function( [ @@ -81,17 +78,14 @@ Defs { comment: None, body_pattern: @43-55 Identifier { ident: "wrappedNotEq", - suffixed: 0, }, body_expr: @58-93 Closure( [ @59-63 Identifier { ident: "num1", - suffixed: 0, }, @65-69 Identifier { ident: "num2", - suffixed: 0, }, ], @81-93 SpaceBefore( @@ -101,7 +95,6 @@ Defs { @81-85 Var { module_name: "", ident: "num1", - suffixed: 0, }, @86-88 NotEquals, ), @@ -109,7 +102,6 @@ Defs { @89-93 Var { module_name: "", ident: "num2", - suffixed: 0, }, ), [ @@ -125,7 +117,6 @@ Defs { @99-111 Var { module_name: "", ident: "wrappedNotEq", - suffixed: 0, }, [ @112-113 Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_without_newline.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_without_newline.expr.result-ast index d9b69d85d8..c0cf621ea6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_without_newline.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/nested_def_without_newline.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-1 Identifier { ident: "x", - suffixed: 0, }, @2-7 Defs( Defs { @@ -40,7 +39,6 @@ Defs( Annotation( @2-3 Identifier { ident: "a", - suffixed: 0, }, @4-5 BoundVariable( "n", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/nested_if.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/nested_if.expr.result-ast index 95f8f3bb8e..c4542c48eb 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/nested_if.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/nested_if.expr.result-ast @@ -4,7 +4,6 @@ If( @3-5 Var { module_name: "", ident: "t1", - suffixed: 0, }, @13-14 SpaceBefore( SpaceAfter( @@ -24,7 +23,6 @@ If( @23-25 Var { module_name: "", ident: "t2", - suffixed: 0, }, @33-34 SpaceBefore( SpaceAfter( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_after_equals.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_after_equals.expr.result-ast index ca35054854..87a156b495 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_after_equals.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_after_equals.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-1 Identifier { ident: "x", - suffixed: 0, }, @8-9 SpaceBefore( Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_and_spaces_before_less_than.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_and_spaces_before_less_than.expr.result-ast index b23933af04..76ea5c917c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_and_spaces_before_less_than.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_and_spaces_before_less_than.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-1 Identifier { ident: "x", - suffixed: 0, }, @4-13 BinOps( [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast index c60a44392d..7f98b39683 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast @@ -102,14 +102,12 @@ Full { Body( @199-203 Identifier { ident: "main", - suffixed: 0, }, @210-246 SpaceBefore( Apply( @210-221 Var { module_name: "Stdout", ident: "line", - suffixed: 0, }, [ @222-246 Str( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_alias_application.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_alias_application.expr.result-ast index dfafa5e235..727ea8ca75 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_alias_application.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_alias_application.expr.result-ast @@ -43,7 +43,6 @@ Defs( Var { module_name: "", ident: "p", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_def.expr.result-ast index 8afad66f73..f1cdadca77 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_type_def.expr.result-ast @@ -32,7 +32,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/one_backpassing.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/one_backpassing.expr.result-ast index 1cc468a214..963976ac90 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/one_backpassing.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/one_backpassing.expr.result-ast @@ -3,7 +3,6 @@ SpaceBefore( [ @18-19 Identifier { ident: "x", - suffixed: 0, }, ], @23-32 ParensAround( @@ -11,13 +10,11 @@ SpaceBefore( [ @25-26 Identifier { ident: "y", - suffixed: 0, }, ], @30-31 Var { module_name: "", ident: "y", - suffixed: 0, }, ), ), @@ -25,7 +22,6 @@ SpaceBefore( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/one_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/one_def.expr.result-ast index c0e34bffa3..d5d5b85144 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/one_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/one_def.expr.result-ast @@ -19,7 +19,6 @@ SpaceBefore( Body( @18-19 Identifier { ident: "x", - suffixed: 0, }, @20-21 Num( "5", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/one_spaced_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/one_spaced_def.expr.result-ast index 8fd4f97daf..38c887ba9c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/one_spaced_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/one_spaced_def.expr.result-ast @@ -19,7 +19,6 @@ SpaceBefore( Body( @18-19 Identifier { ident: "x", - suffixed: 0, }, @22-23 Num( "5", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_destructure_first_item_in_body.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_destructure_first_item_in_body.expr.result-ast index d852df0050..152d1e596d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_destructure_first_item_in_body.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_destructure_first_item_in_body.expr.result-ast @@ -23,7 +23,6 @@ Defs( [ @7-9 Identifier { ident: "it", - suffixed: 0, }, ], ), @@ -31,7 +30,6 @@ Defs( @12-14 Var { module_name: "", ident: "id", - suffixed: 0, }, [ @16-21 ParensAround( @@ -58,7 +56,6 @@ Defs( @23-25 Var { module_name: "", ident: "it", - suffixed: 0, }, [ @26-28 Record( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_expr_with_arguments.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_expr_with_arguments.expr.result-ast index 2a65fad0a1..c42661df16 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_expr_with_arguments.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_expr_with_arguments.expr.result-ast @@ -6,12 +6,10 @@ Apply( @5-6 Var { module_name: "", ident: "m", - suffixed: 0, }, @7-8 Var { module_name: "", ident: "n", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern.expr.result-ast index 5994d242a4..0dd1a3462e 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "n", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern_with_arguments.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern_with_arguments.expr.result-ast index 60417da473..9694879ba4 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern_with_arguments.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_reference_pattern_with_arguments.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "n", - suffixed: 0, }, [ WhenBranch { @@ -15,11 +14,9 @@ When( [ @17-18 Identifier { ident: "n", - suffixed: 0, }, @19-20 Identifier { ident: "m", - suffixed: 0, }, ], ), @@ -34,7 +31,6 @@ When( @24-25 Var { module_name: "", ident: "n", - suffixed: 0, }, @26-27 Plus, ), @@ -42,7 +38,6 @@ When( @28-29 Var { module_name: "", ident: "m", - suffixed: 0, }, ), guard: None, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_type_def_with_newline.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_type_def_with_newline.expr.result-ast index fe8798cc4d..0ee155bf93 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_type_def_with_newline.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_type_def_with_newline.expr.result-ast @@ -40,7 +40,6 @@ Defs( Annotation( @0-1 Identifier { ident: "a", - suffixed: 0, }, @2-3 BoundVariable( "e", @@ -51,6 +50,5 @@ Defs( @12-14 Var { module_name: "", ident: "e0", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_with_type_arguments.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_with_type_arguments.moduledefs.result-ast index b9ddb31515..f60cc590b6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_with_type_arguments.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_with_type_arguments.moduledefs.result-ast @@ -19,7 +19,6 @@ Defs { vars: [ @9-10 Identifier { ident: "a", - suffixed: 0, }, ], }, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_app_with_record.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_app_with_record.expr.result-ast index 672ab7737c..bad6ae5651 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_app_with_record.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_app_with_record.expr.result-ast @@ -18,13 +18,11 @@ Defs( Body( @0-1 Identifier { ident: "x", - suffixed: 0, }, @4-29 Apply( @4-7 Var { module_name: "", ident: "foo", - suffixed: 0, }, [ @9-28 ParensAround( @@ -32,7 +30,6 @@ Defs( @9-12 Var { module_name: "", ident: "baz", - suffixed: 0, }, [ @13-28 Record( @@ -45,7 +42,6 @@ Defs( @22-26 Var { module_name: "", ident: "blah", - suffixed: 0, }, ), [ @@ -72,7 +68,6 @@ Defs( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_colon_in_record.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_colon_in_record.expr.result-ast index 8928c919d3..c99bc7d791 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_colon_in_record.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_colon_in_record.expr.result-ast @@ -18,13 +18,11 @@ Defs( Body( @0-1 Identifier { ident: "x", - suffixed: 0, }, @4-22 Apply( @4-7 Var { module_name: "", ident: "foo", - suffixed: 0, }, [ @8-22 Record( @@ -40,7 +38,6 @@ Defs( Var { module_name: "", ident: "blah", - suffixed: 0, }, [ Newline, @@ -67,7 +64,6 @@ Defs( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_list.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_list.expr.result-ast index 83616357e3..7796fc43a0 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_list.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_list.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-1 Identifier { ident: "a", - suffixed: 0, }, @4-17 List( [ @@ -50,7 +49,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_record.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_record.expr.result-ast index 71bae23921..3b9dba7114 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/outdented_record.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/outdented_record.expr.result-ast @@ -18,13 +18,11 @@ Defs( Body( @0-1 Identifier { ident: "x", - suffixed: 0, }, @4-23 Apply( @4-7 Var { module_name: "", ident: "foo", - suffixed: 0, }, [ @8-23 Record( @@ -37,7 +35,6 @@ Defs( @17-21 Var { module_name: "", ident: "blah", - suffixed: 0, }, ), [ @@ -60,7 +57,6 @@ Defs( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_type_def_apply.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_type_def_apply.expr.result-ast index 49829caf72..0321365086 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_type_def_apply.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_type_def_apply.expr.result-ast @@ -21,12 +21,10 @@ Defs( @2-5 Apply( @2-3 Identifier { ident: "b", - suffixed: 0, }, [ @4-5 Identifier { ident: "a", - suffixed: 0, }, ], ), @@ -43,7 +41,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_value_def_annotation.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_value_def_annotation.expr.result-ast index 70f3ba77c2..57adf1d09e 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_value_def_annotation.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parens_in_value_def_annotation.expr.result-ast @@ -19,7 +19,6 @@ Defs( @0-1 Apply( @0-1 Identifier { ident: "i", - suffixed: 0, }, [ @5-6 SpaceBefore( @@ -45,7 +44,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def.expr.result-ast index becae3c75c..fbc4c78d44 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def.expr.result-ast @@ -30,7 +30,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def_space_before.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def_space_before.expr.result-ast index b7bc94d2f7..3a8d3030da 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def_space_before.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parenthesized_type_def_space_before.expr.result-ast @@ -30,7 +30,6 @@ Defs( Var { module_name: "", ident: "a", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_apply.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_apply.expr.result-ast index f31de2f59c..c8000965eb 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_apply.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_apply.expr.result-ast @@ -3,7 +3,6 @@ Apply( Var { module_name: "", ident: "whee", - suffixed: 0, }, ), [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_basic_field.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_basic_field.expr.result-ast index afa6be43dd..4d2a918ff6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_basic_field.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_basic_field.expr.result-ast @@ -3,7 +3,6 @@ RecordAccess( Var { module_name: "", ident: "rec", - suffixed: 0, }, ), "field", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_field_qualified_var.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_field_qualified_var.expr.result-ast index 0f3f9bfd9a..3e7ca8d62c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_field_qualified_var.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_field_qualified_var.expr.result-ast @@ -3,7 +3,6 @@ RecordAccess( Var { module_name: "One.Two", ident: "rec", - suffixed: 0, }, ), "field", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_var.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_var.expr.result-ast index 3fd6d95044..dd22ad62c6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_var.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parenthetical_var.expr.result-ast @@ -2,6 +2,5 @@ ParensAround( Var { module_name: "", ident: "whee", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parse_alias.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parse_alias.expr.result-ast index ac22741c90..39188e402b 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parse_alias.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parse_alias.expr.result-ast @@ -20,11 +20,9 @@ Defs( vars: [ @5-6 Identifier { ident: "a", - suffixed: 0, }, @7-8 Identifier { ident: "b", - suffixed: 0, }, ], }, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/parse_as_ann.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/parse_as_ann.expr.result-ast index 903e760eca..c8c4f05ac3 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/parse_as_ann.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/parse_as_ann.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-3 Identifier { ident: "foo", - suffixed: 0, }, @6-33 As( @6-21 Apply( @@ -39,11 +38,9 @@ Defs( vars: [ @30-31 Identifier { ident: "a", - suffixed: 0, }, @32-33 Identifier { ident: "b", - suffixed: 0, }, ], }, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as.expr.result-ast index 9eacee15a0..b3c943b6ac 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as.expr.result-ast @@ -26,7 +26,6 @@ When( value: @24-25 Var { module_name: "", ident: "n", - suffixed: 0, }, guard: None, }, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as_list_rest.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as_list_rest.expr.result-ast index 25fa29a0f7..ff0aec60dc 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as_list_rest.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/pattern_as_list_rest.expr.result-ast @@ -2,7 +2,6 @@ When( @5-11 Var { module_name: "", ident: "myList", - suffixed: 0, }, [ WhenBranch { @@ -12,7 +11,6 @@ When( [ @20-25 Identifier { ident: "first", - suffixed: 0, }, @27-37 ListRest( Some( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/pattern_with_space_in_parens.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/pattern_with_space_in_parens.expr.result-ast index af885517fc..a6c26c8500 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/pattern_with_space_in_parens.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/pattern_with_space_in_parens.expr.result-ast @@ -13,7 +13,6 @@ When( @17-19 Var { module_name: "", ident: "rx", - suffixed: 0, }, ], Space, @@ -41,7 +40,6 @@ When( [ @42-44 Identifier { ident: "ry", - suffixed: 0, }, ], ), @@ -69,12 +67,10 @@ When( @65-75 Var { module_name: "Bool", ident: "false", - suffixed: 0, }, @76-78 Var { module_name: "", ident: "ry", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/plus_if.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/plus_if.expr.result-ast index a8be22d9bd..3375d05218 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/plus_if.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/plus_if.expr.result-ast @@ -13,7 +13,6 @@ BinOps( @7-16 Var { module_name: "Bool", ident: "true", - suffixed: 0, }, @22-23 Num( "1", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/pos_inf_float.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/pos_inf_float.expr.result-ast index b3206090c8..58a09d0639 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/pos_inf_float.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/pos_inf_float.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "", ident: "inf", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/qualified_field.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/qualified_field.expr.result-ast index df06143d8d..48c6df6e5d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/qualified_field.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/qualified_field.expr.result-ast @@ -4,7 +4,6 @@ RecordAccess( Var { module_name: "One.Two", ident: "rec", - suffixed: 0, }, "abc", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/qualified_var.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/qualified_var.expr.result-ast index 499ded409f..14a1b7ab96 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/qualified_var.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/qualified_var.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "One.Two", ident: "whee", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/record_destructure_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/record_destructure_def.expr.result-ast index 3f712d08f0..6f64d4ce7d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/record_destructure_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/record_destructure_def.expr.result-ast @@ -27,11 +27,9 @@ SpaceBefore( [ @20-21 Identifier { ident: "x", - suffixed: 0, }, @23-25 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -42,7 +40,6 @@ SpaceBefore( Body( @31-32 Identifier { ident: "y", - suffixed: 0, }, @35-36 Num( "6", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/record_func_type_decl.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/record_func_type_decl.expr.result-ast index 9f6fd3eca7..d2378aaacc 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/record_func_type_decl.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/record_func_type_decl.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @8-122 SpaceBefore( Record { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/record_type_with_function.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/record_type_with_function.expr.result-ast index 8b41d114ed..925374f414 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/record_type_with_function.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/record_type_with_function.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "x", - suffixed: 0, }, @4-77 Record { fields: [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/record_update.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/record_update.expr.result-ast index d9a77ede1d..8666e0151f 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/record_update.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/record_update.expr.result-ast @@ -2,7 +2,6 @@ RecordUpdate { update: @2-13 Var { module_name: "Foo.Bar", ident: "baz", - suffixed: 0, }, fields: [ @16-20 RequiredValue( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/record_with_if.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/record_with_if.expr.result-ast index 0daff00d70..43a85f4464 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/record_with_if.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/record_with_if.expr.result-ast @@ -9,7 +9,6 @@ Record( @8-17 Var { module_name: "Bool", ident: "true", - suffixed: 0, }, @23-24 Num( "1", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/single_arg_closure.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/single_arg_closure.expr.result-ast index 49b4408fff..8ad5df45e5 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/single_arg_closure.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/single_arg_closure.expr.result-ast @@ -2,7 +2,6 @@ Closure( [ @1-2 Identifier { ident: "a", - suffixed: 0, }, ], @6-8 Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/space_before_colon.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/space_before_colon.full.result-ast index 1c60290d60..34f4321b38 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/space_before_colon.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/space_before_colon.full.result-ast @@ -95,13 +95,11 @@ Full { Body( @98-102 Identifier { ident: "main", - suffixed: 0, }, @105-124 Apply( @105-116 Var { module_name: "Stdout", ident: "line", - suffixed: 0, }, [ @117-124 Str( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/space_only_after_minus.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/space_only_after_minus.expr.result-ast index 780b0034cd..45c8618b1c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/space_only_after_minus.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/space_only_after_minus.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "x", - suffixed: 0, }, @1-2 Minus, ), @@ -12,6 +11,5 @@ BinOps( @3-4 Var { module_name: "", ident: "y", - suffixed: 0, }, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/standalone_module_defs.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/standalone_module_defs.moduledefs.result-ast index e6eebed5ac..574c23a248 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/standalone_module_defs.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/standalone_module_defs.moduledefs.result-ast @@ -39,7 +39,6 @@ Defs { Body( @12-15 Identifier { ident: "foo", - suffixed: 0, }, @18-19 Num( "1", @@ -48,7 +47,6 @@ Defs { Body( @33-36 Identifier { ident: "bar", - suffixed: 0, }, @39-43 Str( PlainLine( @@ -59,7 +57,6 @@ Defs { Body( @44-47 Identifier { ident: "baz", - suffixed: 0, }, @50-57 Str( PlainLine( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/sub_var_with_spaces.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/sub_var_with_spaces.expr.result-ast index 77f4907408..2e4b2c87d2 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/sub_var_with_spaces.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/sub_var_with_spaces.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "x", - suffixed: 0, }, @2-3 Minus, ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast index 200b750619..1c715e9505 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed.expr.result-ast @@ -4,7 +4,6 @@ TaskAwaitBang( Var { module_name: "Stdout", ident: "line", - suffixed: 0, }, ), ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast index aafb449ee4..8bf74738c2 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_multiple_defs.moduledefs.result-ast @@ -17,7 +17,6 @@ Defs { Body( @0-4 Identifier { ident: "main", - suffixed: 0, }, @0-49 SpaceBefore( Defs( @@ -53,7 +52,6 @@ Defs { Var { module_name: "", ident: "a", - suffixed: 0, }, ), [ @@ -69,14 +67,12 @@ Defs { Body( @26-27 Identifier { ident: "x", - suffixed: 0, }, @26-39 Apply( @29-32 TaskAwaitBang( Var { module_name: "B", ident: "b", - suffixed: 0, }, ), [ @@ -96,14 +92,12 @@ Defs { Var { module_name: "", ident: "c", - suffixed: 0, }, ), [ @48-49 Var { module_name: "", ident: "x", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast index 9dbf333a7f..368792b05c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_nested.expr.result-ast @@ -3,7 +3,6 @@ Apply( Var { module_name: "", ident: "foo", - suffixed: 0, }, ), [ @@ -13,14 +12,12 @@ Apply( Var { module_name: "", ident: "bar", - suffixed: 0, }, ), [ @14-17 Var { module_name: "", ident: "baz", - suffixed: 0, }, ], Space, @@ -31,13 +28,11 @@ Apply( @22-26 Var { module_name: "", ident: "blah", - suffixed: 0, }, [ @27-32 Var { module_name: "", ident: "stuff", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast index 92c6aa5159..66f7aee6c0 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_one_def.full.result-ast @@ -115,7 +115,6 @@ Full { Body( @155-159 Identifier { ident: "main", - suffixed: 0, }, @199-299 SpaceBefore( Defs( @@ -155,7 +154,6 @@ Full { Var { module_name: "A", ident: "x", - suffixed: 0, }, ), ), @@ -178,7 +176,6 @@ Full { Var { module_name: "B", ident: "y", - suffixed: 0, }, ), [ @@ -220,7 +217,6 @@ Full { @290-293 Var { module_name: "C", ident: "z", - suffixed: 0, }, [ @294-299 Str( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast index 1c21de2d92..becab68b89 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/suffixed_optional_last.full.result-ast @@ -97,7 +97,6 @@ Full { Body( @88-92 Identifier { ident: "main", - suffixed: 0, }, @88-202 SpaceBefore( BinOps( @@ -120,7 +119,6 @@ Full { Var { module_name: "Cmd", ident: "new", - suffixed: 0, }, [ Newline, @@ -133,7 +131,6 @@ Full { Var { module_name: "Cmd", ident: "status", - suffixed: 0, }, [ Newline, @@ -147,7 +144,6 @@ Full { Var { module_name: "Task", ident: "mapErr", - suffixed: 0, }, ), [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/three_arg_closure.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/three_arg_closure.expr.result-ast index 26a23bee8a..002ee1df76 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/three_arg_closure.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/three_arg_closure.expr.result-ast @@ -2,15 +2,12 @@ Closure( [ @1-2 Identifier { ident: "a", - suffixed: 0, }, @4-5 Identifier { ident: "b", - suffixed: 0, }, @7-8 Identifier { ident: "c", - suffixed: 0, }, ], @12-14 Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/tuple_access_after_ident.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/tuple_access_after_ident.expr.result-ast index 9cce3468bb..15a50e472e 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/tuple_access_after_ident.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/tuple_access_after_ident.expr.result-ast @@ -18,7 +18,6 @@ Defs( Body( @0-3 Identifier { ident: "abc", - suffixed: 0, }, @6-15 Tuple( [ @@ -41,7 +40,6 @@ Defs( Var { module_name: "", ident: "abc", - suffixed: 0, }, "0", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type.expr.result-ast index 573cc4b73c..bec852d838 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @3-27 Function( [ @@ -58,7 +57,6 @@ Defs( AnnotatedBody { ann_pattern: @0-1 Identifier { ident: "f", - suffixed: 0, }, ann_type: @3-27 Function( [ @@ -97,19 +95,16 @@ Defs( comment: None, body_pattern: @28-29 Identifier { ident: "f", - suffixed: 0, }, body_expr: @32-39 Closure( [ @33-34 Identifier { ident: "x", - suffixed: 0, }, ], @38-39 Var { module_name: "", ident: "x", - suffixed: 0, }, ), }, @@ -120,7 +115,6 @@ Defs( @41-42 Var { module_name: "", ident: "f", - suffixed: 0, }, [ @43-49 Tuple( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type_ext.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type_ext.expr.result-ast index df8184713a..1814abae10 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type_ext.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/tuple_type_ext.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @3-29 Function( [ @@ -66,7 +65,6 @@ Defs( AnnotatedBody { ann_pattern: @0-1 Identifier { ident: "f", - suffixed: 0, }, ann_type: @3-29 Function( [ @@ -113,19 +111,16 @@ Defs( comment: None, body_pattern: @30-31 Identifier { ident: "f", - suffixed: 0, }, body_expr: @34-41 Closure( [ @35-36 Identifier { ident: "x", - suffixed: 0, }, ], @40-41 Var { module_name: "", ident: "x", - suffixed: 0, }, ), }, @@ -136,7 +131,6 @@ Defs( @43-44 Var { module_name: "", ident: "f", - suffixed: 0, }, [ @45-51 Tuple( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/two_arg_closure.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/two_arg_closure.expr.result-ast index f07167b93f..7e130c4d17 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/two_arg_closure.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/two_arg_closure.expr.result-ast @@ -2,11 +2,9 @@ Closure( [ @1-2 Identifier { ident: "a", - suffixed: 0, }, @4-5 Identifier { ident: "b", - suffixed: 0, }, ], @9-11 Num( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/two_backpassing.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/two_backpassing.expr.result-ast index 4189ee4e92..7490de4952 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/two_backpassing.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/two_backpassing.expr.result-ast @@ -3,7 +3,6 @@ SpaceBefore( [ @18-19 Identifier { ident: "x", - suffixed: 0, }, ], @23-32 ParensAround( @@ -11,13 +10,11 @@ SpaceBefore( [ @25-26 Identifier { ident: "y", - suffixed: 0, }, ], @30-31 Var { module_name: "", ident: "y", - suffixed: 0, }, ), ), @@ -26,7 +23,6 @@ SpaceBefore( [ @33-34 Identifier { ident: "z", - suffixed: 0, }, ], @38-40 Record( @@ -36,7 +32,6 @@ SpaceBefore( Var { module_name: "", ident: "x", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/two_branch_when.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/two_branch_when.expr.result-ast index c3221a2ece..7cab905c51 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/two_branch_when.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/two_branch_when.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/two_spaced_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/two_spaced_def.expr.result-ast index ac643dcb30..e306d5d495 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/two_spaced_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/two_spaced_def.expr.result-ast @@ -25,7 +25,6 @@ SpaceBefore( Body( @18-19 Identifier { ident: "x", - suffixed: 0, }, @22-23 Num( "5", @@ -34,7 +33,6 @@ SpaceBefore( Body( @24-25 Identifier { ident: "y", - suffixed: 0, }, @28-29 Num( "6", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/type_decl_with_underscore.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/type_decl_with_underscore.expr.result-ast index 3c2aabb021..9f125564b9 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/type_decl_with_underscore.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/type_decl_with_underscore.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-7 Identifier { ident: "doStuff", - suffixed: 0, }, @10-30 Function( [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_def.expr.result-ast index 252bcb9650..66dc5a24e1 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_def.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-3 Identifier { ident: "foo", - suffixed: 0, }, @6-9 Apply( "", @@ -29,7 +28,6 @@ Defs( AnnotatedBody { ann_pattern: @0-3 Identifier { ident: "foo", - suffixed: 0, }, ann_type: @6-9 Apply( "", @@ -39,7 +37,6 @@ Defs( comment: None, body_pattern: @10-13 Identifier { ident: "foo", - suffixed: 0, }, body_expr: @16-17 Num( "4", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_function_def.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_function_def.expr.result-ast index 382f3df20b..845dd2061c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_function_def.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/type_signature_function_def.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-3 Identifier { ident: "foo", - suffixed: 0, }, @6-24 Function( [ @@ -43,7 +42,6 @@ Defs( AnnotatedBody { ann_pattern: @0-3 Identifier { ident: "foo", - suffixed: 0, }, ann_type: @6-24 Function( [ @@ -67,13 +65,11 @@ Defs( comment: None, body_pattern: @25-28 Identifier { ident: "foo", - suffixed: 0, }, body_expr: @31-42 Closure( [ @32-33 Identifier { ident: "x", - suffixed: 0, }, @35-36 Underscore( "", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation.expr.result-ast index 864ecc9511..ded94596fe 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation.expr.result-ast @@ -2,7 +2,6 @@ UnaryOp( @1-4 Var { module_name: "", ident: "foo", - suffixed: 0, }, @0-1 Negate, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_access.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_access.expr.result-ast index deaee9980e..4094bd8ff4 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_access.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_access.expr.result-ast @@ -3,7 +3,6 @@ UnaryOp( Var { module_name: "", ident: "rec1", - suffixed: 0, }, "field", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_arg.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_arg.expr.result-ast index 5f8127a696..f42c07d6fd 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_arg.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_arg.expr.result-ast @@ -2,7 +2,6 @@ Apply( @0-4 Var { module_name: "", ident: "whee", - suffixed: 0, }, [ @6-8 Num( @@ -12,7 +11,6 @@ Apply( @10-13 Var { module_name: "", ident: "foo", - suffixed: 0, }, @9-10 Negate, ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_with_parens.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_with_parens.expr.result-ast index 670581e7e9..acb507d2b2 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_with_parens.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/unary_negation_with_parens.expr.result-ast @@ -4,7 +4,6 @@ UnaryOp( @2-6 Var { module_name: "", ident: "whee", - suffixed: 0, }, [ @8-10 Num( @@ -13,7 +12,6 @@ UnaryOp( @11-14 Var { module_name: "", ident: "foo", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/unary_not.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/unary_not.expr.result-ast index 3c3821a222..87170ac08a 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/unary_not.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/unary_not.expr.result-ast @@ -2,7 +2,6 @@ UnaryOp( @1-5 Var { module_name: "", ident: "blah", - suffixed: 0, }, @0-1 Not, ) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/unary_not_with_parens.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/unary_not_with_parens.expr.result-ast index 8f69ecaf66..b1f93ec376 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/unary_not_with_parens.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/unary_not_with_parens.expr.result-ast @@ -4,7 +4,6 @@ UnaryOp( @2-6 Var { module_name: "", ident: "whee", - suffixed: 0, }, [ @8-10 Num( @@ -13,7 +12,6 @@ UnaryOp( @11-14 Var { module_name: "", ident: "foo", - suffixed: 0, }, ], Space, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/underscore_backpassing.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/underscore_backpassing.expr.result-ast index 2c0286704c..9c957001dc 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/underscore_backpassing.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/underscore_backpassing.expr.result-ast @@ -10,13 +10,11 @@ SpaceBefore( [ @25-26 Identifier { ident: "y", - suffixed: 0, }, ], @30-31 Var { module_name: "", ident: "y", - suffixed: 0, }, ), ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/underscore_in_assignment_pattern.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/underscore_in_assignment_pattern.expr.result-ast index a1d230f7bf..247fe016c7 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/underscore_in_assignment_pattern.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/underscore_in_assignment_pattern.expr.result-ast @@ -44,7 +44,6 @@ Defs( [ @5-6 Identifier { ident: "x", - suffixed: 0, }, @7-8 Underscore( "", @@ -77,7 +76,6 @@ Defs( ), @27-28 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -157,7 +155,6 @@ Defs( [ @84-85 Identifier { ident: "x", - suffixed: 0, }, @86-87 Underscore( "", @@ -174,7 +171,6 @@ Defs( ), @97-98 Identifier { ident: "y", - suffixed: 0, }, ], ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/value_def_confusion.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/value_def_confusion.expr.result-ast index 53745d5b8d..1714a4810c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/value_def_confusion.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/value_def_confusion.expr.result-ast @@ -34,7 +34,6 @@ Defs( Annotation( @0-1 Identifier { ident: "a", - suffixed: 0, }, @2-3 Apply( "", @@ -48,7 +47,6 @@ Defs( Var { module_name: "", ident: "abc", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/var_else.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/var_else.expr.result-ast index f3cf61853e..7c569cf669 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/var_else.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/var_else.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "", ident: "elsewhere", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/var_if.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/var_if.expr.result-ast index 173bb327dc..2b95a15c2e 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/var_if.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/var_if.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "", ident: "iffy", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/var_is.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/var_is.expr.result-ast index 0e219b9817..2e84e98557 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/var_is.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/var_is.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "", ident: "isnt", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/var_minus_two.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/var_minus_two.expr.result-ast index 7c164151f8..499046f993 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/var_minus_two.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/var_minus_two.expr.result-ast @@ -4,7 +4,6 @@ BinOps( @0-1 Var { module_name: "", ident: "x", - suffixed: 0, }, @1-2 Minus, ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/var_then.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/var_then.expr.result-ast index 2d7da82523..b989386f63 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/var_then.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/var_then.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "", ident: "thenever", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/var_when.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/var_when.expr.result-ast index c07344fd15..d7d0d773f3 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/var_when.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/var_when.expr.result-ast @@ -1,5 +1,4 @@ Var { module_name: "", ident: "whenever", - suffixed: 0, } diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_if_guard.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_if_guard.expr.result-ast index cf9b8ac66b..bdd18adf88 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_if_guard.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_if_guard.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_assignment.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_assignment.expr.result-ast index fc34c96db6..4b4923faed 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_assignment.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_assignment.expr.result-ast @@ -18,13 +18,11 @@ Defs( Body( @0-1 Identifier { ident: "x", - suffixed: 0, }, @4-25 When( @9-10 Var { module_name: "", ident: "n", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function.expr.result-ast index 27f5e037fe..3f23f3af7d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function.expr.result-ast @@ -18,20 +18,17 @@ Defs( Body( @0-4 Identifier { ident: "func", - suffixed: 0, }, @7-43 Closure( [ @8-9 Identifier { ident: "x", - suffixed: 0, }, ], @13-43 When( @18-19 Var { module_name: "", ident: "n", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast index a100921104..51743bd8c5 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_function_python_style_indent.expr.result-ast @@ -18,20 +18,17 @@ Defs( Body( @0-4 Identifier { ident: "func", - suffixed: 0, }, @7-33 Closure( [ @8-9 Identifier { ident: "x", - suffixed: 0, }, ], @13-33 When( @18-19 Var { module_name: "", ident: "n", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens.expr.result-ast index 95123b0f3e..2844887e56 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens.expr.result-ast @@ -3,7 +3,6 @@ ParensAround( @6-7 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens_indented.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens_indented.expr.result-ast index 044a01583b..419e8c07ad 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens_indented.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_parens_indented.expr.result-ast @@ -4,7 +4,6 @@ ParensAround( @6-7 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_alternative_patterns.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_alternative_patterns.expr.result-ast index 6fb26c4f92..2b573943f6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_alternative_patterns.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_alternative_patterns.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_function_application.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_function_application.expr.result-ast index 7e392dc82e..1822dfa962 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_function_application.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_function_application.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { @@ -20,7 +19,6 @@ When( @19-26 Var { module_name: "Num", ident: "neg", - suffixed: 0, }, [ @32-33 SpaceBefore( diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_negative_numbers.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_negative_numbers.expr.result-ast index 16f5b1eb40..8c6a5e4e61 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_negative_numbers.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_negative_numbers.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_numbers.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_numbers.expr.result-ast index ae3cd76a66..8866aef903 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_numbers.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_numbers.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_records.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_records.expr.result-ast index 86e0e661dd..33e249c2a2 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_records.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_records.expr.result-ast @@ -2,7 +2,6 @@ When( @5-6 Var { module_name: "", ident: "x", - suffixed: 0, }, [ WhenBranch { @@ -12,7 +11,6 @@ When( [ @13-14 Identifier { ident: "y", - suffixed: 0, }, ], ), @@ -33,11 +31,9 @@ When( [ @25-26 Identifier { ident: "z", - suffixed: 0, }, @28-29 Identifier { ident: "w", - suffixed: 0, }, ], ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuple_in_record.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuple_in_record.expr.result-ast index 43540cf4b9..b36a554854 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuple_in_record.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuple_in_record.expr.result-ast @@ -32,7 +32,6 @@ When( ), @33-34 Identifier { ident: "x", - suffixed: 0, }, ], ), @@ -47,7 +46,6 @@ When( value: @40-41 Var { module_name: "", ident: "x", - suffixed: 0, }, guard: None, }, @@ -65,7 +63,6 @@ When( ), @53-54 Identifier { ident: "b", - suffixed: 0, }, ], ), @@ -89,7 +86,6 @@ When( @64-65 Var { module_name: "", ident: "b", - suffixed: 0, }, ), guard: None, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuples.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuples.expr.result-ast index 7ec0b709db..687ef1ac7c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuples.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_with_tuples.expr.result-ast @@ -20,7 +20,6 @@ When( ), @20-21 Identifier { ident: "x", - suffixed: 0, }, ], ), @@ -32,7 +31,6 @@ When( value: @26-27 Var { module_name: "", ident: "x", - suffixed: 0, }, guard: None, }, @@ -46,7 +44,6 @@ When( ), @33-34 Identifier { ident: "b", - suffixed: 0, }, ], ), @@ -67,7 +64,6 @@ When( @43-44 Var { module_name: "", ident: "b", - suffixed: 0, }, ), guard: None, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast index 31ef1b64fe..d2ddc4d1bd 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-38 Where( @4-16 Function( @@ -58,7 +57,6 @@ Defs( Var { module_name: "", ident: "f", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast index 1e42717f13..a0e3798f03 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast @@ -25,7 +25,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-73 Where( @4-10 Function( @@ -80,7 +79,6 @@ Defs( Annotation( @75-76 Identifier { ident: "f", - suffixed: 0, }, @79-154 Where( @79-85 SpaceAfter( @@ -148,7 +146,6 @@ Defs( Var { module_name: "", ident: "f", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast index e167ed2d3e..a900672d36 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-73 Where( @4-16 Function( @@ -78,7 +77,6 @@ Defs( Var { module_name: "", ident: "f", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast index 8f9c00c982..69fa499336 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-92 Where( @4-16 SpaceAfter( @@ -93,7 +92,6 @@ Defs( Var { module_name: "", ident: "f", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast index d26e4384af..c1ae8292a2 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-26 Where( @4-5 BoundVariable( @@ -44,7 +43,6 @@ Defs( Var { module_name: "", ident: "f", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast index 756c64d233..bbe411ff15 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-1 Identifier { ident: "f", - suffixed: 0, }, @4-40 Where( @4-12 SpaceAfter( @@ -58,7 +57,6 @@ Defs( Var { module_name: "", ident: "f", - suffixed: 0, }, [ Newline, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_ident.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_ident.expr.result-ast index 028c110f7b..e3d5c5e1b4 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_ident.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_ident.expr.result-ast @@ -18,7 +18,6 @@ Defs( Annotation( @0-5 Identifier { ident: "where", - suffixed: 0, }, @8-20 Record { fields: [ @@ -38,7 +37,6 @@ Defs( AnnotatedBody { ann_pattern: @0-5 Identifier { ident: "where", - suffixed: 0, }, ann_type: @8-20 Record { fields: [ @@ -57,7 +55,6 @@ Defs( comment: None, body_pattern: @21-26 Identifier { ident: "where", - suffixed: 0, }, body_expr: @29-39 Record( [ @@ -78,7 +75,6 @@ Defs( Var { module_name: "", ident: "where", - suffixed: 0, }, "where", ), From 20f277c132cdc59045c775e2068ab99c89898771 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sat, 27 Apr 2024 13:24:56 +1000 Subject: [PATCH 58/72] update later tests --- crates/compiler/can/tests/test_suffixed.rs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/crates/compiler/can/tests/test_suffixed.rs b/crates/compiler/can/tests/test_suffixed.rs index 61e0508fa1..80688ee1d4 100644 --- a/crates/compiler/can/tests/test_suffixed.rs +++ b/crates/compiler/can/tests/test_suffixed.rs @@ -772,7 +772,7 @@ mod suffixed_tests { Input name -> Stdout.line! "Hello, $(name)" "#, - r#"Defs { tags: [Index(2147483648)], regions: [@0-226], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main", suffixed: 0 }, @32-43 Apply(@32-43 Var { module_name: "Task", ident: "await", suffixed: 0 }, [@32-43 Var { module_name: "Stdin", ident: "line", suffixed: 0 }, @32-43 Closure([@23-29 Identifier { ident: "result", suffixed: 0 }], @61-226 When(@66-72 Var { module_name: "", ident: "result", suffixed: 0 }, [WhenBranch { patterns: [@96-99 Tag("End")], value: @127-137 Apply(@127-134 Var { module_name: "Task", ident: "ok", suffixed: 0 }, [@135-137 Record([])], Space), guard: None }, WhenBranch { patterns: [@159-169 Apply(@159-164 Tag("Input"), [@165-169 Identifier { ident: "name", suffixed: 0 }])], value: @197-226 Apply(@197-226 Var { module_name: "Stdout", ident: "line", suffixed: 0 }, [@210-226 Str(Line([Plaintext("Hello, "), Interpolated(@220-224 Var { module_name: "", ident: "name", suffixed: 0 })]))], Space), guard: None }]))], BangSuffix))] }"#, + r#"Defs { tags: [Index(2147483648)], regions: [@0-226], space_before: [Slice(start = 0, length = 0)], space_after: [Slice(start = 0, length = 0)], spaces: [], type_defs: [], value_defs: [Body(@0-4 Identifier { ident: "main" }, @32-43 Apply(@32-43 Var { module_name: "Task", ident: "await" }, [@32-43 Var { module_name: "Stdin", ident: "line" }, @32-43 Closure([@23-29 Identifier { ident: "result" }], @61-226 When(@66-72 Var { module_name: "", ident: "result" }, [WhenBranch { patterns: [@96-99 Tag("End")], value: @127-137 Apply(@127-134 Var { module_name: "Task", ident: "ok" }, [@135-137 Record([])], Space), guard: None }, WhenBranch { patterns: [@159-169 Apply(@159-164 Tag("Input"), [@165-169 Identifier { ident: "name" }])], value: @197-226 Apply(@197-226 Var { module_name: "Stdout", ident: "line" }, [@210-226 Str(Line([Plaintext("Hello, "), Interpolated(@220-224 Var { module_name: "", ident: "name" })]))], Space), guard: None }]))], BangSuffix))] }"#, ); } } @@ -789,14 +789,10 @@ mod test_suffixed_helpers { #[test] fn test_matching_answer() { - let loc_pat = Loc::at_zero(Pattern::Identifier { - ident: "#!a0", - suffixed: 0, - }); + let loc_pat = Loc::at_zero(Pattern::Identifier { ident: "#!a0" }); let loc_new = Loc::at_zero(Expr::Var { module_name: "", ident: "#!a0", - suffixed: 0, }); std::assert!(is_matching_intermediate_answer(&loc_pat, &loc_new)); @@ -804,19 +800,14 @@ mod test_suffixed_helpers { #[test] fn test_matching_answer_task_ok() { - let loc_pat = Loc::at_zero(Pattern::Identifier { - ident: "#!a0", - suffixed: 0, - }); + let loc_pat = Loc::at_zero(Pattern::Identifier { ident: "#!a0" }); let intermetiate = &[&Loc::at_zero(Expr::Var { module_name: "", ident: "#!a0", - suffixed: 0, })]; let task_ok = Loc::at_zero(Expr::Var { module_name: ModuleName::TASK, ident: "ok", - suffixed: 0, }); let loc_new = Loc::at_zero(Expr::Apply(&task_ok, intermetiate, CalledVia::BangSuffix)); From 74e531b994064467422cd5c6ca4fc94a9ea7d9e6 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sun, 28 Apr 2024 08:41:39 +1000 Subject: [PATCH 59/72] remove suffixed from Ident::Access and cleanup --- crates/compiler/can/src/expr.rs | 2 +- crates/compiler/parse/src/expr.rs | 11 +------ crates/compiler/parse/src/ident.rs | 44 ++------------------------- crates/compiler/parse/src/pattern.rs | 45 ---------------------------- 4 files changed, 4 insertions(+), 98 deletions(-) diff --git a/crates/compiler/can/src/expr.rs b/crates/compiler/can/src/expr.rs index db395cc404..fbd8e896d9 100644 --- a/crates/compiler/can/src/expr.rs +++ b/crates/compiler/can/src/expr.rs @@ -1169,7 +1169,7 @@ pub fn canonicalize_expr<'a>( output, ) } - ast::Expr::TaskAwaitBang(..) => todo!("canonicalize_expr on TaskAwaitBang"), + ast::Expr::TaskAwaitBang(..) => internal_error!("a Expr::TaskAwaitBang expression was not completed removed in desugar_value_def_suffixed"), ast::Expr::Tag(tag) => { let variant_var = var_store.fresh(); let ext_var = var_store.fresh(); diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 561db5fa50..8c20e7b3e8 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -254,11 +254,6 @@ fn parse_ident_seq<'a>( let expr = apply_expr_access_chain(arena, expr, suffixes); Ok((MadeProgress, Loc::at(loc_ident.region, expr), state)) } -// loc!(map_with_arena!( -// assign_or_destructure_identifier(), -// ident_to_expr -// )) -// } fn underscore_expression<'a>() -> impl Parser<'a, Expr<'a>, EExpr<'a>> { move |arena: &'a Bump, state: State<'a>, min_indent: u32| { @@ -2816,11 +2811,7 @@ fn ident_to_expr<'a>(arena: &'a Bump, src: Ident<'a>) -> Expr<'a> { match src { Ident::Tag(string) => Expr::Tag(string), Ident::OpaqueRef(string) => Expr::OpaqueRef(string), - Ident::Access { - module_name, - parts, - suffixed: _, - } => { + Ident::Access { module_name, parts } => { let mut iter = parts.iter(); // The first value in the iterator is the variable name, diff --git a/crates/compiler/parse/src/ident.rs b/crates/compiler/parse/src/ident.rs index 1179663f6b..8b28bb2ffa 100644 --- a/crates/compiler/parse/src/ident.rs +++ b/crates/compiler/parse/src/ident.rs @@ -42,7 +42,6 @@ pub enum Ident<'a> { Access { module_name: &'a str, parts: &'a [Accessor<'a>], - suffixed: u8, }, /// `.foo { foo: 42 }` or `.1 (1, 2, 3)` AccessorFunction(Accessor<'a>), @@ -193,12 +192,7 @@ pub fn parse_ident<'a>( match chomp_identifier_chain(arena, state.bytes(), state.pos()) { Ok((width, ident)) => { let state = advance_state!(state, width as usize)?; - if let Ident::Access { - module_name, - parts, - suffixed, - } = ident - { + if let Ident::Access { module_name, parts } = ident { if module_name.is_empty() { if let Some(first) = parts.first() { for keyword in crate::keyword::KEYWORDS.iter() { @@ -209,15 +203,7 @@ pub fn parse_ident<'a>( } } - return Ok(( - MadeProgress, - Ident::Access { - module_name, - parts, - suffixed, - }, - state, - )); + return Ok((MadeProgress, Ident::Access { module_name, parts }, state)); } Ok((MadeProgress, ident, state)) @@ -534,22 +520,9 @@ fn chomp_identifier_chain<'a>( chomped += width as usize; - // Parse any `!` suffixes - let suffixed = 0; - // while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) { - // if ch == '!' { - // suffixed += 1; - // chomped += width; - // } else { - // // we're done - // break; - // } - // } - let ident = Ident::Access { module_name, parts: parts.into_bump_slice(), - suffixed, }; Ok((chomped as u32, ident)) @@ -584,22 +557,9 @@ fn chomp_identifier_chain<'a>( // just one segment, starting with a lowercase letter; that's a normal identifier let value = unsafe { std::str::from_utf8_unchecked(&buffer[..chomped]) }; - // Parse any `!` suffixes - let suffixed = 0; - // while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) { - // if ch == '!' { - // suffixed += 1; - // chomped += width; - // } else { - // // we're done - // break; - // } - // } - let ident = Ident::Access { module_name: "", parts: arena.alloc([Accessor::RecordField(value)]), - suffixed, }; Ok((chomped as u32, ident)) diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index f32e11782b..a3616f0c13 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -12,7 +12,6 @@ use crate::string_literal::StrLikeLiteral; use bumpalo::collections::string::String; use bumpalo::collections::Vec; use bumpalo::Bump; -use roc_error_macros::internal_error; use roc_region::all::{Loc, Region}; /// Different patterns are supported in different circumstances. @@ -50,14 +49,6 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> let pattern_state = state.clone(); - // Return early with the suffixed statement - // match pattern.value { - // Pattern::Identifier { .. } if suffixed > 0 => { - // return Ok((MadeProgress, pattern, pattern_state)) - // } - // _ => {} - // } - let (pattern_spaces, state) = match space0_e(EPattern::AsKeyword).parse(arena, state, min_indent) { Err(_) => return Ok((MadeProgress, pattern, pattern_state)), @@ -393,42 +384,6 @@ fn loc_ident_pattern_help<'a>( Ok((MadeProgress, loc_pat, state)) } } - // Parse a statement that begins with a suffixed identifier, e.g. `Stdout.line! "Hello"` - Ident::Access { - module_name, - parts, - suffixed, - .. - } if suffixed > 0 => { - if module_name.is_empty() && parts.len() == 1 { - if let Accessor::RecordField(var) = &parts[0] { - Ok(( - MadeProgress, - Loc { - region: loc_ident.region, - value: Pattern::Identifier { ident: var }, - }, - state, - )) - } else { - internal_error!("unexpected suffixed TupleIndex"); - } - } else if let Accessor::RecordField(var) = &parts[0] { - return Ok(( - MadeProgress, - Loc { - region: loc_ident.region, - value: Pattern::QualifiedIdentifier { - module_name, - ident: var, - }, - }, - state, - )); - } else { - internal_error!("unexpected suffixed TupleIndex"); - } - } Ident::Access { module_name, parts, .. } => { From 240cb89350821e866cacfa494636e8054c6fb9c0 Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Sun, 28 Apr 2024 11:07:48 +1000 Subject: [PATCH 60/72] fix minor heading issue in tutorial --- www/content/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/content/tutorial.md b/www/content/tutorial.md index a186ec5b63..8f86835b90 100644 --- a/www/content/tutorial.md +++ b/www/content/tutorial.md @@ -1715,7 +1715,7 @@ We could also use `Task.onErr` instead, which is like `mapErr` except instead of Since we don't have any extra tasks to run, `mapErr` is more concise because we don't have to say `Task.err` at the end of each branch. -### [The \_ type](#_) {#\_} +### [The \_ type](#underscore) {#underscore} In a larger program, we might want to split `main` into different pieces for logic and handling errors: From 3742ef5f427c98b9cd7b384d066b83fb1a79ae9c Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sun, 28 Apr 2024 12:45:31 +0200 Subject: [PATCH 61/72] update basic-cli links to 0.10 --- crates/cli/tests/cli_run.rs | 2 +- crates/compiler/load_internal/tests/test_load.rs | 2 +- .../pass/newline_in_packages.full.formatted.roc | 2 +- .../snapshots/pass/newline_in_packages.full.result-ast | 2 +- .../tests/snapshots/pass/newline_in_packages.full.roc | 2 +- examples/cli/argsBROKEN.roc | 2 +- examples/cli/countdown.roc | 2 +- examples/cli/echo.roc | 2 +- examples/cli/env.roc | 2 +- examples/cli/fileBROKEN.roc | 2 +- examples/cli/form.roc | 2 +- examples/cli/http-get.roc | 2 +- examples/cli/ingested-file-bytes.roc | 2 +- examples/cli/ingested-file.roc | 2 +- examples/helloWorld.roc | 2 +- examples/inspect-logging.roc | 2 +- examples/parser/letter-counts.roc | 2 +- examples/parser/parse-movies-csv.roc | 2 +- www/content/platforms.md | 2 +- www/content/tutorial.md | 10 +++++----- 20 files changed, 24 insertions(+), 24 deletions(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index e67474321e..ac6f8524b1 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -949,7 +949,7 @@ mod cli_run { This roc file can print its own source code. The source is: app "ingested-file" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, "ingested-file.roc" as ownCode : Str, diff --git a/crates/compiler/load_internal/tests/test_load.rs b/crates/compiler/load_internal/tests/test_load.rs index ab03b7bd43..6929536638 100644 --- a/crates/compiler/load_internal/tests/test_load.rs +++ b/crates/compiler/load_internal/tests/test_load.rs @@ -1280,7 +1280,7 @@ fn roc_file_no_extension() { indoc!( r#" app "helloWorld" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc index 5e804ba783..e56f127e4a 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.formatted.roc @@ -1,7 +1,7 @@ app "hello" packages { pf: - "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", + "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br", } imports [pf.Stdout] provides [main] to pf diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast index 7f98b39683..9e480292f6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast @@ -24,7 +24,7 @@ Full { Newline, ], package_name: @31-145 PackageName( - "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", + "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br", ), }, [ diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc index 25148860d5..ba43f8a290 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.roc @@ -1,6 +1,6 @@ app "hello" packages { pf: -"https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" +"https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/examples/cli/argsBROKEN.roc b/examples/cli/argsBROKEN.roc index 1d301f4757..230322fc67 100644 --- a/examples/cli/argsBROKEN.roc +++ b/examples/cli/argsBROKEN.roc @@ -1,5 +1,5 @@ app "args" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout, pf.Arg, pf.Task.{ Task }] provides [main] to pf diff --git a/examples/cli/countdown.roc b/examples/cli/countdown.roc index 7f5173bbdc..957d68c6cf 100644 --- a/examples/cli/countdown.roc +++ b/examples/cli/countdown.roc @@ -1,5 +1,5 @@ app "countdown" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdin, pf.Stdout, pf.Task.{ await, loop }] provides [main] to pf diff --git a/examples/cli/echo.roc b/examples/cli/echo.roc index 7b6e04bc2b..baa1d00ce1 100644 --- a/examples/cli/echo.roc +++ b/examples/cli/echo.roc @@ -1,5 +1,5 @@ app "echo" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdin, pf.Stdout, pf.Task.{ Task }] provides [main] to pf diff --git a/examples/cli/env.roc b/examples/cli/env.roc index aef97a5978..29e89ff481 100644 --- a/examples/cli/env.roc +++ b/examples/cli/env.roc @@ -1,5 +1,5 @@ app "env" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout, pf.Stderr, pf.Env, pf.Task.{ Task }] provides [main] to pf diff --git a/examples/cli/fileBROKEN.roc b/examples/cli/fileBROKEN.roc index 007eb669bf..786bba35fa 100644 --- a/examples/cli/fileBROKEN.roc +++ b/examples/cli/fileBROKEN.roc @@ -1,5 +1,5 @@ app "file-io" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, pf.Stderr, diff --git a/examples/cli/form.roc b/examples/cli/form.roc index cb447acfa9..7393e76aeb 100644 --- a/examples/cli/form.roc +++ b/examples/cli/form.roc @@ -1,5 +1,5 @@ app "form" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdin, pf.Stdout, pf.Task.{ await, Task }] provides [main] to pf diff --git a/examples/cli/http-get.roc b/examples/cli/http-get.roc index eb922ea500..5e52961953 100644 --- a/examples/cli/http-get.roc +++ b/examples/cli/http-get.roc @@ -1,5 +1,5 @@ app "http-get" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Http, pf.Task.{ Task }, pf.Stdin, pf.Stdout] provides [main] to pf diff --git a/examples/cli/ingested-file-bytes.roc b/examples/cli/ingested-file-bytes.roc index ebf5b67cef..59a99f0027 100644 --- a/examples/cli/ingested-file-bytes.roc +++ b/examples/cli/ingested-file-bytes.roc @@ -1,5 +1,5 @@ app "ingested-file-bytes" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, "../../LICENSE" as license : _, # A type hole can also be used here. diff --git a/examples/cli/ingested-file.roc b/examples/cli/ingested-file.roc index f6a420909c..a8f8d6b76b 100644 --- a/examples/cli/ingested-file.roc +++ b/examples/cli/ingested-file.roc @@ -1,5 +1,5 @@ app "ingested-file" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, "ingested-file.roc" as ownCode : Str, diff --git a/examples/helloWorld.roc b/examples/helloWorld.roc index 172d634517..c44d458f07 100644 --- a/examples/helloWorld.roc +++ b/examples/helloWorld.roc @@ -1,5 +1,5 @@ app "helloWorld" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/examples/inspect-logging.roc b/examples/inspect-logging.roc index 0f69394d7d..bcc418c8fe 100644 --- a/examples/inspect-logging.roc +++ b/examples/inspect-logging.roc @@ -2,7 +2,7 @@ # Shows how Roc values can be logged # app "inspect-logging" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, Community, diff --git a/examples/parser/letter-counts.roc b/examples/parser/letter-counts.roc index 08769ba703..1a1ab4bf8c 100644 --- a/examples/parser/letter-counts.roc +++ b/examples/parser/letter-counts.roc @@ -1,6 +1,6 @@ app "example" packages { - cli: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", + cli: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br", parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br", } imports [ diff --git a/examples/parser/parse-movies-csv.roc b/examples/parser/parse-movies-csv.roc index fe1fd540f5..682252c5ef 100644 --- a/examples/parser/parse-movies-csv.roc +++ b/examples/parser/parse-movies-csv.roc @@ -1,6 +1,6 @@ app "example" packages { - pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br", + pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br", parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br", } imports [ diff --git a/www/content/platforms.md b/www/content/platforms.md index abb559033c..8b786a00d6 100644 --- a/www/content/platforms.md +++ b/www/content/platforms.md @@ -8,7 +8,7 @@ Here is a Roc application that prints `"Hello, World!"` to the command line: ```roc app "hello" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf diff --git a/www/content/tutorial.md b/www/content/tutorial.md index 8f86835b90..adb34c26fd 100644 --- a/www/content/tutorial.md +++ b/www/content/tutorial.md @@ -155,7 +155,7 @@ Make a file named `main.roc` and put this in it: ```roc app "hello" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf @@ -1455,7 +1455,7 @@ Let's take a closer look at the part of `main.roc` above the `main` def: ```roc app "hello" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf ``` @@ -1467,7 +1467,7 @@ The line `app "hello"` shows that this module is a Roc application. The "hello" The remaining lines all involve the [platform](https://github.com/roc-lang/roc/wiki/Roc-concepts-explained#platform) this application is built on: ```roc -packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } +packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf ``` @@ -1566,7 +1566,7 @@ Let's start with a basic "Hello World" program. ```roc app "cli-tutorial" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout] provides [main] to pf @@ -1600,7 +1600,7 @@ Let's change `main` to read a line from `stdin`, and then print what we got: ```roc app "cli-tutorial" - packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" } + packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [pf.Stdout, pf.Stdin, pf.Task] provides [main] to pf From 1c83abcb0386aaab61fdd11a7eb81d5550b47e9f Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 28 Apr 2024 08:20:31 -0400 Subject: [PATCH 62/72] Remove type annotations on CLI examples --- examples/cli/argsBROKEN.roc | 3 +-- examples/cli/echo.roc | 1 - examples/cli/env.roc | 1 - examples/cli/fileBROKEN.roc | 1 - examples/cli/form.roc | 1 - examples/cli/http-get.roc | 1 - examples/parser/parse-movies-csv.roc | 1 - 7 files changed, 1 insertion(+), 8 deletions(-) diff --git a/examples/cli/argsBROKEN.roc b/examples/cli/argsBROKEN.roc index 230322fc67..44d8f9eb30 100644 --- a/examples/cli/argsBROKEN.roc +++ b/examples/cli/argsBROKEN.roc @@ -3,7 +3,6 @@ app "args" imports [pf.Stdout, pf.Arg, pf.Task.{ Task }] provides [main] to pf -main : Task {} I32 main = args <- Arg.list |> Task.await parser = @@ -57,7 +56,7 @@ main = Err helpMenu -> {} <- Stdout.line helpMenu |> Task.await - Task.err 1 + Task.err [Exit 1 ""] runCmd = \cmd -> when cmd is diff --git a/examples/cli/echo.roc b/examples/cli/echo.roc index baa1d00ce1..0e15596a42 100644 --- a/examples/cli/echo.roc +++ b/examples/cli/echo.roc @@ -3,7 +3,6 @@ app "echo" imports [pf.Stdin, pf.Stdout, pf.Task.{ Task }] provides [main] to pf -main : Task {} I32 main = _ <- Task.await (Stdout.line "🗣 Shout into this cave and hear the echo! 👂👂👂") diff --git a/examples/cli/env.roc b/examples/cli/env.roc index 29e89ff481..93303f591f 100644 --- a/examples/cli/env.roc +++ b/examples/cli/env.roc @@ -3,7 +3,6 @@ app "env" imports [pf.Stdout, pf.Stderr, pf.Env, pf.Task.{ Task }] provides [main] to pf -main : Task {} I32 main = task = Env.decode "EDITOR" diff --git a/examples/cli/fileBROKEN.roc b/examples/cli/fileBROKEN.roc index 786bba35fa..9f35344029 100644 --- a/examples/cli/fileBROKEN.roc +++ b/examples/cli/fileBROKEN.roc @@ -11,7 +11,6 @@ app "file-io" ] provides [main] to pf -main : Task {} I32 main = path = Path.fromStr "out.txt" task = diff --git a/examples/cli/form.roc b/examples/cli/form.roc index 7393e76aeb..07c3cf40b9 100644 --- a/examples/cli/form.roc +++ b/examples/cli/form.roc @@ -3,7 +3,6 @@ app "form" imports [pf.Stdin, pf.Stdout, pf.Task.{ await, Task }] provides [main] to pf -main : Task {} I32 main = _ <- await (Stdout.line "What's your first name?") firstName <- await Stdin.line diff --git a/examples/cli/http-get.roc b/examples/cli/http-get.roc index 5e52961953..85fe7ccc00 100644 --- a/examples/cli/http-get.roc +++ b/examples/cli/http-get.roc @@ -3,7 +3,6 @@ app "http-get" imports [pf.Http, pf.Task.{ Task }, pf.Stdin, pf.Stdout] provides [main] to pf -main : Task {} I32 main = _ <- Task.await (Stdout.line "Enter a URL to fetch. It must contain a scheme like \"http://\" or \"https://\".") diff --git a/examples/parser/parse-movies-csv.roc b/examples/parser/parse-movies-csv.roc index 682252c5ef..5b6195b4e0 100644 --- a/examples/parser/parse-movies-csv.roc +++ b/examples/parser/parse-movies-csv.roc @@ -16,7 +16,6 @@ app "example" input : Str input = "Airplane!,1980,\"Robert Hays,Julie Hagerty\"\r\nCaddyshack,1980,\"Chevy Chase,Rodney Dangerfield,Ted Knight,Michael O'Keefe,Bill Murray\"" -main : Task {} * main = when CSV.parseStr movieInfoParser input is Ok movies -> From 1fd7f079c57dd66b192951a07950fcf08f25052b Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 28 Apr 2024 08:35:44 -0400 Subject: [PATCH 63/72] Fix typo in tutorial --- www/content/tutorial.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/www/content/tutorial.md b/www/content/tutorial.md index adb34c26fd..3e617b95eb 100644 --- a/www/content/tutorial.md +++ b/www/content/tutorial.md @@ -1630,7 +1630,7 @@ high-quality programs handle errors gracefully. Fortunately, we can do this nice If we wanted to add the type annotation to `main` that Roc is inferring for it, we would add this annotation: ```roc -main : Task {} [Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err] +main : Task {} [Exit I32, StdoutErr Stdout.Err, StdinErr Stdin.Err] main = ``` @@ -1638,7 +1638,7 @@ Let's break down what this type is saying: - `Task` tells us this is a `Task` type. Its two type parameters are just like the ones we saw in `Result` earlier: the first type tells us what this task will produce if it succeeds, and the other one tells us what it will produce if it fails. - `{}` tells us that this task always produces an empty record when it succeeds. (That is, it doesn't produce anything useful. Empty records don't have any information in them!) This is because the last task in `main` comes from `Stdout.line`, which doesn't produce anything. (In contrast, the `Stdin` task's first type parameter is a `Str`, because it produces a `Str` if it succeeds.) -- `[Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err]` tells us the different ways this task can fail. The `StdoutErr` and `StdinErr` tags are there becase we used `Stdout.line` and `Stdin.line`. We'll talk about `Exit I32` more in a moment. +- `[Exit I32, StdoutErr Stdout.Err, StdinErr Stdin.Err]` tells us the different ways this task can fail. The `StdoutErr` and `StdinErr` tags are there becase we used `Stdout.line` and `Stdin.line`. We'll talk about `Exit I32` more in a moment. To understand what the `Exit I32 Str` error means, let's try temporarily commenting out our current `main` and replacing it with this one: @@ -1666,7 +1666,7 @@ In summary: ### [Handling task failures](#handling-task-failures) {#handling-task-failures} -If the `main` task ends up failing with any other errors besides `Exit` (such as `StdoutErr` or `StdinErr`), then the `basic-cli` platform's automatic error handling will handle them by printing out words taken from the source code (such as "StdoutErr" and "StinErr"), which could lead to a bad experience for people using this program! +If the `main` task ends up failing with any other errors besides `Exit` (such as `StdoutErr` or `StdinErr`), then the `basic-cli` platform's automatic error handling will handle them by printing out words taken from the source code (such as "StdoutErr" and "StdinErr"), which could lead to a bad experience for people using this program! We can prevent that by gracefully handling the other error types, and then translating them into `Exit` errors so that they affect the program's exit code and don't result in the platform printing anything. A convenient way to make sure we've handled all the other errors is to keep our current type annotation for `main` but restore our old implementation: From 82660f1cae661226cb4123342e11b1e313d8067d Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 28 Apr 2024 08:36:48 -0400 Subject: [PATCH 64/72] Fix some Task imports in examples --- examples/parser/letter-counts.roc | 1 + examples/parser/parse-movies-csv.roc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/parser/letter-counts.roc b/examples/parser/letter-counts.roc index 1a1ab4bf8c..3a5fa19b43 100644 --- a/examples/parser/letter-counts.roc +++ b/examples/parser/letter-counts.roc @@ -6,6 +6,7 @@ app "example" imports [ cli.Stdout, cli.Stderr, + cli.Task, parser.Core.{ Parser, buildPrimitiveParser, many }, parser.String.{ parseStr }, ] diff --git a/examples/parser/parse-movies-csv.roc b/examples/parser/parse-movies-csv.roc index 5b6195b4e0..a5a5557708 100644 --- a/examples/parser/parse-movies-csv.roc +++ b/examples/parser/parse-movies-csv.roc @@ -6,7 +6,7 @@ app "example" imports [ pf.Stdout, pf.Stderr, - pf.Task.{ Task }, + pf.Task, parser.Core.{ Parser, map, keep }, parser.String.{ strFromUtf8 }, parser.CSV.{ CSV }, From 681df41fd3f3eeea38964675979e8caf26fffa47 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 28 Apr 2024 11:20:00 -0400 Subject: [PATCH 65/72] Fix some missing Task imports in examples --- examples/helloWorld.roc | 4 ++-- examples/inspect-logging.roc | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/helloWorld.roc b/examples/helloWorld.roc index c44d458f07..9e16783fc5 100644 --- a/examples/helloWorld.roc +++ b/examples/helloWorld.roc @@ -1,7 +1,7 @@ app "helloWorld" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } - imports [pf.Stdout] + imports [pf.Stdout, pf.Task] provides [main] to pf main = - Stdout.line "Hello, World!" + Stdout.line! "Hello, World!" diff --git a/examples/inspect-logging.roc b/examples/inspect-logging.roc index bcc418c8fe..ffbc5af6cf 100644 --- a/examples/inspect-logging.roc +++ b/examples/inspect-logging.roc @@ -5,6 +5,7 @@ app "inspect-logging" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, + pf.Task, Community, ] provides [main] to pf @@ -35,4 +36,4 @@ main = |> Community.addFriend 0 2 |> Community.addFriend 1 2 |> Inspect.toStr - |> Stdout.line + |> Stdout.line! From 7fcf13d14b77cc7ad2af4d17bc38e091b7cce53a Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 28 Apr 2024 11:26:37 -0400 Subject: [PATCH 66/72] Update some tests to use `!` --- crates/cli/tests/cli_run.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index ac6f8524b1..e2faf3c25d 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -952,12 +952,13 @@ mod cli_run { packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, + pf.Task, "ingested-file.roc" as ownCode : Str, ] provides [main] to pf main = - Stdout.line "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)" + Stdout.line! "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)" "# ), From 87d19c664bfa4d4d39c06c0535fc2b0526c205d2 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 28 Apr 2024 11:35:25 -0400 Subject: [PATCH 67/72] Update more examples to use `!` --- examples/cli/fileBROKEN.roc | 45 ++++++++++++++-------------- examples/cli/form.roc | 18 ++++------- examples/cli/http-get.roc | 37 ++++++++++------------- examples/cli/ingested-file-bytes.roc | 3 +- examples/cli/ingested-file.roc | 3 +- 5 files changed, 48 insertions(+), 58 deletions(-) diff --git a/examples/cli/fileBROKEN.roc b/examples/cli/fileBROKEN.roc index 9f35344029..51733fc028 100644 --- a/examples/cli/fileBROKEN.roc +++ b/examples/cli/fileBROKEN.roc @@ -11,33 +11,32 @@ app "file-io" ] provides [main] to pf +main : Task {} [Exit I32 Str] main = path = Path.fromStr "out.txt" - task = - cwd <- Env.cwd |> Task.await - cwdStr = Path.display cwd - _ <- Stdout.line "cwd: $(cwdStr)" |> Task.await - dirEntries <- Dir.list cwd |> Task.await + task = + cwd = Env.cwd! + + Stdout.line! "cwd: $(Path.display cwd)" + dirEntries = Dir.list! cwd contentsStr = Str.joinWith (List.map dirEntries Path.display) "\n " - _ <- Stdout.line "Directory contents:\n $(contentsStr)\n" |> Task.await - _ <- Stdout.line "Writing a string to out.txt" |> Task.await - _ <- File.writeUtf8 path "a string!" |> Task.await - contents <- File.readUtf8 path |> Task.await - Stdout.line "I read the file back. Its contents: \"$(contents)\"" + Stdout.line! "Directory contents:\n $(contentsStr)\n" + Stdout.line! "Writing a string to out.txt" + File.writeUtf8! path "a string!" + contents = File.readUtf8! path + Stdout.line! "I read the file back. Its contents: \"$(contents)\"" - Task.attempt task \result -> - when result is - Ok {} -> Stdout.line "Successfully wrote a string to out.txt" - Err err -> - msg = - when err is - FileWriteErr _ PermissionDenied -> "PermissionDenied" - FileWriteErr _ Unsupported -> "Unsupported" - FileWriteErr _ (Unrecognized _ other) -> other - FileReadErr _ _ -> "Error reading file" - _ -> "Uh oh, there was an error!" + when Task.result! task is + Ok {} -> Stdout.line! "Successfully wrote a string to out.txt" + Err err -> + msg = + when err is + FileWriteErr _ PermissionDenied -> "PermissionDenied" + FileWriteErr _ Unsupported -> "Unsupported" + FileWriteErr _ (Unrecognized _ other) -> other + FileReadErr _ _ -> "Error reading file" + _ -> "Uh oh, there was an error!" - {} <- Stderr.line msg |> Task.await - Task.err 1 + Task.err (Exit 1 msg) diff --git a/examples/cli/form.roc b/examples/cli/form.roc index 07c3cf40b9..b20ef6ee44 100644 --- a/examples/cli/form.roc +++ b/examples/cli/form.roc @@ -1,19 +1,13 @@ app "form" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } - imports [pf.Stdin, pf.Stdout, pf.Task.{ await, Task }] + imports [pf.Stdin, pf.Stdout, pf.Task] provides [main] to pf main = - _ <- await (Stdout.line "What's your first name?") - firstName <- await Stdin.line + Stdout.line! "What's your first name?" + firstName = Stdin.line! - _ <- await (Stdout.line "What's your last name?") - lastName <- await Stdin.line + Stdout.line! "What's your last name?" + lastName = Stdin.line! - Stdout.line "Hi, $(unwrap firstName) $(unwrap lastName)! 👋" - -unwrap : [Input Str, End] -> Str -unwrap = \input -> - when input is - Input line -> line - End -> "Received end of input (EOF)." + Stdout.line "Hi, $(firstName) $(lastName)! 👋" diff --git a/examples/cli/http-get.roc b/examples/cli/http-get.roc index 85fe7ccc00..6d3da47b8c 100644 --- a/examples/cli/http-get.roc +++ b/examples/cli/http-get.roc @@ -1,30 +1,25 @@ app "http-get" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } - imports [pf.Http, pf.Task.{ Task }, pf.Stdin, pf.Stdout] + imports [pf.Http, pf.Task, pf.Stdin, pf.Stdout] provides [main] to pf main = - _ <- Task.await (Stdout.line "Enter a URL to fetch. It must contain a scheme like \"http://\" or \"https://\".") + Stdout.line! "Enter a URL to fetch. It must contain a scheme like \"http://\" or \"https://\"." - input <- Task.await Stdin.line + url = Stdin.line! - when input is - End -> - Stdout.line "I received end-of-input (EOF) instead of a URL." + request = { + method: Get, + headers: [], + url, + mimeType: "", + body: [], + timeout: NoTimeout, + } - Input url -> - request = { - method: Get, - headers: [], - url, - mimeType: "", - body: [], - timeout: NoTimeout, - } + output = + Http.send request + |> Task.await \resp -> resp |> Http.handleStringResponse |> Task.fromResult + |> Task.onErr! \err -> crash (Http.errorToString err) - output <- Http.send request - |> Task.await \resp -> resp |> Http.handleStringResponse |> Task.fromResult - |> Task.onErr \err -> crash (Http.errorToString err) - |> Task.await - - Stdout.line output + Stdout.line! output diff --git a/examples/cli/ingested-file-bytes.roc b/examples/cli/ingested-file-bytes.roc index 59a99f0027..623f55d238 100644 --- a/examples/cli/ingested-file-bytes.roc +++ b/examples/cli/ingested-file-bytes.roc @@ -2,6 +2,7 @@ app "ingested-file-bytes" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, + pf.Task "../../LICENSE" as license : _, # A type hole can also be used here. ] provides [main] to pf @@ -12,4 +13,4 @@ main = |> List.map Num.toU64 |> List.sum |> Num.toStr - |> Stdout.line + |> Stdout.line! diff --git a/examples/cli/ingested-file.roc b/examples/cli/ingested-file.roc index a8f8d6b76b..a13c38ff81 100644 --- a/examples/cli/ingested-file.roc +++ b/examples/cli/ingested-file.roc @@ -2,9 +2,10 @@ app "ingested-file" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, + pf.Task, "ingested-file.roc" as ownCode : Str, ] provides [main] to pf main = - Stdout.line "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)" + Stdout.line! "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)" From b044f588c06c23e1741086fde00b098380ae8713 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sun, 28 Apr 2024 18:08:34 +0200 Subject: [PATCH 68/72] fix some cli run check tests --- examples/cli/argsBROKEN.roc | 9 ++++----- examples/cli/echo.roc | 11 +++++------ examples/cli/fileBROKEN.roc | 3 +-- examples/cli/http-get.roc | 21 +++++++++------------ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/examples/cli/argsBROKEN.roc b/examples/cli/argsBROKEN.roc index 44d8f9eb30..a58a0cf772 100644 --- a/examples/cli/argsBROKEN.roc +++ b/examples/cli/argsBROKEN.roc @@ -4,7 +4,7 @@ app "args" provides [main] to pf main = - args <- Arg.list |> Task.await + args = Arg.list! parser = divCmd = Arg.succeed (\dividend -> \divisor -> Div (Num.toF64 dividend) (Num.toF64 divisor)) @@ -54,13 +54,12 @@ main = |> Num.toStr |> Stdout.line - Err helpMenu -> - {} <- Stdout.line helpMenu |> Task.await - Task.err [Exit 1 ""] + Err helpMenuErr -> + Task.err (Exit 1 "unable to parse args: $(Inspect.toStr helpMenuErr)") runCmd = \cmd -> when cmd is Div n d -> n / d Log b n -> # log_b(n) = log_x(n) / log_x(b) for all x - runCmd (Div (Num.log n) (Num.log b)) + runCmd (Div (Num.log n) (Num.log b)) \ No newline at end of file diff --git a/examples/cli/echo.roc b/examples/cli/echo.roc index 0e15596a42..ee3dea1b3f 100644 --- a/examples/cli/echo.roc +++ b/examples/cli/echo.roc @@ -8,13 +8,12 @@ main = Task.loop {} tick -tick : {} -> Task [Step {}, Done {}] * +tick : {} -> Task [Step {}, Done {}] _ tick = \{} -> - shout <- Task.await Stdin.line - - when shout is - Input s -> Stdout.line (echo s) |> Task.map Step - End -> Stdout.line (echo "Received end of input (EOF).") |> Task.map Done + when Stdin.line |> Task.result! is + Ok str -> Stdout.line (echo str) |> Task.map Step + Err (StdinErr EndOfFile) -> Stdout.line (echo "Received end of input (EOF).") |> Task.map Done + Err (StdinErr err) -> Stdout.line (echo "Unable to read input $(Inspect.toStr err)") |> Task.map Done echo : Str -> Str echo = \shout -> diff --git a/examples/cli/fileBROKEN.roc b/examples/cli/fileBROKEN.roc index 51733fc028..237898fc7f 100644 --- a/examples/cli/fileBROKEN.roc +++ b/examples/cli/fileBROKEN.roc @@ -2,7 +2,6 @@ app "file-io" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, - pf.Stderr, pf.Task.{ Task }, pf.File, pf.Path, @@ -11,7 +10,7 @@ app "file-io" ] provides [main] to pf -main : Task {} [Exit I32 Str] +main : Task {} [Exit I32 Str]_ main = path = Path.fromStr "out.txt" diff --git a/examples/cli/http-get.roc b/examples/cli/http-get.roc index 6d3da47b8c..e6b79a4d2f 100644 --- a/examples/cli/http-get.roc +++ b/examples/cli/http-get.roc @@ -1,25 +1,22 @@ app "http-get" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } - imports [pf.Http, pf.Task, pf.Stdin, pf.Stdout] + imports [pf.Http, pf.Task, pf.Stdout] provides [main] to pf main = - Stdout.line! "Enter a URL to fetch. It must contain a scheme like \"http://\" or \"https://\"." - - url = Stdin.line! - request = { method: Get, headers: [], - url, + url: "http://www.example.com", mimeType: "", body: [], - timeout: NoTimeout, + timeout: TimeoutMilliseconds 5000, } - output = - Http.send request - |> Task.await \resp -> resp |> Http.handleStringResponse |> Task.fromResult - |> Task.onErr! \err -> crash (Http.errorToString err) + resp = Http.send! request - Stdout.line! output + output = when resp |> Http.handleStringResponse is + Err err -> crash (Http.errorToString err) + Ok body -> body + + Stdout.line output From 6c974070337d117879c43dfc1723ec9c448e78c2 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sun, 28 Apr 2024 18:13:42 +0200 Subject: [PATCH 69/72] fix ingested file bytes example --- examples/cli/ingested-file-bytes.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cli/ingested-file-bytes.roc b/examples/cli/ingested-file-bytes.roc index 623f55d238..d806bba251 100644 --- a/examples/cli/ingested-file-bytes.roc +++ b/examples/cli/ingested-file-bytes.roc @@ -2,7 +2,7 @@ app "ingested-file-bytes" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" } imports [ pf.Stdout, - pf.Task + pf.Task, "../../LICENSE" as license : _, # A type hole can also be used here. ] provides [main] to pf From 9d28e70cdce35e5bb2ecad00db2170525237111a Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sun, 28 Apr 2024 18:27:59 +0200 Subject: [PATCH 70/72] all fixed --- .../pass/newline_in_packages.full.result-ast | 20 ++++---- examples/cli/fileBROKEN.roc | 2 - examples/cli/form.roc | 1 - examples/cli/http-get.roc | 7 +-- examples/cli/ingested-file-bytes.roc | 8 +-- examples/inspect-logging.roc | 50 +++++++++---------- 6 files changed, 43 insertions(+), 45 deletions(-) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast index 9e480292f6..73f8eaa2af 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/newline_in_packages.full.result-ast @@ -17,13 +17,13 @@ Full { after: [], }, item: [ - @27-145 SpaceAfter( + @27-146 SpaceAfter( PackageEntry { shorthand: "pf", spaces_after_shorthand: [ Newline, ], - package_name: @31-145 PackageName( + package_name: @31-146 PackageName( "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br", ), }, @@ -44,7 +44,7 @@ Full { after: [], }, item: [ - @161-170 Package( + @162-171 Package( "pf", ModuleName( "Stdout", @@ -63,7 +63,7 @@ Full { after: [], }, entries: [ - @186-190 ExposedName( + @187-191 ExposedName( "main", ), ], @@ -73,7 +73,7 @@ Full { item: ToKeyword, after: [], }, - to: @195-197 ExistingPackage( + to: @196-198 ExistingPackage( "pf", ), }, @@ -85,7 +85,7 @@ Full { Index(2147483648), ], regions: [ - @199-246, + @200-247, ], space_before: [ Slice(start = 0, length = 2), @@ -100,17 +100,17 @@ Full { type_defs: [], value_defs: [ Body( - @199-203 Identifier { + @200-204 Identifier { ident: "main", }, - @210-246 SpaceBefore( + @211-247 SpaceBefore( Apply( - @210-221 Var { + @211-222 Var { module_name: "Stdout", ident: "line", }, [ - @222-246 Str( + @223-247 Str( PlainLine( "I'm a Roc application!", ), diff --git a/examples/cli/fileBROKEN.roc b/examples/cli/fileBROKEN.roc index 237898fc7f..b81f16c57a 100644 --- a/examples/cli/fileBROKEN.roc +++ b/examples/cli/fileBROKEN.roc @@ -16,11 +16,9 @@ main = task = cwd = Env.cwd! - Stdout.line! "cwd: $(Path.display cwd)" dirEntries = Dir.list! cwd contentsStr = Str.joinWith (List.map dirEntries Path.display) "\n " - Stdout.line! "Directory contents:\n $(contentsStr)\n" Stdout.line! "Writing a string to out.txt" File.writeUtf8! path "a string!" diff --git a/examples/cli/form.roc b/examples/cli/form.roc index b20ef6ee44..c605313f88 100644 --- a/examples/cli/form.roc +++ b/examples/cli/form.roc @@ -6,7 +6,6 @@ app "form" main = Stdout.line! "What's your first name?" firstName = Stdin.line! - Stdout.line! "What's your last name?" lastName = Stdin.line! diff --git a/examples/cli/http-get.roc b/examples/cli/http-get.roc index e6b79a4d2f..5c4cb54c84 100644 --- a/examples/cli/http-get.roc +++ b/examples/cli/http-get.roc @@ -15,8 +15,9 @@ main = resp = Http.send! request - output = when resp |> Http.handleStringResponse is - Err err -> crash (Http.errorToString err) - Ok body -> body + output = + when resp |> Http.handleStringResponse is + Err err -> crash (Http.errorToString err) + Ok body -> body Stdout.line output diff --git a/examples/cli/ingested-file-bytes.roc b/examples/cli/ingested-file-bytes.roc index d806bba251..67e6667cbf 100644 --- a/examples/cli/ingested-file-bytes.roc +++ b/examples/cli/ingested-file-bytes.roc @@ -10,7 +10,7 @@ app "ingested-file-bytes" main = # Due to how license is used, it will be a List U8. license - |> List.map Num.toU64 - |> List.sum - |> Num.toStr - |> Stdout.line! + |> List.map Num.toU64 + |> List.sum + |> Num.toStr + |> Stdout.line! diff --git a/examples/inspect-logging.roc b/examples/inspect-logging.roc index ffbc5af6cf..0883b5b7d0 100644 --- a/examples/inspect-logging.roc +++ b/examples/inspect-logging.roc @@ -12,28 +12,28 @@ app "inspect-logging" main = Community.empty - |> Community.addPerson { - firstName: "John", - lastName: "Smith", - age: 27, - hasBeard: Bool.true, - favoriteColor: Blue, - } - |> Community.addPerson { - firstName: "Debby", - lastName: "Johnson", - age: 47, - hasBeard: Bool.false, - favoriteColor: Green, - } - |> Community.addPerson { - firstName: "Jane", - lastName: "Doe", - age: 33, - hasBeard: Bool.false, - favoriteColor: RGB (255, 255, 0), - } - |> Community.addFriend 0 2 - |> Community.addFriend 1 2 - |> Inspect.toStr - |> Stdout.line! + |> Community.addPerson { + firstName: "John", + lastName: "Smith", + age: 27, + hasBeard: Bool.true, + favoriteColor: Blue, + } + |> Community.addPerson { + firstName: "Debby", + lastName: "Johnson", + age: 47, + hasBeard: Bool.false, + favoriteColor: Green, + } + |> Community.addPerson { + firstName: "Jane", + lastName: "Doe", + age: 33, + hasBeard: Bool.false, + favoriteColor: RGB (255, 255, 0), + } + |> Community.addFriend 0 2 + |> Community.addFriend 1 2 + |> Inspect.toStr + |> Stdout.line! From 5f26d5a097d9ee3569afa85fdeaa9fbf56fe10be Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 28 Apr 2024 13:15:39 -0400 Subject: [PATCH 71/72] Update tutorial CSS --- www/public/site.css | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/www/public/site.css b/www/public/site.css index 9178b6acdd..76a5dc2bde 100644 --- a/www/public/site.css +++ b/www/public/site.css @@ -39,6 +39,7 @@ --header-link-color: #1bbcb3; --header-link-hover: #222; --h1-color: #8055e4; + --tutorial-h3-color: #8c5ce3; /* Slightly darker than --primary-1, which looks washed-out in

        s */ } html { @@ -167,7 +168,7 @@ hr { } #sponsor-logos .logo-decem .cls-1 { - fill:#04021e; + fill: #04021e; } #sponsor-logos + p { @@ -731,7 +732,8 @@ li { font-style: normal; font-weight: 400; font-display: swap; - src: url("/fonts/permanent-marker-v16-latin/permanent-marker-v16-latin-regular.woff2") + src: + url("/fonts/permanent-marker-v16-latin/permanent-marker-v16-latin-regular.woff2") format("woff2"), url("/fonts/permanent-marker-v16-latin/permanent-marker-v16-latin-regular.woff") format("woff"); @@ -746,7 +748,8 @@ li { font-style: normal; font-weight: 400; font-display: swap; - src: url("/fonts/lato-v23-latin-ext_latin/lato-v23-latin-ext_latin-regular.woff2") + src: + url("/fonts/lato-v23-latin-ext_latin/lato-v23-latin-ext_latin-regular.woff2") format("woff2"), url("/fonts/lato-v23-latin-ext_latin/lato-v23-latin-ext_latin-regular.woff") format("woff"); @@ -760,7 +763,8 @@ li { font-style: normal; font-weight: 400; font-display: swap; - src: url("/fonts/lato-v23-latin/lato-v23-latin-regular.woff2") + src: + url("/fonts/lato-v23-latin/lato-v23-latin-regular.woff2") format("woff2"), url("/fonts/lato-v23-latin/lato-v23-latin-regular.woff") format("woff"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, @@ -774,7 +778,8 @@ li { font-style: normal; font-weight: 400; font-display: swap; - src: url("/fonts/source-code-pro-v22-latin-ext_latin/source-code-pro-v22-latin-ext_latin-regular.woff2") + src: + url("/fonts/source-code-pro-v22-latin-ext_latin/source-code-pro-v22-latin-ext_latin-regular.woff2") format("woff2"), url("/fonts/source-code-pro-v22-latin-ext_latin/source-code-pro-v22-latin-ext_latin-regular.woff") format("woff"); @@ -788,7 +793,8 @@ li { font-style: normal; font-weight: 400; font-display: swap; - src: url("/fonts/source-code-pro-v22-latin/source-code-pro-v22-latin-regular.woff2") + src: + url("/fonts/source-code-pro-v22-latin/source-code-pro-v22-latin-regular.woff2") format("woff2"), url("/fonts/source-code-pro-v22-latin/source-code-pro-v22-latin-regular.woff") format("woff"); @@ -825,6 +831,7 @@ li { --header-link-color: #9c7cea; --header-link-hover: #ddd; --h1-color: #1bc6bd; + --tutorial-h3-color: var(--primary-1); } .logo-dark { @@ -1137,7 +1144,8 @@ code .dim { color: #7c38f5; } -.interactive-desc code, .interactive-desc pre { +.interactive-desc code, +.interactive-desc pre { background: none; color: inherit; } @@ -1201,9 +1209,12 @@ code .dim { border: none; } +#tutorial-main h3 a { + color: var(--tutorial-h3-color); +} + #tutorial-main h1 a, #tutorial-main h2 a, -#tutorial-main h3 a, #tutorial-main h4 a, #tutorial-main h5 a { color: var(--header-link-color); @@ -1240,7 +1251,7 @@ code .dim { font-family: inherit; font-size: 1.65rem; line-height: 3rem; - text-shadow: 1px 1px 1px #010101; + margin-bottom: 0.5rem; } #tutorial-main h4 { @@ -1364,12 +1375,14 @@ code .dim { font-size: 18px; } -#homepage-repl-container #repl-prompt, #homepage-repl-container .input-line-prefix { +#homepage-repl-container #repl-prompt, +#homepage-repl-container .input-line-prefix { top: 1.25rem; color: var(--light-cyan); } -.input-line-prefix, #repl-prompt { +.input-line-prefix, +#repl-prompt { color: var(--cyan); color: var(--primary-2); } @@ -1481,7 +1494,7 @@ code .dim { in a light color scheme, and only white in dark mode. The name could be better! */ #homepage-repl-container .color-white { - color: #FFF; + color: #fff; } #repl-container .color-white { @@ -1489,15 +1502,13 @@ code .dim { } @media (prefers-color-scheme: dark) { - #homepage-repl-container .color-white { - color: #FFF; + color: #fff; } #repl-container .color-white { - color: #FFF; + color: #fff; } - } .bold { From 4b1433bfc68517e90f9f4774cd681d630849ca08 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Mon, 29 Apr 2024 09:02:54 -0400 Subject: [PATCH 72/72] Remove `Inspect` from /plans It exists already! Signed-off-by: Richard Feldman --- www/content/plans.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/www/content/plans.md b/www/content/plans.md index def218f733..ac8a527795 100644 --- a/www/content/plans.md +++ b/www/content/plans.md @@ -70,9 +70,3 @@ These are planned changes to how things work, which should be backwards-compatib This doesn't come up a lot, but [the feature](https://github.com/roc-lang/roc/issues/5504) basically means you can match on some tags in a `when`, and then have an `other ->` branch which has the tags you already matched on removed from the union. That means if you later do another `when` on the `other` value, you won't have to match on (or use `_ ->` to ignore) the tags you already matched in the first `when`, like you do today. This is planned but nobody is currently working on it. It's a quality of life improvement but doesn't unblock anything; today you can just add a `_ ->` branch to the inner `when`, which is undesirable but not a blocker. - -### [`Inspect` Inference](#inspect-inference) {#inspect-inference} - -When this lands, all Roc types will have a default `implements Inspect`, which you can override if desired. `dbg` will use it to display things, which in turn means you'll be able to customize `dbg` output. Also it will mean you can do things like turning any Roc type into a string and writing it to a log file. - -Note that in this design, functions will have an `Inspect` implementation which essentially renders them as `""` with no other information, and opaque types will be `""` by default unless you customize them. This is important because neither functions nor opaque types should expose their internal details, so that you can safely refactor them without causing regressions in distant parts of the code base because something depended on an internal implementation detail.