diff --git a/check/src/rename.rs b/check/src/rename.rs index 554bf812b3..a0a91211e5 100644 --- a/check/src/rename.rs +++ b/check/src/rename.rs @@ -10,7 +10,7 @@ use crate::base::{ scoped_map::ScopedMap, source::Source, symbol::{Symbol, SymbolData, SymbolModule}, - types::Type, + types::{ArcType, Type}, }; struct Environment { @@ -35,6 +35,7 @@ pub fn rename<'s, 'ast>( scope: Vec, env: Environment, ast_arena: ast::ArenaRef<'s, 'ast, Symbol>, + hole: ArcType, } impl<'a, 'b, 's, 'ast> RenameVisitor<'a, 'b, 's, 'ast> { @@ -287,7 +288,7 @@ pub fn rename<'s, 'ast>( Span::new(expr.span.end(), expr.span.start() + ByteOffset::from(2)), Expr::Ident(TypedIdent { name: flat_map, - typ: Type::hole(), + typ: self.hole.clone(), }), ))); @@ -382,6 +383,7 @@ pub fn rename<'s, 'ast>( stack: ScopedMap::new(), }, ast_arena, + hole: Type::hole(), }; visitor.visit_expr(expr); } diff --git a/repl/src/repl.rs b/repl/src/repl.rs index c5a29296e3..6ecabaef7c 100644 --- a/repl/src/repl.rs +++ b/repl/src/repl.rs @@ -366,9 +366,7 @@ async fn eval_line_(vm: RootedThread, line: &str) -> gluon::Result<()> { }; match repl_line { None => return Ok(()), - Some(ReplLine::Expr(expr)) => { - RootExpr::new(arena.clone(), arena.alloc(expr)) - } + Some(ReplLine::Expr(expr)) => RootExpr::new(arena.clone(), arena.alloc(expr)), Some(ReplLine::Let(mut let_binding)) => { is_let_binding = true; // We can't compile function bindings by only looking at `let_binding.expr` @@ -385,7 +383,10 @@ async fn eval_line_(vm: RootedThread, line: &str) -> gluon::Result<()> { arena.alloc(let_binding.name), ), ); - TypedIdent::new(id) + TypedIdent { + name: id, + typ: let_binding.resolved_type.clone(), + } } }; let id = pos::spanned2(0.into(), 0.into(), Expr::Ident(id.clone())); diff --git a/vm/src/compiler.rs b/vm/src/compiler.rs index c3ed99333b..9a989157b5 100644 --- a/vm/src/compiler.rs +++ b/vm/src/compiler.rs @@ -453,6 +453,7 @@ pub struct Compiler<'a> { source_name: String, emit_debug_info: bool, empty_symbol: Symbol, + hole: ArcType, } impl<'a> KindEnv for Compiler<'a> { @@ -497,6 +498,7 @@ impl<'a> Compiler<'a> { source: source, source_name: source_name, emit_debug_info: emit_debug_info, + hole: Type::hole(), } } @@ -1047,7 +1049,11 @@ impl<'a> Compiler<'a> { // Add a dummy variable for the record itself so the correct number // of slots are removed when exiting - function.new_stack_var(self, self.empty_symbol.clone(), Type::hole()); + function.new_stack_var( + self, + self.empty_symbol.clone(), + self.hole.clone(), + ); let record_index = function.stack_size() - 1; for pattern_field in fields { @@ -1075,7 +1081,7 @@ impl<'a> Compiler<'a> { bind.as_ref().unwrap_or(&name.name).clone(), field.typ.clone(), ), - None => (self.empty_symbol.clone(), Type::hole()), + None => (self.empty_symbol.clone(), self.hole.clone()), }; function.push_stack_var(self, name, typ); } diff --git a/vm/src/core/mod.rs b/vm/src/core/mod.rs index 3f7ec7843f..3481917cd4 100644 --- a/vm/src/core/mod.rs +++ b/vm/src/core/mod.rs @@ -745,17 +745,29 @@ pub struct Translator<'a, 'e> { ident_replacements: RefCell>, env: &'e dyn PrimitiveEnv, dummy_symbol: TypedIdent, + error_symbol: TypedIdent, dummy_record_symbol: TypedIdent, } impl<'a, 'e> Translator<'a, 'e> { pub fn new(env: &'e dyn PrimitiveEnv) -> Translator<'a, 'e> { + let hole: ArcType = Type::hole(); Translator { allocator: Arc::new(Allocator::new()), ident_replacements: Default::default(), env, - dummy_symbol: TypedIdent::new(Symbol::from("")), - dummy_record_symbol: TypedIdent::new(Symbol::from("")), + dummy_symbol: TypedIdent { + name: Symbol::from(""), + typ: hole.clone(), + }, + error_symbol: TypedIdent { + name: Symbol::from("@error"), + typ: hole.clone(), + }, + dummy_record_symbol: TypedIdent { + name: Symbol::from(""), + typ: hole.clone(), + }, } } @@ -1005,7 +1017,13 @@ impl<'a, 'e> Translator<'a, 'e> { last_span = expr.span; self.translate(expr) } - None => Expr::Ident(TypedIdent::new(field.name.value.clone()), last_span), + None => Expr::Ident( + TypedIdent { + name: field.name.value.clone(), + typ: self.dummy_symbol.typ.clone(), + }, + last_span, + ), }; if needs_bindings { let typ = expr.env_type_of(&self.env); @@ -1379,10 +1397,7 @@ impl<'a, 'e> Translator<'a, 'e> { fn error_expr(&'a self, msg: &str) -> Expr<'a> { let arena = &self.allocator.arena; - let error = arena.alloc(Expr::Ident( - TypedIdent::new(Symbol::from("@error")), - Span::default(), - )); + let error = arena.alloc(Expr::Ident(self.error_symbol.clone(), Span::default())); let args = arena.alloc_fixed( Some(Expr::Const(Literal::String(msg.into()), Span::default())).into_iter(), ); @@ -1651,6 +1666,18 @@ impl<'a, 'e> PatternTranslator<'a, 'e> { groups.len() == iter.by_ref().count() && **iter.current_type() == Type::EmptyRow }; + let default_alt = if complete { + None + } else { + Some(Alternative { + pattern: Pattern::Ident(TypedIdent { + name: Symbol::from("_"), + typ: self.0.dummy_symbol.typ.clone(), + }), + expr: default, + }) + }; + let new_alts = group_order .into_iter() .map(|key| { @@ -1688,14 +1715,7 @@ impl<'a, 'e> PatternTranslator<'a, 'e> { expr: expr, } }) - .chain(if complete { - None - } else { - Some(Alternative { - pattern: Pattern::Ident(TypedIdent::new(Symbol::from("_"))), - expr: default, - }) - }) + .chain(default_alt) .collect::>(); let expr = Expr::Match( variables[0], @@ -1774,6 +1794,11 @@ impl<'a, 'e> PatternTranslator<'a, 'e> { } } + let default_alt = Alternative { + pattern: Pattern::Ident(self.0.dummy_symbol.clone()), + expr: default, + }; + let new_alts = group_order .into_iter() .map(|key| { @@ -1795,10 +1820,7 @@ impl<'a, 'e> PatternTranslator<'a, 'e> { expr: expr, } }) - .chain(Some(Alternative { - pattern: Pattern::Ident(TypedIdent::new(Symbol::from("_"))), - expr: default, - })) + .chain(Some(default_alt)) .collect::>(); let expr = Expr::Match( diff --git a/vm/src/macros.rs b/vm/src/macros.rs index 7bb6817de7..0635106226 100644 --- a/vm/src/macros.rs +++ b/vm/src/macros.rs @@ -555,9 +555,9 @@ impl<'a, 'b, 'c, 'e, 'ast> MutVisitor<'e, 'ast> for MacroVisitor<'a, 'b, 'c, '_, expander, .. } = self; - let generated_bindings = binds - .iter() - .flat_map(|bind| { + let mut generated_bindings = Vec::new(); + for bind in &**binds { + generated_bindings.extend( bind.metadata .attributes .iter() @@ -572,10 +572,9 @@ impl<'a, 'b, 'c, 'e, 'ast> MutVisitor<'e, 'ast> for MacroVisitor<'a, 'b, 'c, '_, } } }) - .flatten() - .collect::>() - }) - .collect::>(); + .flatten(), + ); + } if !generated_bindings.is_empty() { let next_expr = mem::take(*body); body.value =