use crate::{
body::Body,
db::DefDatabase,
- expr::{Expr, ExprId, LabelId, Pat, PatId, Statement},
+ expr::{Expr, ExprId, LabelId, MatchGuard, Pat, PatId, Statement},
BlockId, DefWithBodyId,
};
) {
for stmt in statements {
match stmt {
- Statement::Let { pat, initializer, .. } => {
+ Statement::Let { pat, initializer, else_branch, .. } => {
if let Some(expr) = initializer {
- scopes.set_scope(*expr, scope);
+ compute_expr_scopes(*expr, body, scopes, scope);
+ }
+ if let Some(expr) = else_branch {
compute_expr_scopes(*expr, body, scopes, scope);
}
scope = scopes.new_scope(scope);
scopes.add_bindings(body, scope, *pat);
}
Statement::Expr { expr, .. } => {
- scopes.set_scope(*expr, scope);
compute_expr_scopes(*expr, body, scopes, scope);
}
}
fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) {
let make_label =
- |label: &Option<_>| label.map(|label| (label, body.labels[label].name.clone()));
+ |label: &Option<LabelId>| label.map(|label| (label, body.labels[label].name.clone()));
scopes.set_scope(expr, scope);
match &body[expr] {
}
Expr::Lambda { args, body: body_expr, .. } => {
let scope = scopes.new_scope(scope);
- scopes.add_params_bindings(body, scope, &args);
+ scopes.add_params_bindings(body, scope, args);
compute_expr_scopes(*body_expr, body, scopes, scope);
}
Expr::Match { expr, arms } => {
compute_expr_scopes(*expr, body, scopes, scope);
- for arm in arms {
- let scope = scopes.new_scope(scope);
+ for arm in arms.iter() {
+ let mut scope = scopes.new_scope(scope);
scopes.add_bindings(body, scope, arm.pat);
- if let Some(guard) = arm.guard {
- scopes.set_scope(guard, scope);
- compute_expr_scopes(guard, body, scopes, scope);
- }
+ match arm.guard {
+ Some(MatchGuard::If { expr: guard }) => {
+ scopes.set_scope(guard, scope);
+ compute_expr_scopes(guard, body, scopes, scope);
+ }
+ Some(MatchGuard::IfLet { pat, expr: guard }) => {
+ scopes.set_scope(guard, scope);
+ compute_expr_scopes(guard, body, scopes, scope);
+ scope = scopes.new_scope(scope);
+ scopes.add_bindings(body, scope, pat);
+ }
+ _ => {}
+ };
scopes.set_scope(arm.expr, scope);
compute_expr_scopes(arm.expr, body, scopes, scope);
}
let actual = scopes
.scope_chain(scope)
.flat_map(|scope| scopes.entries(scope))
- .map(|it| it.name().to_string())
+ .map(|it| it.name().to_smol_str())
.collect::<Vec<_>>()
.join("\n");
let expected = expected.join("\n");