Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
11 changes: 4 additions & 7 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn symbol_at(program: &SemanticProgram, file: FileId, offset: u32) -> Option
/// All use sites of a symbol (span of each resolution reference).
pub fn references(program: &SemanticProgram, symbol: SymbolId) -> Vec<Span> {
let mut out = Vec::new();
for (_, res) in &program.resolution {
for res in program.resolution.values() {
if let Resolution::Symbol(sid) = res {
if *sid == symbol {
out.push(program.tables.symbol(*sid).span);
Expand Down Expand Up @@ -125,7 +125,7 @@ fn expr_node_at(
walk_item_exprs(item, &mut |e: &crate::syntax::ast::Expr| {
if e.span.contains(offset) {
let size = e.span.end - e.span.start;
if best.map_or(true, |(_, s)| size <= s) {
if best.is_none_or(|(_, s)| size <= s) {
best = Some((e.id, size));
}
}
Expand Down Expand Up @@ -229,11 +229,8 @@ fn walk_stmt_exprs(s: &crate::syntax::ast::Stmt, f: &mut dyn FnMut(&crate::synta
}
}
}
K::Return { value } => {
if let Some(v) = value {
walk_expr_exprs(v, f);
}
}
K::Return { value: Some(v) } => walk_expr_exprs(v, f),
K::Return { value: None } => {}
K::Expr(e) => walk_expr_exprs(e, f),
K::Delete { target } => walk_expr_exprs(target, f),
K::Hook { target, value } => {
Expand Down
2 changes: 1 addition & 1 deletion src/compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub const REPORT_SCHEMA: u32 = 1;

/// Load and execute every source fixture in `tests/corpus`.
pub fn run(root: &Path) -> Result<CompatibilityReport, Vec<String>> {
let matrix = matrix::load_and_validate().map_err(|problems| problems)?;
let matrix = matrix::load_and_validate()?;
let fixtures = discover(root, &matrix)?;
let mut cases = Vec::with_capacity(fixtures.len());
for fixture in fixtures {
Expand Down
17 changes: 7 additions & 10 deletions src/hir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ pub struct Lowerer<'a> {
pub symbol_var: HashMap<SymbolId, HirVarId>,
/// var name node id -> HirVarId (locals during body lowering).
local_vars: HashMap<NodeId, HirVarId>,
/// Lambda expr node id -> HirFuncId.
lambda_funcs: HashMap<NodeId, HirFuncId>,
}

pub fn lower(program: &SemanticProgram) -> (HirProgram, Vec<crate::diagnostics::Diagnostic>) {
Expand All @@ -49,7 +47,6 @@ pub fn lower(program: &SemanticProgram) -> (HirProgram, Vec<crate::diagnostics::
symbol_enum: HashMap::new(),
symbol_var: HashMap::new(),
local_vars: HashMap::new(),
lambda_funcs: HashMap::new(),
};
l.run();
l.hir.exprs = std::mem::take(&mut l.exprs);
Expand Down Expand Up @@ -511,7 +508,7 @@ impl<'a> Lowerer<'a> {
}

fn lower_stmt(&mut self, s: &Stmt, out: &mut Vec<HirStmt>) {
let kind = self.lower_stmt_kind(s, out);
let kind = self.lower_stmt_kind(s);
out.push(HirStmt {
id: self.next_stmt,
span: s.span,
Expand All @@ -520,7 +517,7 @@ impl<'a> Lowerer<'a> {
self.next_stmt += 1;
}

fn lower_stmt_kind(&mut self, s: &Stmt, out: &mut Vec<HirStmt>) -> HirStmtKind {
fn lower_stmt_kind(&mut self, s: &Stmt) -> HirStmtKind {
match &s.kind {
StmtKind::Block(b) => HirStmtKind::Block(self.lower_block(b)),
StmtKind::Var(v) => {
Expand Down Expand Up @@ -728,7 +725,7 @@ impl<'a> Lowerer<'a> {
ExprKind::Null => HirExprKind::Literal(LiteralValue::Null),
ExprKind::Ident(_) => {
if let Some(Resolution::Symbol(sid)) = self.program.resolution.get(&e.id) {
if let Some(vid) = self.symbol_var.get(&sid) {
if let Some(vid) = self.symbol_var.get(sid) {
return HirExprKind::VarRef { var: *vid };
}
// Locals/params registered during body lowering by their
Expand All @@ -737,7 +734,7 @@ impl<'a> Lowerer<'a> {
if let Some(vid) = self.local_vars.get(&decl) {
return HirExprKind::VarRef { var: *vid };
}
if let Some(fid) = self.symbol_func.get(&sid) {
if let Some(fid) = self.symbol_func.get(sid) {
return HirExprKind::FunctionValue { func: *fid };
}
}
Expand Down Expand Up @@ -865,7 +862,7 @@ impl<'a> Lowerer<'a> {
}
}
if matches!(sym.kind, SymbolKind::Function | SymbolKind::Macro) {
if let Some(fid) = self.symbol_func.get(&sid) {
if let Some(fid) = self.symbol_func.get(sid) {
if let Some(class) = self.hir.funcs[*fid as usize].class {
return HirMemberTarget::MethodGroup {
class,
Expand All @@ -874,7 +871,7 @@ impl<'a> Lowerer<'a> {
}
}
}
if let Some(vid) = self.symbol_var.get(&sid) {
if let Some(vid) = self.symbol_var.get(sid) {
return HirMemberTarget::PlayervarAccess(*vid);
}
// Class field.
Expand Down Expand Up @@ -907,7 +904,7 @@ impl<'a> Lowerer<'a> {
BuiltinMember::Invoke => return HirMemberTarget::Invoke,
}),
Some(Resolution::PlayervarAccess(sid)) => {
if let Some(vid) = self.symbol_var.get(&sid) {
if let Some(vid) = self.symbol_var.get(sid) {
HirMemberTarget::PlayervarAccess(*vid)
} else {
HirMemberTarget::Invoke
Expand Down
11 changes: 2 additions & 9 deletions src/hir/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! before any backend exists. Not a Workshop runtime: external calls are
//! holes; events never fire.

use crate::diagnostics::{error, Diagnostic, Phase};
use crate::diagnostics::Diagnostic;
use crate::hir::*;
use crate::span::Span;
use std::collections::HashMap;
Expand Down Expand Up @@ -94,8 +94,6 @@ pub struct Oracle<'a> {
pub options: OracleOptions,
steps: u64,
depth: u32,
/// Per-loop iteration counters keyed by statement id.
loop_counts: HashMap<u32, u64>,
}

enum Flow {
Expand All @@ -121,14 +119,9 @@ impl<'a> Oracle<'a> {
options: OracleOptions::default(),
steps: 0,
depth: 0,
loop_counts: HashMap::new(),
}
}

fn diag(&mut self, code: &str, span: Span, msg: String) {
self.diagnostics.push(error(Phase::Oracle, code, span, msg));
}

fn step(&mut self, span: Span) -> Result<(), OracleError> {
self.steps += 1;
if self.steps > self.options.max_steps {
Expand Down Expand Up @@ -159,7 +152,7 @@ impl<'a> Oracle<'a> {
.globals
.get(var)
.cloned()
.ok_or_else(|| OracleError::Undefined { span: e.span })?;
.ok_or(OracleError::Undefined { span: e.span })?;
Ok(v)
}
HirExprKind::Member { base, member } => {
Expand Down
20 changes: 9 additions & 11 deletions src/hir/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::semantic::types::Type;

pub fn validate(hir: &HirProgram) -> Vec<Diagnostic> {
let mut diags = Vec::new();
let mut err = |code: &str, span: crate::span::Span, msg: String, out: &mut Vec<Diagnostic>| {
let err = |code: &str, span: crate::span::Span, msg: String, out: &mut Vec<Diagnostic>| {
out.push(error(Phase::Hir, code, span, msg));
};

Expand All @@ -26,22 +26,20 @@ pub fn validate(hir: &HirProgram) -> Vec<Diagnostic> {
);
}
}
HirExprKind::New { class, .. } => {
if *class as usize >= hir.classes.len() {
err(
"HI010",
e.span,
format!("new targets unknown class {class}"),
&mut diags,
);
}
HirExprKind::New { class, .. } if *class as usize >= hir.classes.len() => {
err(
"HI010",
e.span,
format!("new targets unknown class {class}"),
&mut diags,
);
}
_ => {}
}
}

// HI006: assignment targets are lvalues.
for (_, e) in hir.exprs.iter().enumerate() {
for e in &hir.exprs {
if let HirExprKind::Assign { target, .. } = &e.kind {
match &hir.expr(*target).map(|t| &t.kind) {
Some(HirExprKind::VarRef { .. })
Expand Down
58 changes: 29 additions & 29 deletions src/semantic/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ impl<'a> Checker<'a> {
..Default::default()
},
};
if let Err(_) = self.program.tables.declare(self.scope(), sym) {
if self.program.tables.declare(self.scope(), sym).is_err() {
self.err(
"SM001",
v.name.span,
Expand Down Expand Up @@ -679,7 +679,7 @@ impl<'a> Checker<'a> {
&& !scrut.is_external()
&& !lt.is_error()
&& !lt.is_external()
&& self.conversion(&lt, &scrut).rank() >= 255
&& self.conversion(&lt, &scrut).rank() == 255
{
self.err(
"SM026",
Expand Down Expand Up @@ -1017,9 +1017,10 @@ impl<'a> Checker<'a> {
tt
} else if self.conversion(&tt, &et).rank() < 255 {
et
} else if self.conversion(&et, &tt).rank() < 255 {
tt
} else if tt.is_external() || et.is_external() {
} else if self.conversion(&et, &tt).rank() < 255
|| tt.is_external()
|| et.is_external()
{
tt
} else {
Type::Any
Expand Down Expand Up @@ -1267,8 +1268,8 @@ impl<'a> Checker<'a> {
fn check_binary_op(&mut self, op: &BinaryOp, lt: &Type, rt: &Type, span: Span) -> Type {
match op {
BinaryOp::Eq | BinaryOp::Ne => {
if self.conversion(lt, rt).rank() >= 255
&& self.conversion(rt, lt).rank() >= 255
if self.conversion(lt, rt).rank() == 255
&& self.conversion(rt, lt).rank() == 255
&& !lt.is_external()
&& !rt.is_external()
&& !lt.is_error()
Expand Down Expand Up @@ -1559,12 +1560,14 @@ impl<'a> Checker<'a> {
{
return true;
}
match self.program.types.get(&base.id) {
Some(Type::Class(_)) => true,
Some(Type::Player) => true,
Some(Type::External(_)) | Some(Type::Any) | None => true,
_ => false,
}
matches!(
self.program.types.get(&base.id),
Some(Type::Class(_))
| Some(Type::Player)
| Some(Type::External(_))
| Some(Type::Any)
| None
)
}
_ => self
.program
Expand Down Expand Up @@ -1669,15 +1672,13 @@ impl<'a> Checker<'a> {
self.record(expr, ty.clone(), Some(Resolution::Symbol(mid)));
return ty;
}
if matches!(base_ty, Type::Enum(_)) {
if name.name == "Key" || name.name == "Name" {
self.record(
expr,
Type::Number,
Some(Resolution::BuiltinMember(BuiltinMember::Key)),
);
return Type::Number;
}
if matches!(base_ty, Type::Enum(_)) && (name.name == "Key" || name.name == "Name") {
self.record(
expr,
Type::Number,
Some(Resolution::BuiltinMember(BuiltinMember::Key)),
);
return Type::Number;
}
if let Type::Array(elem) = base_ty {
let bm = match name.name.as_str() {
Expand Down Expand Up @@ -2268,14 +2269,13 @@ impl<'a> Checker<'a> {
if matches!(
bm,
BuiltinMember::ArrayModAppend | BuiltinMember::ArrayModRemoveByIndex
) {
if !self.check_lvalue(base) {
self.err(
) && !self.check_lvalue(base)
{
self.err(
"SM017",
base.span,
"functions that directly modify arrays require a mutable variable as the source",
);
}
}
Type::Any
}
Expand Down Expand Up @@ -2427,13 +2427,13 @@ impl<'a> Checker<'a> {
} else {
self.conversion(at, pt)
};
if c.rank() >= 255 && !pt.is_external() {
if c.rank() == 255 && !pt.is_external() {
conv_ok = false;
break;
}
rank = rank.max(c.rank() as u32);
}
if conv_ok && best.as_ref().map_or(true, |(_, r)| rank < *r) {
if conv_ok && best.as_ref().is_none_or(|(_, r)| rank < *r) {
best = Some((sid, rank));
}
}
Expand Down Expand Up @@ -2465,7 +2465,7 @@ impl<'a> Checker<'a> {
fn param_info_inner(&mut self, sid: SymbolId) -> (Vec<String>, Vec<bool>) {
for file in &self.program.project.files {
if let Some(parsed) = self.program.asts.get(file) {
if let Some(info) = find_param_info(parsed, sid, &self.program) {
if let Some(info) = find_param_info(parsed, sid, self.program) {
return info;
}
}
Expand Down
19 changes: 8 additions & 11 deletions src/semantic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,15 +942,15 @@ impl<'a> Builder<'a> {
let sym_ty = self.tables.symbol(*mid).ty.clone();
let sym_kind = self.tables.symbol(*mid).kind;
if sym_kind == SymbolKind::Variable {
self.collect_value_refs(&sym_ty, *tid, &mut targets);
self.collect_value_refs(&sym_ty, &mut targets);
} else if sym_kind == SymbolKind::EnumMember {
let fts = self
.enum_members
.get(mid)
.map(|i| i.field_types.clone())
.unwrap_or_default();
for ft in &fts {
self.collect_value_refs(ft, *tid, &mut targets);
self.collect_value_refs(ft, &mut targets);
}
}
}
Expand Down Expand Up @@ -991,9 +991,9 @@ impl<'a> Builder<'a> {
}
}

fn collect_value_refs(&mut self, ty: &Type, self_id: SymbolId, out: &mut Vec<SymbolId>) {
fn collect_value_refs(&mut self, ty: &Type, out: &mut Vec<SymbolId>) {
match ty {
Type::Array(inner) => self.collect_value_refs(inner, self_id, out),
Type::Array(inner) => self.collect_value_refs(inner, out),
Type::Struct(id) | Type::Enum(id) => out.push(*id),
Type::GenericInstantiation { def, args } => {
let kind = self.tables.symbol(*def).kind;
Expand Down Expand Up @@ -1021,7 +1021,7 @@ impl<'a> Builder<'a> {
let sym_kind = self.tables.symbol(*mid).kind;
if sym_kind == SymbolKind::Variable {
let subst_ty = substitute(&sym_ty, &subst);
self.collect_value_refs(&subst_ty, self_id, out);
self.collect_value_refs(&subst_ty, out);
} else if sym_kind == SymbolKind::EnumMember {
let fts = self
.enum_members
Expand All @@ -1030,7 +1030,7 @@ impl<'a> Builder<'a> {
.unwrap_or_default();
for ft in &fts {
let subst_ty = substitute(ft, &subst);
self.collect_value_refs(&subst_ty, self_id, out);
self.collect_value_refs(&subst_ty, out);
}
}
}
Expand Down Expand Up @@ -1331,11 +1331,8 @@ fn collect_call_names(body: &FuncBody, out: &mut Vec<String>) {
}
}
}
StmtKind::Return { value } => {
if let Some(v) = value {
walk_expr(v, out);
}
}
StmtKind::Return { value: Some(v) } => walk_expr(v, out),
StmtKind::Return { value: None } => {}
StmtKind::Delete { target } => walk_expr(target, out),
StmtKind::Hook { target, value } => {
walk_expr(target, out);
Expand Down
Loading