Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the return keyword #7173

Merged
merged 19 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ fn main() -> io::Result<()> {
current_block = String::new();
} else if in_roc_block {
current_block.push_str(&line);
current_block.push_str("\n");
current_block.push('\n');
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/compiler/can/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ fn defn_help(
function_type: var_store.fresh(),
closure_type: var_store.fresh(),
return_type: ret_var,
early_returns: vec![],
name: fn_name,
captured_symbols: Vec::new(),
recursive: Recursive::NotRecursive,
Expand Down
2 changes: 2 additions & 0 deletions crates/compiler/can/src/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ impl Constraints {
Category::List,
Category::Str,
Category::Character,
Category::Return,
]);

pattern_categories.extend([
Expand Down Expand Up @@ -150,6 +151,7 @@ impl Constraints {
pub const CATEGORY_LIST: Index<Category> = Index::new(11);
pub const CATEGORY_STR: Index<Category> = Index::new(12);
pub const CATEGORY_CHARACTER: Index<Category> = Index::new(13);
pub const CATEGORY_RETURN: Index<Category> = Index::new(14);

pub const PCATEGORY_RECORD: Index<PatternCategory> = Index::new(0);
pub const PCATEGORY_EMPTYRECORD: Index<PatternCategory> = Index::new(1);
Expand Down
13 changes: 13 additions & 0 deletions crates/compiler/can/src/copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
function_type,
closure_type,
return_type,
early_returns,
name,
captured_symbols,
recursive,
Expand All @@ -465,6 +466,10 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
function_type: sub!(*function_type),
closure_type: sub!(*closure_type),
return_type: sub!(*return_type),
early_returns: early_returns
.iter()
.map(|(var, region)| (sub!(*var), *region))
.collect(),
name: *name,
captured_symbols: captured_symbols
.iter()
Expand Down Expand Up @@ -688,6 +693,14 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
lookups_in_cond: lookups_in_cond.to_vec(),
},

Return {
return_value,
return_var,
} => Return {
return_value: Box::new(return_value.map(|e| go_help!(e))),
return_var: sub!(*return_var),
},

Dbg {
source_location,
source,
Expand Down
1 change: 1 addition & 0 deletions crates/compiler/can/src/debug/pretty_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a,
Dbg { .. } => todo!(),
Expect { .. } => todo!(),
ExpectFx { .. } => todo!(),
Return { .. } => todo!(),
TypedHole(_) => todo!(),
RuntimeError(_) => todo!(),
}
Expand Down
20 changes: 15 additions & 5 deletions crates/compiler/can/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,7 @@ impl DefOrdering {
}

#[inline(always)]
pub(crate) fn sort_can_defs_new(
pub(crate) fn sort_top_level_can_defs(
env: &mut Env<'_>,
scope: &mut Scope,
var_store: &mut VarStore,
Expand Down Expand Up @@ -2354,6 +2354,7 @@ fn canonicalize_pending_value_def<'a>(
function_type: var_store.fresh(),
closure_type: var_store.fresh(),
return_type: var_store.fresh(),
early_returns: scope.early_returns.clone(),
name: symbol,
captured_symbols: Vec::new(),
recursive: Recursive::NotRecursive,
Expand Down Expand Up @@ -2571,6 +2572,8 @@ fn canonicalize_pending_body<'a>(
loc_value = value;
}

let expr_var = var_store.fresh();

// We treat closure definitions `foo = \a, b -> ...` differently from other body expressions,
// because they need more bookkeeping (for tail calls, closure captures, etc.)
//
Expand Down Expand Up @@ -2602,9 +2605,17 @@ fn canonicalize_pending_body<'a>(
env.tailcallable_symbol = outer_tailcallable;

// The closure is self tail recursive iff it tail calls itself (by defined name).
let is_recursive = match can_output.tail_call {
Some(tail_symbol) if tail_symbol == *defined_symbol => Recursive::TailRecursive,
_ => Recursive::NotRecursive,
let is_recursive = if can_output
.early_tail_calls
.iter()
.chain(std::iter::once(&can_output.final_tail_call))
.all(|tail_call| {
matches!(tail_call, Some(tail_symbol) if tail_symbol == defined_symbol)
})
{
Recursive::TailRecursive
} else {
Recursive::NotRecursive
};

closure_data.recursive = is_recursive;
Expand Down Expand Up @@ -2664,7 +2675,6 @@ fn canonicalize_pending_body<'a>(
}
};

let expr_var = var_store.fresh();
let mut vars_by_symbol = SendMap::default();

pattern_to_vars_by_symbol(&mut vars_by_symbol, &loc_can_pattern.value, expr_var);
Expand Down
13 changes: 11 additions & 2 deletions crates/compiler/can/src/desugar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
}
},

// TODO support desugaring of Dbg, Expect, and ExpectFx
// TODO support desugaring of Dbg and ExpectFx
Dbg { .. } | ExpectFx { .. } => value_def,
ModuleImport { .. } | IngestedFileImport(_) => value_def,

Expand Down Expand Up @@ -1008,6 +1008,7 @@ pub fn desugar_expr<'a>(
Expect(condition, continuation) => {
let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition));
let desugared_continuation = &*env.arena.alloc(desugar_expr(env, scope, continuation));

env.arena.alloc(Loc {
value: Expect(desugared_condition, desugared_continuation),
region: loc_expr.region,
Expand All @@ -1019,14 +1020,22 @@ pub fn desugar_expr<'a>(
}
DbgStmt(condition, continuation) => {
let desugared_condition = &*env.arena.alloc(desugar_expr(env, scope, condition));

let desugared_continuation = &*env.arena.alloc(desugar_expr(env, scope, continuation));

env.arena.alloc(Loc {
value: *desugar_dbg_stmt(env, desugared_condition, desugared_continuation),
region: loc_expr.region,
})
}
Return(return_value, after_return) => {
let desugared_return_value = &*env.arena.alloc(desugar_expr(env, scope, return_value));

env.arena.alloc(Loc {
// Do not desugar after_return since it isn't run anyway
value: Return(desugared_return_value, *after_return),
region: loc_expr.region,
})
}

// note this only exists after desugaring
LowLevelDbg(_, _, _) => loc_expr,
Expand Down
Loading
Loading