Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

parse blocks in case guards

+200 -29
+5 -24
compiler-core/src/format/tests.rs
··· 4653 4653 } 4654 4654 4655 4655 #[test] 4656 - fn remove_braces_case_guard() { 4657 - assert_format_rewrite!( 4658 - "fn main() { 4659 - let is_enabled = False 4660 - let is_confirmed = False 4661 - let is_admin = True 4662 - case is_enabled, is_confirmed, is_admin { 4663 - is_enabled, is_confirmed, is_admin if { is_enabled && is_confirmed } || is_admin -> 4664 - Nil 4665 - _, _, _ -> Nil 4666 - } 4667 - } 4668 - ", 4656 + fn do_not_remove_braces_from_case_guard() { 4657 + assert_format!( 4669 4658 "fn main() { 4670 4659 let is_enabled = False 4671 4660 let is_confirmed = False 4672 4661 let is_admin = True 4673 4662 case is_enabled, is_confirmed, is_admin { 4674 4663 is_enabled, is_confirmed, is_admin 4675 - if is_enabled && is_confirmed || is_admin 4664 + if { is_enabled && is_confirmed } || is_admin 4676 4665 -> Nil 4677 4666 _, _, _ -> Nil 4678 4667 } ··· 4682 4671 } 4683 4672 4684 4673 #[test] 4685 - fn remove_braces_case_guard_2() { 4686 - assert_format_rewrite!( 4674 + fn do_not_remove_braces_from_case_guard_2() { 4675 + assert_format!( 4687 4676 "fn main() { 4688 4677 let wibble = #(10, [0]) 4689 4678 case wibble { 4690 4679 wibble if True && { wibble.0 == 10 } -> Nil 4691 - _ -> Nil 4692 - } 4693 - } 4694 - ", 4695 - "fn main() { 4696 - let wibble = #(10, [0]) 4697 - case wibble { 4698 - wibble if True && wibble.0 == 10 -> Nil 4699 4680 _ -> Nil 4700 4681 } 4701 4682 }
+27 -5
compiler-core/src/parse.rs
··· 1809 1809 } 1810 1810 } 1811 1811 1812 - Some((_, Token::LeftBrace, _)) => { 1813 - // Nested guard expression 1812 + Some((start, Token::LeftBrace, _)) => { 1814 1813 self.advance(); 1815 - let guard = self.parse_clause_guard_inner(); 1816 - let _ = self.expect_one(&Token::RightBrace)?; 1817 - guard 1814 + Ok(Some(self.parse_case_clause_guard_block(start)?)) 1818 1815 } 1819 1816 1820 1817 t0 => { ··· 1828 1825 } 1829 1826 } 1830 1827 } 1828 + } 1829 + 1830 + fn parse_case_clause_guard_block( 1831 + &mut self, 1832 + start: u32, 1833 + ) -> Result<UntypedClauseGuard, ParseError> { 1834 + let body = self.parse_clause_guard_inner()?; 1835 + 1836 + let Some(body) = body else { 1837 + let location = match self.next_tok() { 1838 + Some((_, Token::RightBrace, end)) => SrcSpan { start, end }, 1839 + Some((_, _, _)) | None => SrcSpan { 1840 + start, 1841 + end: start + 1, 1842 + }, 1843 + }; 1844 + 1845 + return parse_error(ParseErrorType::EmptyGuardBlock, location); 1846 + }; 1847 + 1848 + let (_, end) = self.expect_one(&Token::RightBrace)?; 1849 + Ok(ClauseGuard::Block { 1850 + location: SrcSpan { start, end }, 1851 + value: Box::new(body), 1852 + }) 1831 1853 } 1832 1854 1833 1855 fn parse_record_in_clause_guard(
+10
compiler-core/src/parse/error.rs
··· 112 112 module: EcoString, 113 113 item: EcoString, 114 114 }, 115 + /// This can happen when there's an empty block in a case clause guard. 116 + /// For example: `_ if a == {}` 117 + EmptyGuardBlock, 115 118 } 116 119 117 120 pub(crate) struct ParseErrorDetails { ··· 625 628 .join("\n"), 626 629 hint: None, 627 630 label_text: "I was expecting either `/` or `.{` here.".into(), 631 + extra_labels: vec![], 632 + }, 633 + 634 + ParseErrorType::EmptyGuardBlock => ParseErrorDetails { 635 + text: "".into(), 636 + hint: None, 637 + label_text: "A clause guard block cannot be empty".into(), 628 638 extra_labels: vec![], 629 639 }, 630 640 }
+15
compiler-core/src/parse/snapshots/gleam_core__parse__tests__case_guard_with_empty_block.snap
··· 1 + --- 2 + source: compiler-core/src/parse/tests.rs 3 + expression: "case 1 {\n _ if a || {} -> 1\n}" 4 + --- 5 + ----- SOURCE CODE 6 + case 1 { 7 + _ if a || {} -> 1 8 + } 9 + 10 + ----- ERROR 11 + error: Syntax error 12 + ┌─ /src/parse/error.gleam:2:13 13 + 14 + 2 │ _ if a || {} -> 1 15 + │ ^^ A clause guard block cannot be empty
+125
compiler-core/src/parse/snapshots/gleam_core__parse__tests__case_guard_with_nested_blocks.snap
··· 1 + --- 2 + source: compiler-core/src/parse/tests.rs 3 + expression: "case 1 {\n _ if { 1 || { 1 || 1 } } || 1 -> 1\n}" 4 + --- 5 + [ 6 + Expression( 7 + Case { 8 + location: SrcSpan { 9 + start: 0, 10 + end: 48, 11 + }, 12 + subjects: [ 13 + Int { 14 + location: SrcSpan { 15 + start: 5, 16 + end: 6, 17 + }, 18 + value: "1", 19 + int_value: 1, 20 + }, 21 + ], 22 + clauses: Some( 23 + [ 24 + Clause { 25 + location: SrcSpan { 26 + start: 11, 27 + end: 46, 28 + }, 29 + pattern: [ 30 + Discard { 31 + name: "_", 32 + location: SrcSpan { 33 + start: 11, 34 + end: 12, 35 + }, 36 + type_: (), 37 + }, 38 + ], 39 + alternative_patterns: [], 40 + guard: Some( 41 + Or { 42 + location: SrcSpan { 43 + start: 16, 44 + end: 40, 45 + }, 46 + left: Block { 47 + location: SrcSpan { 48 + start: 16, 49 + end: 35, 50 + }, 51 + value: Or { 52 + location: SrcSpan { 53 + start: 18, 54 + end: 33, 55 + }, 56 + left: Constant( 57 + Int { 58 + location: SrcSpan { 59 + start: 18, 60 + end: 19, 61 + }, 62 + value: "1", 63 + int_value: 1, 64 + }, 65 + ), 66 + right: Block { 67 + location: SrcSpan { 68 + start: 23, 69 + end: 33, 70 + }, 71 + value: Or { 72 + location: SrcSpan { 73 + start: 25, 74 + end: 31, 75 + }, 76 + left: Constant( 77 + Int { 78 + location: SrcSpan { 79 + start: 25, 80 + end: 26, 81 + }, 82 + value: "1", 83 + int_value: 1, 84 + }, 85 + ), 86 + right: Constant( 87 + Int { 88 + location: SrcSpan { 89 + start: 30, 90 + end: 31, 91 + }, 92 + value: "1", 93 + int_value: 1, 94 + }, 95 + ), 96 + }, 97 + }, 98 + }, 99 + }, 100 + right: Constant( 101 + Int { 102 + location: SrcSpan { 103 + start: 39, 104 + end: 40, 105 + }, 106 + value: "1", 107 + int_value: 1, 108 + }, 109 + ), 110 + }, 111 + ), 112 + then: Int { 113 + location: SrcSpan { 114 + start: 45, 115 + end: 46, 116 + }, 117 + value: "1", 118 + int_value: 1, 119 + }, 120 + }, 121 + ], 122 + ), 123 + }, 124 + ), 125 + ]
+18
compiler-core/src/parse/tests.rs
··· 1912 1912 fn private_opaque_type_is_parsed() { 1913 1913 assert_parse_module!("opaque type Wibble { Wobble }"); 1914 1914 } 1915 + 1916 + #[test] 1917 + fn case_guard_with_nested_blocks() { 1918 + assert_parse!( 1919 + "case 1 { 1920 + _ if { 1 || { 1 || 1 } } || 1 -> 1 1921 + }" 1922 + ); 1923 + } 1924 + 1925 + #[test] 1926 + fn case_guard_with_empty_block() { 1927 + assert_error!( 1928 + "case 1 { 1929 + _ if a || {} -> 1 1930 + }" 1931 + ); 1932 + }