]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/body/lower.rs
Merge #11287
[rust.git] / crates / hir_def / src / body / lower.rs
index 75dc19c117aed9bfef72dc260ba8737416ebe899..7cbeef1488a05cb802a43bcbdf55f8f510e912f1 100644 (file)
@@ -8,13 +8,13 @@
     ast_id_map::{AstIdMap, FileAstId},
     hygiene::Hygiene,
     name::{name, AsName, Name},
-    ExpandError, HirFileId,
+    ExpandError, HirFileId, InFile,
 };
 use la_arena::Arena;
 use profile::Count;
 use syntax::{
     ast::{
-        self, ArgListOwner, ArrayExprKind, AstChildren, LiteralKind, LoopBodyOwner, NameOwner,
+        self, ArrayExprKind, AstChildren, HasArgList, HasLoopBody, HasName, LiteralKind,
         SlicePatComponents,
     },
     AstNode, AstPtr, SyntaxNodePtr,
 use crate::{
     adt::StructKind,
     body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
+    body::{BodyDiagnostic, ExprSource, PatSource},
     builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
     db::DefDatabase,
-    diagnostics::{InactiveCode, MacroError, UnresolvedMacroCall, UnresolvedProcMacro},
     expr::{
-        dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Label,
-        LabelId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField,
-        Statement,
+        dummy_expr_id, Array, BindingAnnotation, Expr, ExprId, Label, LabelId, Literal, MatchArm,
+        MatchGuard, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
     },
     intern::Interned,
     item_scope::BuiltinShadowMode,
@@ -38,8 +37,6 @@
     AdtId, BlockLoc, ModuleDefId, UnresolvedMacro,
 };
 
-use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource};
-
 pub struct LowerCtx<'a> {
     pub db: &'a dyn DefDatabase,
     hygiene: Hygiene,
@@ -133,11 +130,7 @@ fn collect(
                 self.body.params.push(param_pat);
             }
 
-            for param in param_list.params() {
-                let pat = match param.pat() {
-                    None => continue,
-                    Some(pat) => pat,
-                };
+            for pat in param_list.params().filter_map(|param| param.pat()) {
                 let param_pat = self.collect_pat(pat);
                 self.body.params.push(param_pat);
             }
@@ -163,7 +156,7 @@ fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
         self.make_expr(expr, Err(SyntheticSyntax))
     }
     fn unit(&mut self) -> ExprId {
-        self.alloc_expr_desugared(Expr::Tuple { exprs: Vec::new() })
+        self.alloc_expr_desugared(Expr::Tuple { exprs: Box::default() })
     }
     fn missing_expr(&mut self) -> ExprId {
         self.alloc_expr_desugared(Expr::Missing)
@@ -205,7 +198,7 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
         self.maybe_collect_expr(expr).unwrap_or_else(|| self.missing_expr())
     }
 
-    /// Returns `None` if the expression is `#[cfg]`d out.
+    /// Returns `None` if and only if the expression is `#[cfg]`d out.
     fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
         let syntax_ptr = AstPtr::new(&expr);
         self.check_cfg(&expr)?;
@@ -238,7 +231,8 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                                     expr: else_branch.unwrap_or_else(|| self.unit()),
                                     guard: None,
                                 },
-                            ];
+                            ]
+                            .into();
                             return Some(
                                 self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr),
                             );
@@ -248,43 +242,37 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
 
                 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
             }
-            ast::Expr::EffectExpr(e) => match e.effect() {
-                ast::Effect::Try(_) => {
-                    let body = self.collect_block_opt(e.block_expr());
+            ast::Expr::BlockExpr(e) => match e.modifier() {
+                Some(ast::BlockModifier::Try(_)) => {
+                    let body = self.collect_block(e);
                     self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
                 }
-                ast::Effect::Unsafe(_) => {
-                    let body = self.collect_block_opt(e.block_expr());
+                Some(ast::BlockModifier::Unsafe(_)) => {
+                    let body = self.collect_block(e);
                     self.alloc_expr(Expr::Unsafe { body }, syntax_ptr)
                 }
                 // FIXME: we need to record these effects somewhere...
-                ast::Effect::Label(label) => {
+                Some(ast::BlockModifier::Label(label)) => {
                     let label = self.collect_label(label);
-                    match e.block_expr() {
-                        Some(block) => {
-                            let res = self.collect_block(block);
-                            match &mut self.body.exprs[res] {
-                                Expr::Block { label: block_label, .. } => {
-                                    *block_label = Some(label);
-                                }
-                                _ => unreachable!(),
-                            }
-                            res
+                    let res = self.collect_block(e);
+                    match &mut self.body.exprs[res] {
+                        Expr::Block { label: block_label, .. } => {
+                            *block_label = Some(label);
                         }
-                        None => self.missing_expr(),
+                        _ => unreachable!(),
                     }
+                    res
                 }
-                // FIXME: we need to record these effects somewhere...
-                ast::Effect::Async(_) => {
-                    let body = self.collect_block_opt(e.block_expr());
+                Some(ast::BlockModifier::Async(_)) => {
+                    let body = self.collect_block(e);
                     self.alloc_expr(Expr::Async { body }, syntax_ptr)
                 }
-                ast::Effect::Const(_) => {
-                    let body = self.collect_block_opt(e.block_expr());
+                Some(ast::BlockModifier::Const(_)) => {
+                    let body = self.collect_block(e);
                     self.alloc_expr(Expr::Const { body }, syntax_ptr)
                 }
+                None => self.collect_block(e),
             },
-            ast::Expr::BlockExpr(e) => self.collect_block(e),
             ast::Expr::LoopExpr(e) => {
                 let label = e.label().map(|label| self.collect_label(label));
                 let body = self.collect_block_opt(e.loop_body());
@@ -309,7 +297,8 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                             let arms = vec![
                                 MatchArm { pat, expr: body, guard: None },
                                 MatchArm { pat: placeholder_pat, expr: break_, guard: None },
-                            ];
+                            ]
+                            .into();
                             let match_expr =
                                 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms });
                             return Some(
@@ -333,7 +322,7 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                 let args = if let Some(arg_list) = e.arg_list() {
                     arg_list.args().filter_map(|e| self.maybe_collect_expr(e)).collect()
                 } else {
-                    Vec::new()
+                    Box::default()
                 };
                 self.alloc_expr(Expr::Call { callee, args }, syntax_ptr)
             }
@@ -342,7 +331,7 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                 let args = if let Some(arg_list) = e.arg_list() {
                     arg_list.args().filter_map(|e| self.maybe_collect_expr(e)).collect()
                 } else {
-                    Vec::new()
+                    Box::default()
                 };
                 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
                 let generic_args = e
@@ -363,15 +352,20 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                             self.check_cfg(&arm).map(|()| MatchArm {
                                 pat: self.collect_pat_opt(arm.pat()),
                                 expr: self.collect_expr_opt(arm.expr()),
-                                guard: arm
-                                    .guard()
-                                    .and_then(|guard| guard.expr())
-                                    .map(|e| self.collect_expr(e)),
+                                guard: arm.guard().map(|guard| match guard.pat() {
+                                    Some(pat) => MatchGuard::IfLet {
+                                        pat: self.collect_pat(pat),
+                                        expr: self.collect_expr_opt(guard.expr()),
+                                    },
+                                    None => {
+                                        MatchGuard::If { expr: self.collect_expr_opt(guard.expr()) }
+                                    }
+                                }),
                             })
                         })
                         .collect()
                 } else {
-                    Vec::new()
+                    Box::default()
                 };
                 self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr)
             }
@@ -433,7 +427,7 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                     let spread = nfl.spread().map(|s| self.collect_expr(s));
                     Expr::RecordLit { path, fields, spread }
                 } else {
-                    Expr::RecordLit { path, fields: Vec::new(), spread: None }
+                    Expr::RecordLit { path, fields: Box::default(), spread: None }
                 };
 
                 self.alloc_expr(record_lit, syntax_ptr)
@@ -478,10 +472,9 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
             }
             ast::Expr::PrefixExpr(e) => {
                 let expr = self.collect_expr_opt(e.expr());
-                if let Some(op) = e.op_kind() {
-                    self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
-                } else {
-                    self.alloc_expr(Expr::Missing, syntax_ptr)
+                match e.op_kind() {
+                    Some(op) => self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr),
+                    None => self.alloc_expr(Expr::Missing, syntax_ptr),
                 }
             }
             ast::Expr::ClosureExpr(e) => {
@@ -501,12 +494,15 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                     .and_then(|r| r.ty())
                     .map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
                 let body = self.collect_expr_opt(e.body());
-                self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
+                self.alloc_expr(
+                    Expr::Lambda { args: args.into(), arg_types: arg_types.into(), ret_type, body },
+                    syntax_ptr,
+                )
             }
             ast::Expr::BinExpr(e) => {
                 let lhs = self.collect_expr_opt(e.lhs());
                 let rhs = self.collect_expr_opt(e.rhs());
-                let op = e.op_kind().map(BinaryOp::from);
+                let op = e.op_kind();
                 self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
             }
             ast::Expr::TupleExpr(e) => {
@@ -580,7 +576,7 @@ fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>(
         &mut self,
         e: ast::MacroCall,
         syntax_ptr: AstPtr<ast::MacroCall>,
-        is_error_recoverable: bool,
+        record_diagnostics: bool,
         mut collector: F,
     ) {
         // File containing the macro call. Expansion errors will be attached here.
@@ -592,63 +588,50 @@ fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>(
         let res = match res {
             Ok(res) => res,
             Err(UnresolvedMacro { path }) => {
-                self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall(
-                    UnresolvedMacroCall {
-                        file: outer_file,
-                        node: syntax_ptr.cast().unwrap(),
+                if record_diagnostics {
+                    self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall {
+                        node: InFile::new(outer_file, syntax_ptr),
                         path,
-                    },
-                ));
+                    });
+                }
                 collector(self, None);
                 return;
             }
         };
 
-        match &res.err {
-            Some(ExpandError::UnresolvedProcMacro) => {
-                self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro(
-                    UnresolvedProcMacro {
-                        file: outer_file,
-                        node: syntax_ptr.into(),
-                        precise_location: None,
-                        macro_name: None,
-                    },
-                ));
-            }
-            Some(err) => {
-                self.source_map.diagnostics.push(BodyDiagnostic::MacroError(MacroError {
-                    file: outer_file,
-                    node: syntax_ptr.into(),
-                    message: err.to_string(),
-                }));
+        if record_diagnostics {
+            match &res.err {
+                Some(ExpandError::UnresolvedProcMacro) => {
+                    self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro {
+                        node: InFile::new(outer_file, syntax_ptr),
+                    });
+                }
+                Some(err) => {
+                    self.source_map.diagnostics.push(BodyDiagnostic::MacroError {
+                        node: InFile::new(outer_file, syntax_ptr),
+                        message: err.to_string(),
+                    });
+                }
+                None => {}
             }
-            None => {}
         }
 
         match res.value {
             Some((mark, expansion)) => {
-                // FIXME: Statements are too complicated to recover from error for now.
-                // It is because we don't have any hygiene for local variable expansion right now.
-                if !is_error_recoverable && res.err.is_some() {
-                    self.expander.exit(self.db, mark);
-                    collector(self, None);
-                } else {
-                    self.source_map.expansions.insert(macro_call, self.expander.current_file_id);
+                self.source_map.expansions.insert(macro_call, self.expander.current_file_id);
 
-                    let id = collector(self, Some(expansion));
-                    self.expander.exit(self.db, mark);
-                    id
-                }
+                let id = collector(self, Some(expansion));
+                self.expander.exit(self.db, mark);
+                id
             }
             None => collector(self, None),
         }
     }
 
     fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
-        if let Some(expr) = expr {
-            self.collect_expr(expr)
-        } else {
-            self.missing_expr()
+        match expr {
+            Some(expr) => self.collect_expr(expr),
+            None => self.missing_expr(),
         }
     }
 
@@ -662,13 +645,24 @@ fn collect_stmt(&mut self, s: ast::Stmt) {
                 let type_ref =
                     stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
                 let initializer = stmt.initializer().map(|e| self.collect_expr(e));
-                self.statements_in_scope.push(Statement::Let { pat, type_ref, initializer });
+                let else_branch = stmt
+                    .let_else()
+                    .and_then(|let_else| let_else.block_expr())
+                    .map(|block| self.collect_block(block));
+                self.statements_in_scope.push(Statement::Let {
+                    pat,
+                    type_ref,
+                    initializer,
+                    else_branch,
+                });
             }
             ast::Stmt::ExprStmt(stmt) => {
-                if self.check_cfg(&stmt).is_none() {
-                    return;
+                if let Some(expr) = stmt.expr() {
+                    if self.check_cfg(&expr).is_none() {
+                        return;
+                    }
                 }
-
+                let has_semi = stmt.semicolon_token().is_some();
                 // Note that macro could be expended to multiple statements
                 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() {
                     let macro_ptr = AstPtr::new(&m);
@@ -685,25 +679,22 @@ fn collect_stmt(&mut self, s: ast::Stmt) {
                                 statements.statements().for_each(|stmt| this.collect_stmt(stmt));
                                 if let Some(expr) = statements.expr() {
                                     let expr = this.collect_expr(expr);
-                                    this.statements_in_scope.push(Statement::Expr(expr));
+                                    this.statements_in_scope
+                                        .push(Statement::Expr { expr, has_semi });
                                 }
                             }
                             None => {
                                 let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone());
-                                this.statements_in_scope.push(Statement::Expr(expr));
+                                this.statements_in_scope.push(Statement::Expr { expr, has_semi });
                             }
                         },
                     );
                 } else {
                     let expr = self.collect_expr_opt(stmt.expr());
-                    self.statements_in_scope.push(Statement::Expr(expr));
-                }
-            }
-            ast::Stmt::Item(item) => {
-                if self.check_cfg(&item).is_none() {
-                    return;
+                    self.statements_in_scope.push(Statement::Expr { expr, has_semi });
                 }
             }
+            ast::Stmt::Item(_item) => {}
         }
     }
 
@@ -725,9 +716,19 @@ fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
         let prev_statements = std::mem::take(&mut self.statements_in_scope);
 
         block.statements().for_each(|s| self.collect_stmt(s));
-
-        let tail = block.tail_expr().map(|e| self.collect_expr(e));
-        let statements = std::mem::replace(&mut self.statements_in_scope, prev_statements);
+        block.tail_expr().and_then(|e| {
+            let expr = self.maybe_collect_expr(e)?;
+            self.statements_in_scope.push(Statement::Expr { expr, has_semi: false });
+            Some(())
+        });
+
+        let mut tail = None;
+        if let Some(Statement::Expr { expr, has_semi: false }) = self.statements_in_scope.last() {
+            tail = Some(*expr);
+            self.statements_in_scope.pop();
+        }
+        let tail = tail;
+        let statements = std::mem::replace(&mut self.statements_in_scope, prev_statements).into();
         let syntax_node_ptr = AstPtr::new(&block.into());
         let expr_id = self.alloc_expr(
             Expr::Block { id: block_id, statements, tail, label: None },
@@ -740,10 +741,9 @@ fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
     }
 
     fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
-        if let Some(block) = expr {
-            self.collect_block(block)
-        } else {
-            self.missing_expr()
+        match expr {
+            Some(block) => self.collect_block(block),
+            None => self.missing_expr(),
         }
     }
 
@@ -822,7 +822,7 @@ fn collect_pat(&mut self, pat: ast::Pat) -> PatId {
             ast::Pat::RecordPat(p) => {
                 let path =
                     p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
-                let args: Vec<_> = p
+                let args = p
                     .record_pat_field_list()
                     .expect("every struct should have a field list")
                     .fields()
@@ -837,7 +837,7 @@ fn collect_pat(&mut self, pat: ast::Pat) -> PatId {
                 let ellipsis = p
                     .record_pat_field_list()
                     .expect("every struct should have a field list")
-                    .dotdot_token()
+                    .rest_pat()
                     .is_some();
 
                 Pat::Record { path, args, ellipsis }
@@ -906,14 +906,13 @@ fn collect_pat(&mut self, pat: ast::Pat) -> PatId {
     }
 
     fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId {
-        if let Some(pat) = pat {
-            self.collect_pat(pat)
-        } else {
-            self.missing_pat()
+        match pat {
+            Some(pat) => self.collect_pat(pat),
+            None => self.missing_pat(),
         }
     }
 
-    fn collect_tuple_pat(&mut self, args: AstChildren<ast::Pat>) -> (Vec<PatId>, Option<usize>) {
+    fn collect_tuple_pat(&mut self, args: AstChildren<ast::Pat>) -> (Box<[PatId]>, Option<usize>) {
         // Find the location of the `..`, if there is one. Note that we do not
         // consider the possibility of there being multiple `..` here.
         let ellipsis = args.clone().position(|p| matches!(p, ast::Pat::RestPat(_)));
@@ -928,19 +927,21 @@ fn collect_tuple_pat(&mut self, args: AstChildren<ast::Pat>) -> (Vec<PatId>, Opt
 
     /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when
     /// not.
-    fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> {
+    fn check_cfg(&mut self, owner: &dyn ast::HasAttrs) -> Option<()> {
         match self.expander.parse_attrs(self.db, owner).cfg() {
             Some(cfg) => {
                 if self.expander.cfg_options().check(&cfg) != Some(false) {
                     return Some(());
                 }
 
-                self.source_map.diagnostics.push(BodyDiagnostic::InactiveCode(InactiveCode {
-                    file: self.expander.current_file_id,
-                    node: SyntaxNodePtr::new(owner.syntax()),
+                self.source_map.diagnostics.push(BodyDiagnostic::InactiveCode {
+                    node: InFile::new(
+                        self.expander.current_file_id,
+                        SyntaxNodePtr::new(owner.syntax()),
+                    ),
                     cfg,
                     opts: self.expander.cfg_options().clone(),
-                }));
+                });
 
                 None
             }
@@ -949,70 +950,30 @@ fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> {
     }
 }
 
-impl From<ast::BinOp> for BinaryOp {
-    fn from(ast_op: ast::BinOp) -> Self {
-        match ast_op {
-            ast::BinOp::BooleanOr => BinaryOp::LogicOp(LogicOp::Or),
-            ast::BinOp::BooleanAnd => BinaryOp::LogicOp(LogicOp::And),
-            ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: false }),
-            ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: true }),
-            ast::BinOp::LesserEqualTest => {
-                BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: false })
-            }
-            ast::BinOp::GreaterEqualTest => {
-                BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: false })
-            }
-            ast::BinOp::LesserTest => {
-                BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: true })
-            }
-            ast::BinOp::GreaterTest => {
-                BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: true })
-            }
-            ast::BinOp::Addition => BinaryOp::ArithOp(ArithOp::Add),
-            ast::BinOp::Multiplication => BinaryOp::ArithOp(ArithOp::Mul),
-            ast::BinOp::Subtraction => BinaryOp::ArithOp(ArithOp::Sub),
-            ast::BinOp::Division => BinaryOp::ArithOp(ArithOp::Div),
-            ast::BinOp::Remainder => BinaryOp::ArithOp(ArithOp::Rem),
-            ast::BinOp::LeftShift => BinaryOp::ArithOp(ArithOp::Shl),
-            ast::BinOp::RightShift => BinaryOp::ArithOp(ArithOp::Shr),
-            ast::BinOp::BitwiseXor => BinaryOp::ArithOp(ArithOp::BitXor),
-            ast::BinOp::BitwiseOr => BinaryOp::ArithOp(ArithOp::BitOr),
-            ast::BinOp::BitwiseAnd => BinaryOp::ArithOp(ArithOp::BitAnd),
-            ast::BinOp::Assignment => BinaryOp::Assignment { op: None },
-            ast::BinOp::AddAssign => BinaryOp::Assignment { op: Some(ArithOp::Add) },
-            ast::BinOp::DivAssign => BinaryOp::Assignment { op: Some(ArithOp::Div) },
-            ast::BinOp::MulAssign => BinaryOp::Assignment { op: Some(ArithOp::Mul) },
-            ast::BinOp::RemAssign => BinaryOp::Assignment { op: Some(ArithOp::Rem) },
-            ast::BinOp::ShlAssign => BinaryOp::Assignment { op: Some(ArithOp::Shl) },
-            ast::BinOp::ShrAssign => BinaryOp::Assignment { op: Some(ArithOp::Shr) },
-            ast::BinOp::SubAssign => BinaryOp::Assignment { op: Some(ArithOp::Sub) },
-            ast::BinOp::BitOrAssign => BinaryOp::Assignment { op: Some(ArithOp::BitOr) },
-            ast::BinOp::BitAndAssign => BinaryOp::Assignment { op: Some(ArithOp::BitAnd) },
-            ast::BinOp::BitXorAssign => BinaryOp::Assignment { op: Some(ArithOp::BitXor) },
-        }
-    }
-}
-
 impl From<ast::LiteralKind> for Literal {
     fn from(ast_lit_kind: ast::LiteralKind) -> Self {
         match ast_lit_kind {
+            // FIXME: these should have actual values filled in, but unsure on perf impact
             LiteralKind::IntNumber(lit) => {
                 if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
-                    return Literal::Float(Default::default(), builtin);
+                    Literal::Float(Default::default(), builtin)
                 } else if let builtin @ Some(_) =
-                    lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
+                    lit.suffix().and_then(|it| BuiltinInt::from_suffix(it))
                 {
-                    Literal::Int(Default::default(), builtin)
+                    Literal::Int(lit.value().unwrap_or(0) as i128, builtin)
                 } else {
-                    let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
-                    Literal::Uint(Default::default(), builtin)
+                    let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(it));
+                    Literal::Uint(lit.value().unwrap_or(0), builtin)
                 }
             }
             LiteralKind::FloatNumber(lit) => {
-                let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it));
+                let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(it));
                 Literal::Float(Default::default(), ty)
             }
-            LiteralKind::ByteString(_) => Literal::ByteString(Default::default()),
+            LiteralKind::ByteString(bs) => {
+                let text = bs.value().map(Box::from).unwrap_or_else(Default::default);
+                Literal::ByteString(text)
+            }
             LiteralKind::String(_) => Literal::String(Default::default()),
             LiteralKind::Byte => Literal::Uint(Default::default(), Some(BuiltinUint::U8)),
             LiteralKind::Bool(val) => Literal::Bool(val),