diff options
author | Griffin Smith <grfn@gws.fyi> | 2021-03-28T17·28-0400 |
---|---|---|
committer | glittershark <grfn@gws.fyi> | 2021-03-28T17·33+0000 |
commit | 8e13b1303a0d152c2f3b68f2421163e94fdf226c (patch) | |
tree | 0cac0fee2cd52f912bb118cff78fdca9d28ac895 /users/glittershark/achilles/src/passes/hir/mod.rs | |
parent | db62866d820cf524b67cebe34033d3928804cf3c (diff) |
feat(achilles): Implement a Unit type r/2356
Add support for a zero-sized Unit type. This requires some special at the codegen level because LLVM (unsurprisingly) only allows Void types in function return position - to make that a little easier to handle there's a new pass that strips any unit-only expressions and pulls unit-only function arguments up to new `let` bindings, so we never have to actually pass around unit values. Change-Id: I0fc18a516821f2d69172c42a6a5d246b23471e38 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2695 Reviewed-by: glittershark <grfn@gws.fyi> Tested-by: BuildkiteCI
Diffstat (limited to 'users/glittershark/achilles/src/passes/hir/mod.rs')
-rw-r--r-- | users/glittershark/achilles/src/passes/hir/mod.rs | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/users/glittershark/achilles/src/passes/hir/mod.rs b/users/glittershark/achilles/src/passes/hir/mod.rs index fb2f64e08591..845bfcb7ab6a 100644 --- a/users/glittershark/achilles/src/passes/hir/mod.rs +++ b/users/glittershark/achilles/src/passes/hir/mod.rs @@ -4,6 +4,7 @@ use crate::ast::hir::{Binding, Decl, Expr}; use crate::ast::{BinaryOperator, Ident, Literal, UnaryOperator}; pub(crate) mod monomorphize; +pub(crate) mod strip_positive_units; pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a { type Error; @@ -53,7 +54,12 @@ pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a { Ok(()) } + fn pre_visit_expr(&mut self, _expr: &mut Expr<'ast, T>) -> Result<(), Self::Error> { + Ok(()) + } + fn visit_expr(&mut self, expr: &mut Expr<'ast, T>) -> Result<(), Self::Error> { + self.pre_visit_expr(expr)?; match expr { Expr::Ident(id, t) => { self.visit_ident(id)?; @@ -140,6 +146,17 @@ pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a { Ok(()) } + fn post_visit_fun_decl( + &mut self, + _name: &mut Ident<'ast>, + _type_args: &mut Vec<Ident>, + _args: &mut Vec<(Ident, T)>, + _body: &mut Box<Expr<T>>, + _type_: &mut T, + ) -> Result<(), Self::Error> { + Ok(()) + } + fn visit_decl(&mut self, decl: &'a mut Decl<'ast, T>) -> Result<(), Self::Error> { match decl { Decl::Fun { @@ -150,15 +167,16 @@ pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a { type_, } => { self.visit_ident(name)?; - for type_arg in type_args { + for type_arg in type_args.iter_mut() { self.visit_ident(type_arg)?; } - for (arg, t) in args { + for (arg, t) in args.iter_mut() { self.visit_ident(arg)?; self.visit_type(t)?; } self.visit_expr(body)?; self.visit_type(type_)?; + self.post_visit_fun_decl(name, type_args, args, body, type_)?; } Decl::Extern { name, |