1use bhc_ast::{Alt, ArithSeq, Expr, FieldBind, Guard, GuardedRhs, Lit, ModuleName, Pat, Rhs, Stmt};
4use bhc_intern::Ident;
5use bhc_lexer::TokenKind;
6use bhc_span::Span;
7
8use crate::{ParseError, ParseResult, Parser};
9
10impl<'src> Parser<'src> {
11 pub fn parse_expr(&mut self) -> ParseResult<Expr> {
13 self.enter_recursion()?;
14 let result = self.parse_expr_guarded();
15 self.exit_recursion();
16 result
17 }
18
19 fn parse_expr_guarded(&mut self) -> ParseResult<Expr> {
20 let expr = self.parse_infix_expr(0)?;
21
22 if self.check(&TokenKind::DoubleColon) {
24 self.parse_type_annotation(expr)
25 } else {
26 Ok(expr)
27 }
28 }
29
30 fn parse_infix_expr(&mut self, min_prec: u8) -> ParseResult<Expr> {
32 let lhs = self.parse_prefix_expr()?;
33 self.continue_infix_expr(lhs, min_prec)
34 }
35
36 fn continue_infix_expr(&mut self, mut lhs: Expr, min_prec: u8) -> ParseResult<Expr> {
38 while let Some(tok) = self.current() {
39 let mut op_consumed = false;
41
42 let (op, prec, assoc) = match &tok.node.kind {
43 TokenKind::Operator(sym) => {
44 let (prec, assoc) = self.get_operator_info(sym.as_str());
45 if prec < min_prec {
46 break;
47 }
48 (Ident::new(*sym), prec, assoc)
49 }
50 TokenKind::Star => {
52 let (prec, assoc) = self.get_operator_info("*");
53 if prec < min_prec {
54 break;
55 }
56 (Ident::from_str("*"), prec, assoc)
57 }
58 TokenKind::Minus => {
60 let (prec, assoc) = self.get_operator_info("-");
61 if prec < min_prec {
62 break;
63 }
64 (Ident::from_str("-"), prec, assoc)
65 }
66 TokenKind::Percent => {
68 let (prec, assoc) = self.get_operator_info("%");
69 if prec < min_prec {
70 break;
71 }
72 (Ident::from_str("%"), prec, assoc)
73 }
74 TokenKind::Backtick => {
75 if 9 < min_prec {
80 break;
81 }
82 self.advance(); let Some(func_tok) = self.current() else {
84 return Err(ParseError::UnexpectedEof {
85 expected: "identifier".to_string(),
86 });
87 };
88 let func = match &func_tok.node.kind {
89 TokenKind::Ident(sym) => Ident::new(*sym),
90 TokenKind::ConId(sym) => Ident::new(*sym),
91 TokenKind::QualIdent(qual, name) => {
92 let full_name = format!("{}.{}", qual.as_str(), name.as_str());
94 Ident::from_str(&full_name)
95 }
96 _ => {
97 return Err(ParseError::Unexpected {
98 found: func_tok.node.kind.description().to_string(),
99 expected: "identifier".to_string(),
100 span: func_tok.span,
101 });
102 }
103 };
104 self.advance();
105 self.expect(&TokenKind::Backtick)?;
106 op_consumed = true; (func, 9, Assoc::Left) }
109 TokenKind::Dot => {
111 let (prec, assoc) = self.get_operator_info(".");
112 if prec < min_prec {
113 break;
114 }
115 (Ident::from_str("."), prec, assoc)
116 }
117 TokenKind::ConOperator(sym) => {
119 let (prec, assoc) = self.get_operator_info(sym.as_str());
120 if prec < min_prec {
121 break;
122 }
123 (Ident::new(*sym), prec, assoc)
124 }
125 TokenKind::QualOperator(qual, sym) => {
127 let (prec, assoc) = self.get_operator_info(sym.as_str());
128 if prec < min_prec {
129 break;
130 }
131 let full_name = format!("{}.{}", qual.as_str(), sym.as_str());
132 (Ident::from_str(&full_name), prec, assoc)
133 }
134 TokenKind::QualConOperator(qual, sym) => {
136 let (prec, assoc) = self.get_operator_info(sym.as_str());
137 if prec < min_prec {
138 break;
139 }
140 let full_name = format!("{}.{}", qual.as_str(), sym.as_str());
141 (Ident::from_str(&full_name), prec, assoc)
142 }
143 TokenKind::Bang => {
148 let (prec, assoc) = self.get_operator_info("!");
149 if prec < min_prec {
150 break;
151 }
152 (Ident::from_str("!"), prec, assoc)
153 }
154 TokenKind::Question => {
155 let (prec, assoc) = self.get_operator_info("?");
156 if prec < min_prec {
157 break;
158 }
159 (Ident::from_str("?"), prec, assoc)
160 }
161 TokenKind::Hash => {
162 let (prec, assoc) = self.get_operator_info("#");
163 if prec < min_prec {
164 break;
165 }
166 (Ident::from_str("#"), prec, assoc)
167 }
168 _ => break,
169 };
170
171 if prec < min_prec {
172 break;
173 }
174
175 let _op_span = self.current_span();
176 if !op_consumed {
177 self.advance();
178 }
179
180 let next_min_prec = match assoc {
181 Assoc::Left => prec + 1,
182 Assoc::Right => prec,
183 Assoc::None => prec + 1,
184 };
185
186 let rhs = self.parse_infix_expr(next_min_prec)?;
187 let span = lhs.span().merge(rhs.span());
188 lhs = Expr::Infix(Box::new(lhs), op, Box::new(rhs), span);
189 }
190
191 Ok(lhs)
192 }
193
194 fn parse_prefix_expr(&mut self) -> ParseResult<Expr> {
196 self.enter_recursion()?;
200 let result = self.parse_prefix_expr_guarded();
201 self.exit_recursion();
202 result
203 }
204
205 fn parse_prefix_expr_guarded(&mut self) -> ParseResult<Expr> {
206 if let Some(tok) = self.current() {
207 let is_minus = matches!(&tok.node.kind, TokenKind::Minus)
209 || matches!(&tok.node.kind, TokenKind::Operator(s) if s.as_str() == "-");
210 if is_minus {
211 let start = tok.span;
212 self.advance();
213 let expr = self.parse_prefix_expr()?;
214 let span = start.to(expr.span());
215 return Ok(Expr::Neg(Box::new(expr), span));
216 }
217 }
218
219 self.parse_app_expr()
220 }
221
222 fn parse_app_expr(&mut self) -> ParseResult<Expr> {
224 let mut expr = self.parse_atom_expr()?;
225
226 loop {
227 if self.check(&TokenKind::LBrace) && !matches!(expr, Expr::Con(_, _)) {
229 let start = expr.span();
230 expr = self.parse_record_update(expr, start)?;
231 continue;
232 }
233
234 if self.check(&TokenKind::At) {
236 self.advance(); let ty = self.parse_atype()?;
238 let span = expr.span().to(ty.span());
239 expr = Expr::TypeApp(Box::new(expr), ty, span);
240 continue;
241 }
242
243 if let Some(tok) = self.current() {
245 if self.is_atom_start(&tok.node.kind) {
246 let arg = self.parse_atom_expr()?;
247 let span = expr.span().to(arg.span());
248 expr = Expr::App(Box::new(expr), Box::new(arg), span);
249 continue;
250 }
251 }
252
253 break;
254 }
255
256 Ok(expr)
257 }
258
259 fn is_atom_start(&self, kind: &TokenKind) -> bool {
261 matches!(
262 kind,
263 TokenKind::Ident(_)
264 | TokenKind::QualIdent(_, _)
265 | TokenKind::ConId(_)
266 | TokenKind::QualConId(_, _)
267 | TokenKind::IntLit(_)
268 | TokenKind::FloatLit(_)
269 | TokenKind::CharLit(_)
270 | TokenKind::StringLit(_)
271 | TokenKind::LParen
272 | TokenKind::LBracket
273 | TokenKind::Backslash
274 | TokenKind::Let
275 | TokenKind::If
276 | TokenKind::Case
277 | TokenKind::Do
278 | TokenKind::Underscore )
280 }
281
282 fn parse_atom_expr(&mut self) -> ParseResult<Expr> {
284 let tok = self.current().ok_or(ParseError::UnexpectedEof {
285 expected: "expression".to_string(),
286 })?;
287
288 match &tok.node.kind.clone() {
289 TokenKind::Ident(sym)
290 if sym.as_str() == "lazy"
291 && self.pos + 1 < self.tokens.len()
292 && self.tokens[self.pos + 1].node.kind == TokenKind::LBrace =>
293 {
294 self.parse_lazy_expr()
295 }
296 TokenKind::Ident(sym) => {
297 let ident = Ident::new(*sym);
298 let span = tok.span;
299 self.advance();
300 Ok(Expr::Var(ident, span))
301 }
302
303 TokenKind::QualIdent(qualifier, name) => {
304 let module_name = ModuleName {
305 parts: vec![*qualifier],
306 span: tok.span,
307 };
308 let ident = Ident::new(*name);
309 let span = tok.span;
310 self.advance();
311 Ok(Expr::QualVar(module_name, ident, span))
312 }
313
314 TokenKind::ConId(sym) => {
315 let ident = Ident::new(*sym);
316 let span = tok.span;
317 self.advance();
318
319 if self.check(&TokenKind::LBrace) {
321 return self.parse_record_con(ident, span);
322 }
323
324 Ok(Expr::Con(ident, span))
325 }
326
327 TokenKind::QualConId(qualifier, name) => {
328 let module_name = ModuleName {
329 parts: vec![*qualifier],
330 span: tok.span,
331 };
332 let ident = Ident::new(*name);
333 let span = tok.span;
334 self.advance();
335
336 if self.check(&TokenKind::LBrace) {
338 return self.parse_qual_record_con(module_name, ident, span);
339 }
340
341 Ok(Expr::QualCon(module_name, ident, span))
342 }
343
344 TokenKind::IntLit(ref lit) => {
345 let span = tok.span;
346 let value = self.parse_int_literal(&lit.text, span)?;
347 self.advance();
348 Ok(Expr::Lit(Lit::Int(value), span))
349 }
350
351 TokenKind::FloatLit(ref lit) => {
352 let span = tok.span;
353 let value = self.parse_float_literal(&lit.text, span)?;
354 self.advance();
355 Ok(Expr::Lit(Lit::Float(value), span))
356 }
357
358 TokenKind::CharLit(c) => {
359 let span = tok.span;
360 let c = *c;
361 self.advance();
362 Ok(Expr::Lit(Lit::Char(c), span))
363 }
364
365 TokenKind::StringLit(s) => {
366 let span = tok.span;
367 let s = s.clone();
368 self.advance();
369 Ok(Expr::Lit(Lit::String(s), span))
370 }
371
372 TokenKind::LParen => self.parse_paren_expr(),
373
374 TokenKind::LBracket => self.parse_list_expr(),
375
376 TokenKind::Backslash => self.parse_lambda(),
377
378 TokenKind::Let => self.parse_let_expr(),
379
380 TokenKind::If => self.parse_if_expr(),
381
382 TokenKind::Case => self.parse_case_expr(),
383
384 TokenKind::Do => self.parse_do_expr(),
385
386 TokenKind::Underscore => {
387 let span = tok.span;
389 self.advance();
390 Ok(Expr::Wildcard(span))
391 }
392
393 _ => Err(ParseError::Unexpected {
394 found: tok.node.kind.description().to_string(),
395 expected: "expression".to_string(),
396 span: tok.span,
397 }),
398 }
399 }
400
401 pub(crate) fn parse_int_literal(&self, s: &str, span: Span) -> ParseResult<i64> {
403 let s = s.replace('_', "");
404 let value = if s.starts_with("0x") || s.starts_with("0X") {
405 i64::from_str_radix(&s[2..], 16)
406 } else if s.starts_with("0o") || s.starts_with("0O") {
407 i64::from_str_radix(&s[2..], 8)
408 } else if s.starts_with("0b") || s.starts_with("0B") {
409 i64::from_str_radix(&s[2..], 2)
410 } else {
411 s.parse()
412 };
413
414 value.map_err(|e| ParseError::InvalidLiteral {
415 message: e.to_string(),
416 span,
417 })
418 }
419
420 pub(crate) fn parse_float_literal(&self, s: &str, span: Span) -> ParseResult<f64> {
422 let s = s.replace('_', "");
423 s.parse()
424 .map_err(|e: std::num::ParseFloatError| ParseError::InvalidLiteral {
425 message: e.to_string(),
426 span,
427 })
428 }
429
430 fn get_operator_info(&self, op: &str) -> (u8, Assoc) {
432 match op {
434 "." => (9, Assoc::Right),
435 "^" | "^^" | "**" => (8, Assoc::Right),
436 "*" | "/" | "`div`" | "`mod`" => (7, Assoc::Left),
437 "+" | "-" => (6, Assoc::Left),
438 "<>" => (6, Assoc::Right),
439 ":" | "++" => (5, Assoc::Right),
440 "==" | "/=" | "<" | "<=" | ">" | ">=" | "`elem`" | "`notElem`" => (4, Assoc::None),
441 "<$>" | "<*>" | "<*" | "*>" => (4, Assoc::Left),
442 "<$" => (4, Assoc::Left),
443 "<|>" => (3, Assoc::Left),
444 "&&" => (3, Assoc::Right),
445 "||" => (2, Assoc::Right),
446 ">>=" | ">>" => (1, Assoc::Left),
447 "=<<" => (1, Assoc::Right),
448 "$" | "$!" => (0, Assoc::Right),
449 _ => (9, Assoc::Left), }
451 }
452
453 fn parse_paren_expr(&mut self) -> ParseResult<Expr> {
455 let start = self.current_span();
456 self.expect(&TokenKind::LParen)?;
457
458 if self.eat(&TokenKind::RParen) {
459 let span = start.to(self.tokens[self.pos - 1].span);
461 return Ok(Expr::Con(Ident::from_str("()"), span));
462 }
463
464 if self.check(&TokenKind::Comma) {
467 return self.parse_tuple_section(start, vec![None]);
468 }
469
470 if matches!(
475 self.current_kind(),
476 Some(TokenKind::Operator(_))
477 | Some(TokenKind::Star)
478 | Some(TokenKind::Percent)
479 | Some(TokenKind::Dot)
480 | Some(TokenKind::ConOperator(_))
481 | Some(TokenKind::QualOperator(_, _))
482 | Some(TokenKind::QualConOperator(_, _))
483 ) {
484 return self.parse_operator_section(start);
485 }
486
487 if matches!(self.current_kind(), Some(TokenKind::Minus)) {
489 if self.pos + 1 < self.tokens.len()
491 && matches!(self.tokens[self.pos + 1].node.kind, TokenKind::RParen)
492 {
493 return self.parse_operator_section(start);
495 }
496 }
498
499 if self.check(&TokenKind::Backtick) {
501 self.advance(); let Some(func_tok) = self.current() else {
503 return Err(ParseError::UnexpectedEof {
504 expected: "identifier".to_string(),
505 });
506 };
507 let func = match &func_tok.node.kind {
508 TokenKind::Ident(sym) => Ident::new(*sym),
509 TokenKind::ConId(sym) => Ident::new(*sym),
510 TokenKind::QualIdent(qual, name) => {
511 let full_name = format!("{}.{}", qual.as_str(), name.as_str());
512 Ident::from_str(&full_name)
513 }
514 _ => {
515 return Err(ParseError::Unexpected {
516 found: func_tok.node.kind.description().to_string(),
517 expected: "identifier".to_string(),
518 span: func_tok.span,
519 });
520 }
521 };
522 self.advance();
523 self.expect(&TokenKind::Backtick)?; let rhs = self.parse_app_expr()?;
527
528 let end = self.expect(&TokenKind::RParen)?;
529 let span = start.to(end.span);
530
531 let y = Ident::from_str("$section_arg");
533 let y_pat = Pat::Var(y, Span::DUMMY);
534 let y_expr = Expr::Var(y, Span::DUMMY);
535 let body = Expr::Infix(Box::new(y_expr), func, Box::new(rhs), span);
536 return Ok(Expr::Lam(vec![y_pat], Box::new(body), span));
537 }
538
539 let first = self.parse_prefix_expr()?;
542
543 let op_ident = match self.current_kind().cloned() {
545 Some(TokenKind::Operator(sym)) => Some(Ident::new(sym)),
546 Some(TokenKind::Star) => Some(Ident::from_str("*")),
547 Some(TokenKind::Minus) => Some(Ident::from_str("-")),
548 Some(TokenKind::Percent) => Some(Ident::from_str("%")),
549 Some(TokenKind::Dot) => Some(Ident::from_str(".")),
550 Some(TokenKind::ConOperator(sym)) => Some(Ident::new(sym)),
551 Some(TokenKind::QualOperator(qual, sym)) => {
552 let full_name = format!("{}.{}", qual.as_str(), sym.as_str());
553 Some(Ident::from_str(&full_name))
554 }
555 Some(TokenKind::QualConOperator(qual, sym)) => {
556 let full_name = format!("{}.{}", qual.as_str(), sym.as_str());
557 Some(Ident::from_str(&full_name))
558 }
559 _ => None,
560 };
561
562 if let Some(op) = op_ident {
563 self.advance();
564
565 if self.eat(&TokenKind::RParen) {
566 let span = start.to(self.tokens[self.pos - 1].span);
568 let y = Ident::from_str("$section_arg");
569 let y_pat = Pat::Var(y, Span::DUMMY);
570 let y_expr = Expr::Var(y, Span::DUMMY);
571 let body = Expr::Infix(Box::new(first), op, Box::new(y_expr), span);
572 return Ok(Expr::Lam(vec![y_pat], Box::new(body), span));
573 }
574
575 let (op_prec, op_assoc) = self.get_operator_info(op.name.as_str());
579 let next_min_prec = match op_assoc {
580 Assoc::Left => op_prec + 1,
581 Assoc::Right => op_prec,
582 Assoc::None => op_prec + 1,
583 };
584 let rhs = self.parse_infix_expr(next_min_prec)?;
585 let infix_span = first.span().merge(rhs.span());
586 let first_infix = Expr::Infix(Box::new(first), op, Box::new(rhs), infix_span);
587 let infix_expr = self.continue_infix_expr(first_infix, 0)?;
589
590 let infix_expr = if self.check(&TokenKind::DoubleColon) {
592 self.parse_type_annotation(infix_expr)?
593 } else {
594 infix_expr
595 };
596
597 if self.eat(&TokenKind::Comma) {
599 let mut exprs = vec![infix_expr];
600 loop {
601 exprs.push(self.parse_expr()?);
602 if !self.eat(&TokenKind::Comma) {
603 break;
604 }
605 }
606 let end = self.expect(&TokenKind::RParen)?;
607 let span = start.to(end.span);
608 return Ok(Expr::Tuple(exprs, span));
609 }
610
611 let end = self.expect(&TokenKind::RParen)?;
612 let span = start.to(end.span);
613 return Ok(Expr::Paren(Box::new(infix_expr), span));
614 }
615
616 if self.check(&TokenKind::Backtick) {
618 self.advance(); let Some(func_tok) = self.current() else {
621 return Err(ParseError::UnexpectedEof {
622 expected: "identifier".to_string(),
623 });
624 };
625 let func = match &func_tok.node.kind {
626 TokenKind::Ident(sym) => Ident::new(*sym),
627 TokenKind::ConId(sym) => Ident::new(*sym),
628 TokenKind::QualIdent(qual, name) => {
629 let full_name = format!("{}.{}", qual.as_str(), name.as_str());
630 Ident::from_str(&full_name)
631 }
632 _ => {
633 return Err(ParseError::Unexpected {
634 found: func_tok.node.kind.description().to_string(),
635 expected: "identifier".to_string(),
636 span: func_tok.span,
637 });
638 }
639 };
640 self.advance();
641 self.expect(&TokenKind::Backtick)?; if self.eat(&TokenKind::RParen) {
645 let span = start.to(self.tokens[self.pos - 1].span);
646 let y = Ident::from_str("$section_arg");
647 let y_pat = Pat::Var(y, Span::DUMMY);
648 let y_expr = Expr::Var(y, Span::DUMMY);
649 let body = Expr::Infix(Box::new(first), func, Box::new(y_expr), span);
650 return Ok(Expr::Lam(vec![y_pat], Box::new(body), span));
651 }
652
653 let (bt_prec, bt_assoc) = self.get_operator_info(func.name.as_str());
655 let bt_next_min = match bt_assoc {
656 Assoc::Left => bt_prec + 1,
657 Assoc::Right => bt_prec,
658 Assoc::None => bt_prec + 1,
659 };
660 let rhs = self.parse_infix_expr(bt_next_min)?;
661 let infix_span = first.span().merge(rhs.span());
662 let first_infix = Expr::Infix(Box::new(first), func, Box::new(rhs), infix_span);
663 let infix_expr = self.continue_infix_expr(first_infix, 0)?;
664
665 let infix_expr = if self.check(&TokenKind::DoubleColon) {
667 self.parse_type_annotation(infix_expr)?
668 } else {
669 infix_expr
670 };
671
672 if self.eat(&TokenKind::Comma) {
674 let mut exprs = vec![infix_expr];
675 loop {
676 exprs.push(self.parse_expr()?);
677 if !self.eat(&TokenKind::Comma) {
678 break;
679 }
680 }
681 let end = self.expect(&TokenKind::RParen)?;
682 let span = start.to(end.span);
683 return Ok(Expr::Tuple(exprs, span));
684 }
685
686 let end = self.expect(&TokenKind::RParen)?;
687 let span = start.to(end.span);
688 return Ok(Expr::Paren(Box::new(infix_expr), span));
689 }
690
691 if self.check(&TokenKind::DoubleColon) {
693 let annotated = self.parse_type_annotation(first)?;
694 if self.eat(&TokenKind::Comma) {
696 let mut exprs = vec![annotated];
697 loop {
698 exprs.push(self.parse_expr()?);
699 if !self.eat(&TokenKind::Comma) {
700 break;
701 }
702 }
703 let end = self.expect(&TokenKind::RParen)?;
704 let span = start.to(end.span);
705 return Ok(Expr::Tuple(exprs, span));
706 }
707 let end = self.expect(&TokenKind::RParen)?;
708 let span = start.to(end.span);
709 return Ok(Expr::Paren(Box::new(annotated), span));
710 }
711
712 if self.eat(&TokenKind::Comma) {
713 if self.check(&TokenKind::Comma) || self.check(&TokenKind::RParen) {
716 return self.parse_tuple_section(start, vec![Some(first), None]);
718 }
719
720 let mut exprs = vec![first];
722 loop {
723 exprs.push(self.parse_expr()?);
724 if !self.eat(&TokenKind::Comma) {
725 break;
726 }
727 if self.check(&TokenKind::Comma) || self.check(&TokenKind::RParen) {
729 let mut elements: Vec<Option<Expr>> = exprs.into_iter().map(Some).collect();
731 elements.push(None);
732 return self.parse_tuple_section(start, elements);
733 }
734 }
735 let end = self.expect(&TokenKind::RParen)?;
736 let span = start.to(end.span);
737 Ok(Expr::Tuple(exprs, span))
738 } else {
739 let end = self.expect(&TokenKind::RParen)?;
741 let span = start.to(end.span);
742 Ok(Expr::Paren(Box::new(first), span))
743 }
744 }
745
746 fn parse_tuple_section(
754 &mut self,
755 start: Span,
756 mut elements: Vec<Option<Expr>>,
757 ) -> ParseResult<Expr> {
758 loop {
760 if self.eat(&TokenKind::RParen) {
761 break;
762 }
763 if self.eat(&TokenKind::Comma) {
764 if self.check(&TokenKind::Comma) || self.check(&TokenKind::RParen) {
766 elements.push(None);
767 } else {
768 elements.push(Some(self.parse_expr()?));
769 }
770 } else {
771 elements.push(Some(self.parse_expr()?));
773 if !self.eat(&TokenKind::Comma) {
774 self.expect(&TokenKind::RParen)?;
775 break;
776 }
777 if self.check(&TokenKind::Comma) || self.check(&TokenKind::RParen) {
779 elements.push(None);
780 }
781 }
782 }
783
784 let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
785
786 let mut params = Vec::new();
788 let mut tuple_exprs = Vec::new();
789 let mut hole_idx = 0;
790
791 for elem in elements {
792 match elem {
793 Some(expr) => tuple_exprs.push(expr),
794 None => {
795 let name = Ident::from_str(&format!("$tsec_{}", hole_idx));
796 hole_idx += 1;
797 params.push(Pat::Var(name, Span::DUMMY));
798 tuple_exprs.push(Expr::Var(name, Span::DUMMY));
799 }
800 }
801 }
802
803 let tuple = Expr::Tuple(tuple_exprs, span);
804
805 if params.is_empty() {
806 Ok(tuple)
808 } else {
809 Ok(Expr::Lam(params, Box::new(tuple), span))
810 }
811 }
812
813 fn parse_list_expr(&mut self) -> ParseResult<Expr> {
815 let start = self.current_span();
816 self.expect(&TokenKind::LBracket)?;
817
818 if self.eat(&TokenKind::RBracket) {
819 let span = start.to(self.tokens[self.pos - 1].span);
821 return Ok(Expr::List(vec![], span));
822 }
823
824 let first = self.parse_expr()?;
825
826 if self.eat(&TokenKind::Pipe) {
828 let stmts = self.parse_list_comp_stmts()?;
829 let end = self.expect(&TokenKind::RBracket)?;
830 let span = start.to(end.span);
831 return Ok(Expr::ListComp(Box::new(first), stmts, span));
832 }
833
834 if self.eat(&TokenKind::DotDot) {
836 if self.eat(&TokenKind::RBracket) {
837 let span = start.to(self.tokens[self.pos - 1].span);
839 return Ok(Expr::ArithSeq(ArithSeq::From(Box::new(first)), span));
840 }
841 let to = self.parse_expr()?;
842 let end = self.expect(&TokenKind::RBracket)?;
843 let span = start.to(end.span);
844 return Ok(Expr::ArithSeq(
845 ArithSeq::FromTo(Box::new(first), Box::new(to)),
846 span,
847 ));
848 }
849
850 if self.eat(&TokenKind::Comma) {
851 let second = self.parse_expr()?;
853
854 if self.eat(&TokenKind::DotDot) {
855 if self.eat(&TokenKind::RBracket) {
856 let span = start.to(self.tokens[self.pos - 1].span);
858 return Ok(Expr::ArithSeq(
859 ArithSeq::FromThen(Box::new(first), Box::new(second)),
860 span,
861 ));
862 }
863 let to = self.parse_expr()?;
864 let end = self.expect(&TokenKind::RBracket)?;
865 let span = start.to(end.span);
866 return Ok(Expr::ArithSeq(
867 ArithSeq::FromThenTo(Box::new(first), Box::new(second), Box::new(to)),
868 span,
869 ));
870 }
871
872 let mut exprs = vec![first, second];
874 while self.eat(&TokenKind::Comma) {
875 exprs.push(self.parse_expr()?);
876 }
877 let end = self.expect(&TokenKind::RBracket)?;
878 let span = start.to(end.span);
879 return Ok(Expr::List(exprs, span));
880 }
881
882 let end = self.expect(&TokenKind::RBracket)?;
884 let span = start.to(end.span);
885 Ok(Expr::List(vec![first], span))
886 }
887
888 fn parse_list_comp_stmts(&mut self) -> ParseResult<Vec<Stmt>> {
890 let mut stmts = vec![self.parse_stmt()?];
891 while self.eat(&TokenKind::Comma) {
892 stmts.push(self.parse_stmt()?);
893 }
894 Ok(stmts)
895 }
896
897 fn parse_stmt(&mut self) -> ParseResult<Stmt> {
899 let start = self.current_span();
900
901 if self.check(&TokenKind::Let) {
905 self.advance();
906 let decls = self.parse_local_decls()?;
907 let span = start.to(self.tokens[self.pos - 1].span);
908 return Ok(Stmt::LetStmt(decls, span));
909 }
910
911 let saved_pos = self.pos;
915
916 if self.is_pattern_start() {
918 if let Ok(pat) = self.parse_pattern() {
919 if self.eat(&TokenKind::LeftArrow) {
920 let expr = self.parse_expr()?;
921 let span = start.to(expr.span());
922 return Ok(Stmt::Generator(pat, expr, span));
923 }
924 }
925 self.pos = saved_pos;
927 }
928
929 let expr = self.parse_expr()?;
931 let span = expr.span();
932 Ok(Stmt::Qualifier(expr, span))
933 }
934
935 #[allow(dead_code)]
937 fn expr_to_pat(&self, expr: Expr) -> ParseResult<Pat> {
938 match expr {
939 Expr::Var(id, span) => Ok(Pat::Var(id, span)),
940 Expr::Con(id, span) => Ok(Pat::Con(id, vec![], span)),
941 Expr::Lit(lit, span) => Ok(Pat::Lit(lit, span)),
942 Expr::Tuple(exprs, span) => {
943 let pats: ParseResult<Vec<_>> =
944 exprs.into_iter().map(|e| self.expr_to_pat(e)).collect();
945 Ok(Pat::Tuple(pats?, span))
946 }
947 Expr::List(exprs, span) => {
948 let pats: ParseResult<Vec<_>> =
949 exprs.into_iter().map(|e| self.expr_to_pat(e)).collect();
950 Ok(Pat::List(pats?, span))
951 }
952 Expr::Paren(e, span) => {
953 let p = self.expr_to_pat(*e)?;
954 Ok(Pat::Paren(Box::new(p), span))
955 }
956 Expr::QualCon(module, id, span) => {
957 let qual_name = format!(
959 "{}.{}",
960 module
961 .parts
962 .iter()
963 .map(|s| s.as_str())
964 .collect::<Vec<_>>()
965 .join("."),
966 id.as_str()
967 );
968 Ok(Pat::Con(Ident::from_str(&qual_name), vec![], span))
969 }
970 Expr::App(f, x, span) => {
971 let mut args = vec![*x];
974 let mut cur = *f;
975 while let Expr::App(inner_f, inner_x, _) = cur {
976 args.push(*inner_x);
977 cur = *inner_f;
978 }
979 args.reverse();
980
981 let con_id = match cur {
982 Expr::Con(id, _) => id,
983 Expr::QualCon(module, id, _) => {
984 let qual_name = format!(
985 "{}.{}",
986 module
987 .parts
988 .iter()
989 .map(|s| s.as_str())
990 .collect::<Vec<_>>()
991 .join("."),
992 id.as_str()
993 );
994 Ident::from_str(&qual_name)
995 }
996 _ => {
997 return Err(ParseError::Unexpected {
998 found: "expression".to_string(),
999 expected: "pattern".to_string(),
1000 span,
1001 });
1002 }
1003 };
1004
1005 let pats: ParseResult<Vec<_>> =
1006 args.into_iter().map(|e| self.expr_to_pat(e)).collect();
1007 Ok(Pat::Con(con_id, pats?, span))
1008 }
1009 Expr::Wildcard(span) => Ok(Pat::Wildcard(span)),
1010 Expr::RecordCon(con, field_binds, has_wildcard, span) => {
1011 use bhc_ast::FieldPat;
1013 let mut field_pats = Vec::new();
1014 for fb in field_binds {
1015 let pat = match fb.value {
1016 Some(expr) => Some(self.expr_to_pat(expr)?),
1017 None => None, };
1019 field_pats.push(FieldPat {
1020 qualifier: fb.qualifier,
1021 name: fb.name,
1022 pat,
1023 span: fb.span,
1024 });
1025 }
1026 Ok(Pat::Record(con, field_pats, has_wildcard, span))
1027 }
1028 Expr::QualRecordCon(module_name, con, field_binds, has_wildcard, span) => {
1029 use bhc_ast::FieldPat;
1031 let mut field_pats = Vec::new();
1032 for fb in field_binds {
1033 let pat = match fb.value {
1034 Some(expr) => Some(self.expr_to_pat(expr)?),
1035 None => None,
1036 };
1037 field_pats.push(FieldPat {
1038 qualifier: fb.qualifier,
1039 name: fb.name,
1040 pat,
1041 span: fb.span,
1042 });
1043 }
1044 Ok(Pat::QualRecord(
1045 module_name,
1046 con,
1047 field_pats,
1048 has_wildcard,
1049 span,
1050 ))
1051 }
1052 _ => Err(ParseError::Unexpected {
1053 found: "expression".to_string(),
1054 expected: "pattern".to_string(),
1055 span: expr.span(),
1056 }),
1057 }
1058 }
1059
1060 fn parse_lambda(&mut self) -> ParseResult<Expr> {
1062 let start = self.current_span();
1063 self.expect(&TokenKind::Backslash)?;
1064
1065 if self.eat(&TokenKind::Case) {
1067 let alts = self.parse_case_alts()?;
1068 let span = start.to(alts.last().map(|a| a.span).unwrap_or(start));
1069
1070 let x = Ident::from_str("$lambdacase_arg");
1072 let x_pat = Pat::Var(x, Span::DUMMY);
1073 let x_expr = Expr::Var(x, Span::DUMMY);
1074 let case_expr = Expr::Case(Box::new(x_expr), alts, span);
1075 return Ok(Expr::Lam(vec![x_pat], Box::new(case_expr), span));
1076 }
1077
1078 let mut pats = vec![self.parse_pattern()?];
1079 while !self.check(&TokenKind::Arrow) && !self.at_eof() {
1080 if self.is_pattern_start() {
1081 pats.push(self.parse_pattern()?);
1082 } else {
1083 break;
1084 }
1085 }
1086
1087 self.expect(&TokenKind::Arrow)?;
1088 let body = self.parse_expr()?;
1089 let span = start.to(body.span());
1090
1091 Ok(Expr::Lam(pats, Box::new(body), span))
1092 }
1093
1094 fn parse_let_expr(&mut self) -> ParseResult<Expr> {
1096 let start = self.current_span();
1097 self.expect(&TokenKind::Let)?;
1098
1099 let decls = self.parse_local_decls()?;
1100
1101 self.expect(&TokenKind::In)?;
1102
1103 while self.check(&TokenKind::VirtualRBrace) {
1110 self.advance();
1111 }
1112
1113 let body = self.parse_expr()?;
1114 let span = start.to(body.span());
1115
1116 Ok(Expr::Let(decls, Box::new(body), span))
1117 }
1118
1119 fn parse_if_expr(&mut self) -> ParseResult<Expr> {
1121 let start = self.current_span();
1122 self.expect(&TokenKind::If)?;
1123
1124 if self.check(&TokenKind::Pipe) {
1126 return self.parse_multi_way_if(start);
1127 }
1128
1129 let cond = self.parse_expr()?;
1130 self.expect(&TokenKind::Then)?;
1131 let then_branch = self.parse_expr()?;
1132 self.expect(&TokenKind::Else)?;
1133 let else_branch = self.parse_expr()?;
1134
1135 let span = start.to(else_branch.span());
1136 Ok(Expr::If(
1137 Box::new(cond),
1138 Box::new(then_branch),
1139 Box::new(else_branch),
1140 span,
1141 ))
1142 }
1143
1144 fn parse_multi_way_if(&mut self, start: Span) -> ParseResult<Expr> {
1149 let guarded_rhss = self.parse_guarded_rhss()?;
1150
1151 if guarded_rhss.is_empty() {
1152 return Err(ParseError::Unexpected {
1153 found: "end of multi-way if".to_string(),
1154 expected: "guarded alternative".to_string(),
1155 span: start,
1156 });
1157 }
1158
1159 let mut result = Expr::App(
1162 Box::new(Expr::Var(Ident::from_str("error"), start)),
1163 Box::new(Expr::Lit(
1164 Lit::String("Non-exhaustive guards in multi-way if".to_string()),
1165 start,
1166 )),
1167 start,
1168 );
1169
1170 for grhs in guarded_rhss.into_iter().rev() {
1171 let cond = match grhs.guards.into_iter().next() {
1174 Some(Guard::Expr(cond_expr, _)) => cond_expr,
1175 Some(Guard::Pattern(_, expr, _)) => expr,
1176 None => continue,
1177 };
1178 let span = start.to(grhs.body.span());
1179 result = Expr::If(Box::new(cond), Box::new(grhs.body), Box::new(result), span);
1180 }
1181
1182 Ok(result)
1183 }
1184
1185 fn parse_case_expr(&mut self) -> ParseResult<Expr> {
1187 let start = self.current_span();
1188 self.expect(&TokenKind::Case)?;
1189
1190 let scrutinee = self.parse_expr()?;
1191 self.expect(&TokenKind::Of)?;
1192
1193 let alts = self.parse_case_alts()?;
1194 let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1195
1196 Ok(Expr::Case(Box::new(scrutinee), alts, span))
1197 }
1198
1199 fn parse_case_alts(&mut self) -> ParseResult<Vec<Alt>> {
1201 let mut alts = Vec::new();
1202
1203 let explicit_braces = self.eat(&TokenKind::LBrace);
1205 let virtual_braces = !explicit_braces && self.eat(&TokenKind::VirtualLBrace);
1206 let has_braces = explicit_braces || virtual_braces;
1207
1208 if has_braces {
1209 let rbrace = if explicit_braces {
1211 TokenKind::RBrace
1212 } else {
1213 TokenKind::VirtualRBrace
1214 };
1215
1216 let is_terminated = |s: &Self| {
1219 s.check(&rbrace)
1220 || s.check(&TokenKind::VirtualRBrace)
1221 || (!explicit_braces && s.check(&TokenKind::In))
1222 };
1223
1224 if !is_terminated(self) {
1225 alts.push(self.parse_alt()?);
1226 while self.eat(&TokenKind::Semi) || self.eat(&TokenKind::VirtualSemi) {
1228 if is_terminated(self) {
1229 break;
1230 }
1231 while self.eat(&TokenKind::Semi) || self.eat(&TokenKind::VirtualSemi) {}
1233 if is_terminated(self) {
1234 break;
1235 }
1236 alts.push(self.parse_alt()?);
1237 }
1238 }
1239
1240 if explicit_braces {
1241 self.expect(&TokenKind::RBrace)?;
1242 } else {
1243 self.eat(&TokenKind::VirtualRBrace);
1246 }
1247 } else {
1248 alts.push(self.parse_alt()?);
1250 }
1251
1252 Ok(alts)
1253 }
1254
1255 fn parse_alt(&mut self) -> ParseResult<Alt> {
1257 let start = self.current_span();
1258 let pat = self.parse_pattern()?;
1259
1260 let rhs = if self.check(&TokenKind::Pipe) {
1262 let guards = self.parse_guarded_rhss()?;
1263 let end_span = guards.last().map(|g| g.span).unwrap_or(start);
1264 Rhs::Guarded(guards, start.to(end_span))
1265 } else {
1266 self.expect(&TokenKind::Arrow)?;
1267 let expr = self.parse_expr()?;
1268 let span = start.to(expr.span());
1269 Rhs::Simple(expr, span)
1270 };
1271
1272 let wheres = if self.eat(&TokenKind::Where) {
1274 self.parse_local_decls()?
1275 } else {
1276 vec![]
1277 };
1278
1279 let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1280 Ok(Alt {
1281 pat,
1282 rhs,
1283 wheres,
1284 span,
1285 })
1286 }
1287
1288 fn parse_guarded_rhss(&mut self) -> ParseResult<Vec<GuardedRhs>> {
1290 let mut guarded_rhss = Vec::new();
1291 while self.eat(&TokenKind::Pipe) {
1292 let start = self.current_span();
1293
1294 let mut guards = Vec::new();
1299 loop {
1300 let guard = self.parse_guard_item()?;
1301 guards.push(guard);
1302
1303 if !self.eat(&TokenKind::Comma) {
1305 break;
1306 }
1307 }
1308
1309 self.expect(&TokenKind::Arrow)?;
1310 let body = self.parse_expr()?;
1311 let span = start.to(body.span());
1312 guarded_rhss.push(GuardedRhs { guards, body, span });
1313 }
1314 Ok(guarded_rhss)
1315 }
1316
1317 fn parse_guard_item(&mut self) -> ParseResult<Guard> {
1319 let start = self.current_span();
1320
1321 let saved_pos = self.pos;
1323
1324 if let Ok(pat) = self.parse_pattern() {
1326 if self.eat(&TokenKind::LeftArrow) {
1327 let expr = self.parse_expr()?;
1329 let span = start.to(expr.span());
1330 return Ok(Guard::Pattern(pat, expr, span));
1331 }
1332 self.pos = saved_pos;
1334 } else {
1335 self.pos = saved_pos;
1337 }
1338
1339 let expr = self.parse_expr()?;
1341 let span = start.to(expr.span());
1342 Ok(Guard::Expr(expr, span))
1343 }
1344
1345 fn parse_do_expr(&mut self) -> ParseResult<Expr> {
1347 let start = self.current_span();
1348 self.expect(&TokenKind::Do)?;
1349
1350 let stmts = self.parse_do_stmts()?;
1351 let span = start.to(self.tokens[self.pos.saturating_sub(1)].span);
1352
1353 Ok(Expr::Do(stmts, span))
1354 }
1355
1356 fn parse_do_stmts(&mut self) -> ParseResult<Vec<Stmt>> {
1358 let mut stmts = Vec::new();
1359
1360 let explicit_braces = self.eat(&TokenKind::LBrace);
1362 let virtual_braces = !explicit_braces && self.eat(&TokenKind::VirtualLBrace);
1363 let has_braces = explicit_braces || virtual_braces;
1364
1365 if has_braces {
1366 let rbrace = if explicit_braces {
1368 TokenKind::RBrace
1369 } else {
1370 TokenKind::VirtualRBrace
1371 };
1372
1373 if !self.check(&rbrace) {
1374 stmts.push(self.parse_stmt()?);
1375 while self.eat(&TokenKind::Semi) || self.eat(&TokenKind::VirtualSemi) {
1377 if self.check(&rbrace) || self.check(&TokenKind::VirtualRBrace) {
1378 break;
1379 }
1380 if self.check(&TokenKind::Where) {
1382 break;
1383 }
1384 while self.eat(&TokenKind::Semi) || self.eat(&TokenKind::VirtualSemi) {}
1386 if self.check(&rbrace) || self.check(&TokenKind::VirtualRBrace) {
1387 break;
1388 }
1389 if self.check(&TokenKind::Where) {
1391 break;
1392 }
1393 stmts.push(self.parse_stmt()?);
1394 }
1395 }
1396
1397 if explicit_braces {
1398 self.expect(&TokenKind::RBrace)?;
1399 } else {
1400 self.eat(&TokenKind::VirtualRBrace);
1402 }
1403 } else {
1404 stmts.push(self.parse_stmt()?);
1406 }
1407
1408 Ok(stmts)
1409 }
1410
1411 fn parse_lazy_expr(&mut self) -> ParseResult<Expr> {
1413 let start = self.current_span();
1414 self.expect_ident_str("lazy")?;
1415 self.expect(&TokenKind::LBrace)?;
1416 let expr = self.parse_expr()?;
1417 let end = self.expect(&TokenKind::RBrace)?;
1418 let span = start.to(end.span);
1419
1420 Ok(Expr::Lazy(Box::new(expr), span))
1421 }
1422
1423 fn parse_record_con(&mut self, con: Ident, start: Span) -> ParseResult<Expr> {
1425 self.expect(&TokenKind::LBrace)?;
1426
1427 let mut fields = Vec::new();
1428 let mut has_wildcard = false;
1429 if !self.check(&TokenKind::RBrace) {
1430 if self.eat(&TokenKind::DotDot) {
1432 has_wildcard = true;
1433 } else {
1434 fields.push(self.parse_field_bind()?);
1435 while self.eat(&TokenKind::Comma) {
1436 if self.check(&TokenKind::RBrace) {
1437 break;
1438 }
1439 if self.eat(&TokenKind::DotDot) {
1441 has_wildcard = true;
1442 break;
1443 }
1444 fields.push(self.parse_field_bind()?);
1445 }
1446 }
1447 }
1448
1449 let end = self.expect(&TokenKind::RBrace)?;
1450 let span = start.to(end.span);
1451 Ok(Expr::RecordCon(con, fields, has_wildcard, span))
1452 }
1453
1454 fn parse_qual_record_con(
1456 &mut self,
1457 module_name: ModuleName,
1458 con: Ident,
1459 start: Span,
1460 ) -> ParseResult<Expr> {
1461 self.expect(&TokenKind::LBrace)?;
1462
1463 let mut fields = Vec::new();
1464 let mut has_wildcard = false;
1465 if !self.check(&TokenKind::RBrace) {
1466 if self.eat(&TokenKind::DotDot) {
1467 has_wildcard = true;
1468 } else {
1469 fields.push(self.parse_field_bind()?);
1470 while self.eat(&TokenKind::Comma) {
1471 if self.check(&TokenKind::RBrace) {
1472 break;
1473 }
1474 if self.eat(&TokenKind::DotDot) {
1475 has_wildcard = true;
1476 break;
1477 }
1478 fields.push(self.parse_field_bind()?);
1479 }
1480 }
1481 }
1482
1483 let end = self.expect(&TokenKind::RBrace)?;
1484 let span = start.to(end.span);
1485 Ok(Expr::QualRecordCon(
1486 module_name,
1487 con,
1488 fields,
1489 has_wildcard,
1490 span,
1491 ))
1492 }
1493
1494 fn parse_record_update(&mut self, expr: Expr, start: Span) -> ParseResult<Expr> {
1496 self.expect(&TokenKind::LBrace)?;
1497
1498 let mut fields = Vec::new();
1499 if !self.check(&TokenKind::RBrace) {
1500 fields.push(self.parse_field_bind()?);
1501 while self.eat(&TokenKind::Comma) {
1502 if self.check(&TokenKind::RBrace) {
1503 break;
1504 }
1505 fields.push(self.parse_field_bind()?);
1506 }
1507 }
1508
1509 let end = self.expect(&TokenKind::RBrace)?;
1510 let span = start.to(end.span);
1511 Ok(Expr::RecordUpd(Box::new(expr), fields, span))
1512 }
1513
1514 fn parse_field_bind(&mut self) -> ParseResult<FieldBind> {
1516 let tok = self.current().ok_or(ParseError::UnexpectedEof {
1517 expected: "field name".to_string(),
1518 })?;
1519
1520 let (qualifier, name, span) = match &tok.node.kind {
1521 TokenKind::Ident(sym) => (None, Ident::new(*sym), tok.span),
1522 TokenKind::QualIdent(qual, sym) => {
1523 let module_name = ModuleName {
1524 parts: vec![*qual],
1525 span: tok.span,
1526 };
1527 (Some(module_name), Ident::new(*sym), tok.span)
1528 }
1529 _ => {
1530 return Err(ParseError::Unexpected {
1531 found: tok.node.kind.description().to_string(),
1532 expected: "field name".to_string(),
1533 span: tok.span,
1534 });
1535 }
1536 };
1537 self.advance();
1538
1539 let value = if self.eat(&TokenKind::Eq) {
1540 Some(self.parse_expr()?)
1541 } else {
1542 None };
1544
1545 let end_span = value.as_ref().map(|e| e.span()).unwrap_or(span);
1546 let full_span = span.to(end_span);
1547 Ok(FieldBind {
1548 qualifier,
1549 name,
1550 value,
1551 span: full_span,
1552 })
1553 }
1554
1555 fn parse_operator_section(&mut self, start: Span) -> ParseResult<Expr> {
1557 let tok = self.current().ok_or(ParseError::UnexpectedEof {
1559 expected: "operator".to_string(),
1560 })?;
1561
1562 let op = match &tok.node.kind {
1563 TokenKind::Operator(sym) => Ident::new(*sym),
1564 TokenKind::Star => Ident::from_str("*"),
1565 TokenKind::Minus => Ident::from_str("-"),
1566 TokenKind::Percent => Ident::from_str("%"),
1567 TokenKind::Dot => Ident::from_str("."),
1568 TokenKind::ConOperator(sym) => Ident::new(*sym),
1569 TokenKind::QualOperator(qual, sym) => {
1570 let full_name = format!("{}.{}", qual.as_str(), sym.as_str());
1571 Ident::from_str(&full_name)
1572 }
1573 TokenKind::QualConOperator(qual, sym) => {
1574 let full_name = format!("{}.{}", qual.as_str(), sym.as_str());
1575 Ident::from_str(&full_name)
1576 }
1577 _ => {
1578 return Err(ParseError::Unexpected {
1579 found: tok.node.kind.description().to_string(),
1580 expected: "operator".to_string(),
1581 span: tok.span,
1582 });
1583 }
1584 };
1585 self.advance();
1586
1587 if self.eat(&TokenKind::RParen) {
1588 let span = start.to(self.tokens[self.pos - 1].span);
1590 return Ok(Expr::Var(op, span));
1591 }
1592
1593 let arg = self.parse_expr()?;
1595 let end = self.expect(&TokenKind::RParen)?;
1596 let span = start.to(end.span);
1597
1598 let y = Ident::from_str("$section_arg");
1600 let y_pat = Pat::Var(y, Span::DUMMY);
1601 let y_expr = Expr::Var(y, Span::DUMMY);
1602 let body = Expr::Infix(Box::new(y_expr), op, Box::new(arg), span);
1603 Ok(Expr::Lam(vec![y_pat], Box::new(body), span))
1604 }
1605
1606 fn parse_type_annotation(&mut self, expr: Expr) -> ParseResult<Expr> {
1608 let start = expr.span();
1609 self.expect(&TokenKind::DoubleColon)?;
1610 let ty = self.parse_type()?;
1611 let span = start.to(ty.span());
1612 Ok(Expr::Ann(Box::new(expr), ty, span))
1613 }
1614}
1615
1616#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1618enum Assoc {
1619 Left,
1620 Right,
1621 None,
1622}