use only references (no Vec) in canonical AST

This commit is contained in:
Folkert 2020-10-26 01:03:33 +01:00
parent b91a76bb5c
commit 93a1baad1d
7 changed files with 74 additions and 35 deletions

View File

@ -110,7 +110,7 @@ pub fn canonicalize_defs<'a>(
mut output: Output, mut output: Output,
var_store: &mut VarStore, var_store: &mut VarStore,
original_scope: &Scope, original_scope: &Scope,
loc_defs: &'a bumpalo::collections::Vec<'a, &'a Located<ast::Def<'a>>>, loc_defs: &'a [&'a Located<ast::Def<'a>>],
pattern_type: PatternType, pattern_type: PatternType,
) -> (CanDefs, Scope, Output, MutMap<Symbol, Region>) { ) -> (CanDefs, Scope, Output, MutMap<Symbol, Region>) {
// Canonicalizing defs while detecting shadowing involves a multi-step process: // Canonicalizing defs while detecting shadowing involves a multi-step process:
@ -1239,7 +1239,7 @@ pub fn can_defs_with_return<'a>(
env: &mut Env<'a>, env: &mut Env<'a>,
var_store: &mut VarStore, var_store: &mut VarStore,
scope: Scope, scope: Scope,
loc_defs: &'a bumpalo::collections::Vec<'a, &'a Located<ast::Def<'a>>>, loc_defs: &'a [&'a Located<ast::Def<'a>>],
loc_ret: &'a Located<ast::Expr<'a>>, loc_ret: &'a Located<ast::Expr<'a>>,
) -> (Expr, Output) { ) -> (Expr, Output) {
let (unsorted, mut scope, defs_output, symbols_introduced) = canonicalize_defs( let (unsorted, mut scope, defs_output, symbols_introduced) = canonicalize_defs(

View File

@ -309,7 +309,7 @@ pub fn canonicalize_expr<'a>(
let mut args = Vec::new(); let mut args = Vec::new();
let mut outputs = Vec::new(); let mut outputs = Vec::new();
for loc_arg in loc_args { for loc_arg in loc_args.iter() {
let (arg_expr, arg_out) = let (arg_expr, arg_out) =
canonicalize_expr(env, var_store, scope, loc_arg.region, &loc_arg.value); canonicalize_expr(env, var_store, scope, loc_arg.region, &loc_arg.value);
@ -562,7 +562,7 @@ pub fn canonicalize_expr<'a>(
let mut can_branches = Vec::with_capacity(branches.len()); let mut can_branches = Vec::with_capacity(branches.len());
for branch in branches { for branch in branches.iter() {
let (can_when_branch, branch_references) = let (can_when_branch, branch_references) =
canonicalize_when_branch(env, var_store, scope, region, *branch, &mut output); canonicalize_when_branch(env, var_store, scope, region, *branch, &mut output);
@ -788,7 +788,7 @@ fn canonicalize_when_branch<'a>(
let mut scope = original_scope.clone(); let mut scope = original_scope.clone();
// TODO report symbols not bound in all patterns // TODO report symbols not bound in all patterns
for loc_pattern in &branch.patterns { for loc_pattern in branch.patterns.iter() {
let (new_output, can_pattern) = canonicalize_pattern( let (new_output, can_pattern) = canonicalize_pattern(
env, env,
var_store, var_store,

View File

@ -42,7 +42,7 @@ pub struct ModuleOutput {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn canonicalize_module_defs<'a>( pub fn canonicalize_module_defs<'a>(
arena: &Bump, arena: &Bump,
loc_defs: bumpalo::collections::Vec<'a, Located<ast::Def<'a>>>, loc_defs: &'a [Located<ast::Def<'a>>],
home: ModuleId, home: ModuleId,
module_ids: &ModuleIds, module_ids: &ModuleIds,
exposed_ident_ids: IdentIds, exposed_ident_ids: IdentIds,
@ -65,9 +65,9 @@ pub fn canonicalize_module_defs<'a>(
let mut desugared = let mut desugared =
bumpalo::collections::Vec::with_capacity_in(loc_defs.len() + num_deps, arena); bumpalo::collections::Vec::with_capacity_in(loc_defs.len() + num_deps, arena);
for loc_def in loc_defs { for loc_def in loc_defs.iter() {
desugared.push(&*arena.alloc(Located { desugared.push(&*arena.alloc(Located {
value: desugar_def(arena, arena.alloc(loc_def.value)), value: desugar_def(arena, &loc_def.value),
region: loc_def.region, region: loc_def.region,
})); }));
} }

View File

@ -90,9 +90,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
List(elems) | Nested(List(elems)) => { List(elems) | Nested(List(elems)) => {
let mut new_elems = Vec::with_capacity_in(elems.len(), arena); let mut new_elems = Vec::with_capacity_in(elems.len(), arena);
for elem in elems { for elem in elems.iter() {
new_elems.push(desugar_expr(arena, elem)); new_elems.push(desugar_expr(arena, elem));
} }
let new_elems = new_elems.into_bump_slice();
let value: Expr<'a> = List(new_elems); let value: Expr<'a> = List(new_elems);
arena.alloc(Located { arena.alloc(Located {
@ -103,7 +104,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
Record { fields, update } | Nested(Record { fields, update }) => { Record { fields, update } | Nested(Record { fields, update }) => {
let mut new_fields = Vec::with_capacity_in(fields.len(), arena); let mut new_fields = Vec::with_capacity_in(fields.len(), arena);
for field in fields { for field in fields.iter() {
let value = desugar_field(arena, &field.value); let value = desugar_field(arena, &field.value);
new_fields.push(Located { new_fields.push(Located {
@ -112,6 +113,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
}); });
} }
let new_fields = new_fields.into_bump_slice();
arena.alloc(Located { arena.alloc(Located {
region: loc_expr.region, region: loc_expr.region,
value: Record { value: Record {
@ -139,6 +142,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
desugared_defs.push(&*arena.alloc(loc_def)); desugared_defs.push(&*arena.alloc(loc_def));
} }
let desugared_defs = desugared_defs.into_bump_slice();
arena.alloc(Located { arena.alloc(Located {
value: Defs(desugared_defs, desugar_expr(arena, loc_ret)), value: Defs(desugared_defs, desugar_expr(arena, loc_ret)),
region: loc_expr.region, region: loc_expr.region,
@ -147,10 +152,12 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
Apply(loc_fn, loc_args, called_via) | Nested(Apply(loc_fn, loc_args, called_via)) => { Apply(loc_fn, loc_args, called_via) | Nested(Apply(loc_fn, loc_args, called_via)) => {
let mut desugared_args = Vec::with_capacity_in(loc_args.len(), arena); let mut desugared_args = Vec::with_capacity_in(loc_args.len(), arena);
for loc_arg in loc_args { for loc_arg in loc_args.iter() {
desugared_args.push(desugar_expr(arena, loc_arg)); desugared_args.push(desugar_expr(arena, loc_arg));
} }
let desugared_args = desugared_args.into_bump_slice();
arena.alloc(Located { arena.alloc(Located {
value: Apply(desugar_expr(arena, loc_fn), desugared_args, *called_via), value: Apply(desugar_expr(arena, loc_fn), desugared_args, *called_via),
region: loc_expr.region, region: loc_expr.region,
@ -164,7 +171,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
let desugared = desugar_expr(arena, &branch.value); let desugared = desugar_expr(arena, &branch.value);
let mut alternatives = Vec::with_capacity_in(branch.patterns.len(), arena); let mut alternatives = Vec::with_capacity_in(branch.patterns.len(), arena);
for loc_pattern in &branch.patterns { for loc_pattern in branch.patterns.iter() {
alternatives.push(Located { alternatives.push(Located {
region: loc_pattern.region, region: loc_pattern.region,
value: Pattern::Nested(&loc_pattern.value), value: Pattern::Nested(&loc_pattern.value),
@ -177,6 +184,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
None None
}; };
let alternatives = alternatives.into_bump_slice();
desugared_branches.push(&*arena.alloc(WhenBranch { desugared_branches.push(&*arena.alloc(WhenBranch {
patterns: alternatives, patterns: alternatives,
value: Located { value: Located {
@ -187,6 +196,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
})); }));
} }
let desugared_branches = desugared_branches.into_bump_slice();
arena.alloc(Located { arena.alloc(Located {
value: When(loc_desugared_cond, desugared_branches), value: When(loc_desugared_cond, desugared_branches),
region: loc_expr.region, region: loc_expr.region,
@ -213,6 +224,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
let loc_fn_var = arena.alloc(Located { region, value }); let loc_fn_var = arena.alloc(Located { region, value });
let desugared_args = bumpalo::vec![in arena; desugar_expr(arena, loc_arg)]; let desugared_args = bumpalo::vec![in arena; desugar_expr(arena, loc_arg)];
let desugared_args = desugared_args.into_bump_slice();
arena.alloc(Located { arena.alloc(Located {
value: Apply(loc_fn_var, desugared_args, CalledVia::UnaryOp(op)), value: Apply(loc_fn_var, desugared_args, CalledVia::UnaryOp(op)),
region: loc_expr.region, region: loc_expr.region,
@ -463,10 +476,12 @@ fn desugar_bin_op<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'_>>) -> &'a L
args.push(left); args.push(left);
for arg in arguments { for arg in arguments.iter() {
args.push(arg); args.push(arg);
} }
let args = args.into_bump_slice();
Apply(function, args, CalledVia::BinOp(Pizza)) Apply(function, args, CalledVia::BinOp(Pizza))
} }
expr => { expr => {
@ -480,6 +495,8 @@ fn desugar_bin_op<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'_>>) -> &'a L
region: right.region, region: right.region,
}); });
let args = args.into_bump_slice();
Apply(function, args, CalledVia::BinOp(Pizza)) Apply(function, args, CalledVia::BinOp(Pizza))
} }
} }
@ -498,6 +515,8 @@ fn desugar_bin_op<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'_>>) -> &'a L
region: loc_op.region, region: loc_op.region,
}); });
let args = args.into_bump_slice();
Apply(loc_expr, args, CalledVia::BinOp(binop)) Apply(loc_expr, args, CalledVia::BinOp(binop))
} }
}; };

View File

@ -32,7 +32,7 @@ pub struct DocEntry {
pub fn generate_module_docs<'a>( pub fn generate_module_docs<'a>(
module_name: ModuleName, module_name: ModuleName,
exposed_ident_ids: &'a IdentIds, exposed_ident_ids: &'a IdentIds,
parsed_defs: &'a bumpalo::collections::Vec<'a, Located<Def<'a>>>, parsed_defs: &'a [Located<Def<'a>>],
) -> ModuleDocumentation { ) -> ModuleDocumentation {
let (entries, _) = let (entries, _) =
parsed_defs parsed_defs

View File

@ -29,7 +29,7 @@ pub struct InterfaceHeader<'a> {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct WhenBranch<'a> { pub struct WhenBranch<'a> {
pub patterns: Vec<'a, Loc<Pattern<'a>>>, pub patterns: &'a [Loc<Pattern<'a>>],
pub value: Loc<Expr<'a>>, pub value: Loc<Expr<'a>>,
pub guard: Option<Loc<Expr<'a>>>, pub guard: Option<Loc<Expr<'a>>>,
} }
@ -188,10 +188,10 @@ pub enum Expr<'a> {
AccessorFunction(&'a str), AccessorFunction(&'a str),
// Collection Literals // Collection Literals
List(Vec<'a, &'a Loc<Expr<'a>>>), List(&'a [&'a Loc<Expr<'a>>]),
Record { Record {
update: Option<&'a Loc<Expr<'a>>>, update: Option<&'a Loc<Expr<'a>>>,
fields: Vec<'a, Loc<AssignedField<'a, Expr<'a>>>>, fields: &'a [Loc<AssignedField<'a, Expr<'a>>>],
}, },
// Lookups // Lookups
@ -205,14 +205,14 @@ pub enum Expr<'a> {
PrivateTag(&'a str), PrivateTag(&'a str),
// Pattern Matching // Pattern Matching
Closure(&'a Vec<'a, Loc<Pattern<'a>>>, &'a Loc<Expr<'a>>), Closure(&'a [Loc<Pattern<'a>>], &'a Loc<Expr<'a>>),
/// Multiple defs in a row /// Multiple defs in a row
Defs(Vec<'a, &'a Loc<Def<'a>>>, &'a Loc<Expr<'a>>), Defs(&'a [&'a Loc<Def<'a>>], &'a Loc<Expr<'a>>),
// Application // Application
/// To apply by name, do Apply(Var(...), ...) /// To apply by name, do Apply(Var(...), ...)
/// To apply a tag by name, do Apply(Tag(...), ...) /// To apply a tag by name, do Apply(Tag(...), ...)
Apply(&'a Loc<Expr<'a>>, Vec<'a, &'a Loc<Expr<'a>>>, CalledVia), Apply(&'a Loc<Expr<'a>>, &'a [&'a Loc<Expr<'a>>], CalledVia),
BinOp(&'a (Loc<Expr<'a>>, Loc<BinOp>, Loc<Expr<'a>>)), BinOp(&'a (Loc<Expr<'a>>, Loc<BinOp>, Loc<Expr<'a>>)),
UnaryOp(&'a Loc<Expr<'a>>, Loc<UnaryOp>), UnaryOp(&'a Loc<Expr<'a>>, Loc<UnaryOp>),
@ -226,7 +226,7 @@ pub enum Expr<'a> {
/// Vec, because there may be many patterns, and the guard /// Vec, because there may be many patterns, and the guard
/// is Option<Expr> because each branch may be preceded by /// is Option<Expr> because each branch may be preceded by
/// a guard (".. if .."). /// a guard (".. if ..").
Vec<'a, &'a WhenBranch<'a>>, &'a [&'a WhenBranch<'a>],
), ),
// Blank Space (e.g. comments, spaces, newlines) before or after an expression. // Blank Space (e.g. comments, spaces, newlines) before or after an expression.

View File

@ -82,7 +82,7 @@ macro_rules! loc_parenthetical_expr {
region: loc_expr_with_extras.region, region: loc_expr_with_extras.region,
value: Expr::Apply( value: Expr::Apply(
arena.alloc(loc_expr), arena.alloc(loc_expr),
allocated_args, allocated_args.into_bump_slice(),
CalledVia::Space, CalledVia::Space,
), ),
}, },
@ -250,7 +250,7 @@ fn expr_to_pattern<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>,
let mut arg_patterns = Vec::with_capacity_in(loc_args.len(), arena); let mut arg_patterns = Vec::with_capacity_in(loc_args.len(), arena);
for loc_arg in loc_args { for loc_arg in loc_args.iter() {
let region = loc_arg.region; let region = loc_arg.region;
let value = expr_to_pattern(arena, &loc_arg.value)?; let value = expr_to_pattern(arena, &loc_arg.value)?;
@ -279,7 +279,7 @@ fn expr_to_pattern<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>,
} => { } => {
let mut loc_patterns = Vec::with_capacity_in(fields.len(), arena); let mut loc_patterns = Vec::with_capacity_in(fields.len(), arena);
for loc_assigned_field in fields { for loc_assigned_field in fields.iter() {
let region = loc_assigned_field.region; let region = loc_assigned_field.region;
let value = assigned_expr_field_to_pattern(arena, &loc_assigned_field.value)?; let value = assigned_expr_field_to_pattern(arena, &loc_assigned_field.value)?;
@ -691,7 +691,10 @@ fn parse_def_expr<'a>(
// for formatting reasons, we must insert the first def first! // for formatting reasons, we must insert the first def first!
defs.insert(0, arena.alloc(loc_first_def)); defs.insert(0, arena.alloc(loc_first_def));
Ok((Expr::Defs(defs, arena.alloc(loc_ret)), state)) Ok((
Expr::Defs(defs.into_bump_slice(), arena.alloc(loc_ret)),
state,
))
}, },
) )
.parse(arena, state) .parse(arena, state)
@ -766,6 +769,8 @@ fn parse_def_signature<'a>(
// corresponding definition (the one with the body). // corresponding definition (the one with the body).
defs.insert(0, arena.alloc(loc_first_def)); defs.insert(0, arena.alloc(loc_first_def));
let defs = defs.into_bump_slice();
Ok((Expr::Defs(defs, arena.alloc(loc_ret)), state)) Ok((Expr::Defs(defs, arena.alloc(loc_ret)), state))
}, },
) )
@ -848,7 +853,12 @@ fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
), ),
|arena: &'a Bump, opt_contents| match opt_contents { |arena: &'a Bump, opt_contents| match opt_contents {
None => Expr::MalformedClosure, None => Expr::MalformedClosure,
Some((params, loc_body)) => Expr::Closure(arena.alloc(params), arena.alloc(loc_body)), Some((params, loc_body)) => {
let params: Vec<'a, Located<Pattern<'a>>> = params;
let params: &'a [Located<Pattern<'a>>] = params.into_bump_slice();
Expr::Closure(params, arena.alloc(loc_body))
}
} }
) )
} }
@ -1119,7 +1129,10 @@ mod when {
let (branches, state) = let (branches, state) =
attempt!(Attempting::WhenBranch, branches(min_indent)).parse(arena, state)?; attempt!(Attempting::WhenBranch, branches(min_indent)).parse(arena, state)?;
Ok((Expr::When(arena.alloc(loc_condition), branches), state)) Ok((
Expr::When(arena.alloc(loc_condition), branches.into_bump_slice()),
state,
))
}, },
) )
} }
@ -1152,7 +1165,7 @@ mod when {
// Record this as the first branch, then optionally parse additional branches. // Record this as the first branch, then optionally parse additional branches.
branches.push(arena.alloc(WhenBranch { branches.push(arena.alloc(WhenBranch {
patterns: loc_first_patterns, patterns: loc_first_patterns.into_bump_slice(),
value: loc_first_expr, value: loc_first_expr,
guard: loc_first_guard, guard: loc_first_guard,
})); }));
@ -1173,10 +1186,13 @@ mod when {
), ),
branch_result(indented_more) branch_result(indented_more)
), ),
|((patterns, guard), expr)| WhenBranch { |((patterns, guard), expr)| {
patterns, let patterns: Vec<'a, _> = patterns;
value: expr, WhenBranch {
guard patterns: patterns.into_bump_slice(),
value: expr,
guard,
}
} }
); );
@ -1444,7 +1460,11 @@ fn ident_etc<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
} }
Ok(( Ok((
Expr::Apply(arena.alloc(loc_expr), allocated_args, CalledVia::Space), Expr::Apply(
arena.alloc(loc_expr),
allocated_args.into_bump_slice(),
CalledVia::Space,
),
state, state,
)) ))
} }
@ -1638,7 +1658,7 @@ pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
allocated.push(&*arena.alloc(parsed_elem)); allocated.push(&*arena.alloc(parsed_elem));
} }
Expr::List(allocated) Expr::List(allocated.into_bump_slice())
}), }),
) )
} }
@ -1663,7 +1683,7 @@ pub fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
// This is a record literal, not a destructure. // This is a record literal, not a destructure.
let mut value = Expr::Record { let mut value = Expr::Record {
update: opt_update.map(|loc_expr| &*arena.alloc(loc_expr)), update: opt_update.map(|loc_expr| &*arena.alloc(loc_expr)),
fields: loc_assigned_fields.value, fields: loc_assigned_fields.value.into_bump_slice(),
}; };
// there can be field access, e.g. `{ x : 4 }.x` // there can be field access, e.g. `{ x : 4 }.x`