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
10 changes: 5 additions & 5 deletions ephapax-linear/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ fn p2p_single_consume_always_accepted_both_disciplines() {
let expr = e(ExprKind::LetLin {
name: name.clone().into(),
ty: Some(Ty::Base(BaseTy::I32)),
value: Box::new(i32_lit(i as i32)),
value: Box::new(i32_lit(i)),
body: Box::new(var(&name)),
});

Expand Down Expand Up @@ -413,7 +413,7 @@ fn p2p_contraction_always_rejected_both_disciplines() {
let expr = e(ExprKind::LetLin {
name: name.clone().into(),
ty: Some(Ty::Base(BaseTy::I32)),
value: Box::new(i32_lit(i as i32)),
value: Box::new(i32_lit(i)),
body: Box::new(e(ExprKind::Pair {
left: Box::new(var(&name)),
right: Box::new(var(&name)),
Expand Down Expand Up @@ -462,7 +462,7 @@ fn p2p_weakening_linear_forbidden_affine_allowed() {
let expr = e(ExprKind::LetLin {
name: name.clone().into(),
ty: Some(Ty::Base(BaseTy::I32)),
value: Box::new(i32_lit(i as i32)),
value: Box::new(i32_lit(i)),
body: Box::new(unit()),
});

Expand All @@ -485,7 +485,7 @@ fn p2p_weakening_linear_forbidden_affine_allowed() {
let affine_expr = e(ExprKind::Let {
name: name.clone().into(),
ty: Some(Ty::Base(BaseTy::I32)),
value: Box::new(i32_lit(i as i32)),
value: Box::new(i32_lit(i)),
body: Box::new(unit()),
});
let mut affine = AffineChecker::new();
Expand All @@ -510,7 +510,7 @@ fn p2p_unified_api_consistent_with_direct_checkers() {
let good_expr = e(ExprKind::LetLin {
name: name.clone().into(),
ty: Some(Ty::Base(BaseTy::I32)),
value: Box::new(i32_lit(i as i32)),
value: Box::new(i32_lit(i)),
body: Box::new(var(&name)),
});

Expand Down
1 change: 1 addition & 0 deletions src/ephapax-cli/src/import_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ fn first_module_declaration(source: &str) -> Option<String> {
None
}

#[allow(clippy::too_many_arguments)] // recursive resolver: 8 params vs the 7 default threshold
fn visit(
logical: &str,
explicit_file: Option<&Path>,
Expand Down
6 changes: 4 additions & 2 deletions src/ephapax-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,9 @@ fn check_files(files: &[PathBuf], _mode_str: &str, verbose: bool) -> Result<(),
}
}

#[allow(clippy::too_many_arguments)] // CLI entry point: 8 options vs the 7 default threshold
fn compile_file(
path: &PathBuf,
path: &Path,
output: Option<PathBuf>,
opt_level: u8,
debug: bool,
Expand Down Expand Up @@ -570,10 +571,11 @@ fn compile_file(

/// Codegen + optional ownership verification + output write. Shared by
/// the multi-module and legacy single-file compile paths.
#[allow(clippy::too_many_arguments)] // CLI entry point: 8 options vs the 7 default threshold
fn finish_compile(
module: ephapax_syntax::Module,
filename: &str,
path: &PathBuf,
path: &Path,
output: Option<PathBuf>,
opt_level: u8,
debug: bool,
Expand Down
5 changes: 2 additions & 3 deletions src/ephapax-cli/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ fn assert_checks(source: &str) {

/// Helper: assert that source fails type-checking
fn assert_rejects(source: &str) {
match check(source) {
Ok(ty) => panic!("Expected type-check failure for `{source}`, got: {ty:?}"),
Err(_) => {}
if let Ok(ty) = check(source) {
panic!("Expected type-check failure for `{source}`, got: {ty:?}")
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/ephapax-desugar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ fn module_qualifier_of(base: &SurfaceExpr) -> Option<SmolStr> {
/// (`lib/math` → `math`, `Foo.Bar` → `Bar`, `Coproc` → `Coproc`). This is
/// the name a `M.member` qualifier must use.
fn last_segment(path: &str) -> SmolStr {
path.rsplit(|c| c == '/' || c == '.')
.next()
.unwrap_or(path)
.into()
path.rsplit(['/', '.']).next().unwrap_or(path).into()
}

/// Desugaring errors.
Expand Down Expand Up @@ -2014,7 +2011,7 @@ mod tests {
assert_eq!(params[0].0.as_str(), "title");
assert_eq!(*ret_ty, Ty::Base(BaseTy::I32));
} else {
panic!("expected ExternItem::Fn, got {:?}", &items[1]);
panic!("expected ExternItem::Fn, got {:?}", items[1]);
}
}
other => panic!("expected Decl::Extern, got {other:?}"),
Expand Down
7 changes: 7 additions & 0 deletions src/ephapax-interp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ pub enum RuntimeError {
}

/// Runtime values
//
// clippy::large_enum_variant — `Closure` is ~264 bytes against ~48 for the next
// largest variant. The fix is to box the closure payload, but that changes every
// construction and match site in the interpreter, so it is deliberately NOT bundled
// into the CI-revival change that first surfaced this lint. Tracked separately;
// remove this allow when the boxing lands.
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone)]
pub enum Value {
Unit,
Expand Down
7 changes: 6 additions & 1 deletion src/ephapax-lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ mod tests {
assert_eq!(lex("12345"), vec![TokenKind::Integer(12345)]);
}

// `3.14` here is a float literal under test, not an approximation of PI.
#[allow(clippy::approx_constant)]
#[test]
fn test_floats() {
assert_eq!(lex("3.14"), vec![TokenKind::Float(3.14)]);
Expand Down Expand Up @@ -785,6 +787,9 @@ mod tests {
mod property_tests {
use super::*;

/// Predicate over a token kind, used by the table-driven P2P tests.
type TokenPredicate = fn(&TokenKind) -> bool;

// -------------------------------------------------------------------------
// P2P: round-trip token spans
// -------------------------------------------------------------------------
Expand Down Expand Up @@ -891,7 +896,7 @@ mod property_tests {
/// exactly one content token of the Integer kind.
#[test]
fn p2p_integer_literals_tokenise_to_one_token() {
let inputs: Vec<(&str, fn(&TokenKind) -> bool)> = vec![
let inputs: Vec<(&str, TokenPredicate)> = vec![
("0", |t| matches!(t, TokenKind::Integer(_))),
("1", |t| matches!(t, TokenKind::Integer(_))),
("42", |t| matches!(t, TokenKind::Integer(_))),
Expand Down
8 changes: 2 additions & 6 deletions src/ephapax-lsp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,7 @@ impl Backend {
if let Some(module) = &state.module {
for d in &module.decls {
if let Decl::Fn {
name,
body,
params,
type_params: _,
..
name, body, params, ..
} = d
{
// Check if word matches a parameter
Expand Down Expand Up @@ -572,7 +568,7 @@ fn extract_declarations(module: &Module, _source: &str) -> Vec<DeclInfo> {
.unwrap_or_default()
),
params: Vec::new(),
return_type: ty.as_ref().map(|t| format_ty(t)),
return_type: ty.as_ref().map(format_ty),
}),
Decl::Extern { abi, items } => {
for item in items {
Expand Down
54 changes: 23 additions & 31 deletions src/ephapax-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,8 @@ fn parse_extern_item(pair: pest::iterators::Pair<Rule>) -> Result<ExternItem, Pa
}
}
}
Rule::ty => {
if ret_ty.is_none() {
ret_ty = Some(parse_type(sub)?);
}
Rule::ty if ret_ty.is_none() => {
ret_ty = Some(parse_type(sub)?);
}
_ => {}
}
Expand Down Expand Up @@ -772,8 +770,7 @@ fn parse_seq_expr_core(pair: pest::iterators::Pair<Rule>) -> Result<Expr, ParseE

// invariant: loop above ensures parsed is not empty before we enter this block
let last = parsed.pop().expect("invariant: parsed is not empty");
parsed.into_iter().rev().fold(Ok(last), |acc, expr| {
let acc = acc?;
parsed.into_iter().rev().try_fold(last, |acc, expr| {
let s = expr.span;
Ok(Expr::new(
ExprKind::Let {
Expand Down Expand Up @@ -1261,34 +1258,29 @@ fn parse_handle_expr(pair: pest::iterators::Pair<Rule>) -> Result<Expr, ParseErr
match item.as_rule() {
Rule::handler_param_list => {
for param_item in item.into_inner() {
match param_item.as_rule() {
Rule::handler_param => {
let hp_inner = param_item.into_inner().next();
if let Some(hp) = hp_inner {
match hp.as_rule() {
Rule::resume_param => {
// Check for mode
if let Some(mode_pair) = hp.into_inner().next()
{
resume_mode =
Some(match mode_pair.as_str() {
"once" => ResumeMode::Once,
"multi" => ResumeMode::Multi,
_ => ResumeMode::Once,
});
} else {
resume_mode = Some(ResumeMode::Once);
// default
}
}
Rule::identifier => {
params.push(parse_identifier(hp));
if param_item.as_rule() == Rule::handler_param {
let hp_inner = param_item.into_inner().next();
if let Some(hp) = hp_inner {
match hp.as_rule() {
Rule::resume_param => {
// Check for mode
if let Some(mode_pair) = hp.into_inner().next() {
resume_mode = Some(match mode_pair.as_str() {
"once" => ResumeMode::Once,
"multi" => ResumeMode::Multi,
_ => ResumeMode::Once,
});
} else {
resume_mode = Some(ResumeMode::Once);
// default
}
_ => {}
}
Rule::identifier => {
params.push(parse_identifier(hp));
}
_ => {}
}
}
_ => {}
}
}
}
Expand Down Expand Up @@ -2359,7 +2351,7 @@ mod tests {
assert_eq!(name.as_str(), "window_open");
assert_eq!(params.len(), 2);
} else {
panic!("expected ExternItem::Fn, got {:?}", &items[1]);
panic!("expected ExternItem::Fn, got {:?}", items[1]);
}
}
other => panic!("expected Decl::Extern, got {other:?}"),
Expand Down
9 changes: 3 additions & 6 deletions src/ephapax-parser/src/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,8 @@ fn parse_extern_item(pair: pest::iterators::Pair<Rule>) -> Result<SurfaceExternI
}
}
}
Rule::ty => {
if ret_ty.is_none() {
ret_ty = Some(parse_type(sub)?);
}
Rule::ty if ret_ty.is_none() => {
ret_ty = Some(parse_type(sub)?);
}
_ => {}
}
Expand Down Expand Up @@ -507,8 +505,7 @@ fn parse_seq_expr(pair: pest::iterators::Pair<Rule>) -> Result<SurfaceExpr, Pars
// let _ = e1 in (let _ = e2 in (... eN))
// invariant: loop above ensures parsed is not empty before we enter this block
let last = parsed.pop().expect("invariant: parsed is not empty");
parsed.into_iter().rev().fold(Ok(last), |acc, expr| {
let acc = acc?;
parsed.into_iter().rev().try_fold(last, |acc, expr| {
let s = expr.span;
Ok(SurfaceExpr::new(
SurfaceExprKind::Let {
Expand Down
2 changes: 1 addition & 1 deletion src/ephapax-query/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ mod tests {
let _ = db.wasm("m");
let n = db.recompute_count();

db.set_source_text("m", &format!("// leading comment\n{ADD}"));
db.set_source_text("m", format!("// leading comment\n{ADD}"));
let _ = db.wasm("m");
let delta = db.recompute_count() - n;
assert!(
Expand Down
7 changes: 2 additions & 5 deletions src/ephapax-runtime/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,11 @@ pub unsafe extern "C" fn __ephapax_string_list_get(handle: ListHandle, idx: i32)

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_list_new() {
unsafe {
// This test needs proper WASM memory simulation
// Just verify function signature is correct
}
// This test needs proper WASM memory simulation.
// Placeholder: verifies only that the function signature compiles.
}

#[test]
Expand Down
11 changes: 3 additions & 8 deletions src/ephapax-syntax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,21 +711,16 @@ pub enum ExternItem {

/// Helper for serde skip_serializing_if.
/// Visibility of a declaration.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum Visibility {
/// Accessible from other modules.
Public,
/// Only accessible within this module (default).
#[default]
Private,
}

impl Default for Visibility {
fn default() -> Self {
Visibility::Private
}
}

/// Helper for serde skip_serializing_if.
fn is_private(v: &Visibility) -> bool {
*v == Visibility::Private
Expand Down Expand Up @@ -797,7 +792,7 @@ mod tests {
BaseTy::F64,
] {
assert!(
!Ty::Base(base.clone()).is_linear(),
!Ty::Base(base).is_linear(),
"Coq bridge: TBase {base:?} should be NOT linear"
);
}
Expand Down
14 changes: 2 additions & 12 deletions src/ephapax-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,6 @@ impl Codegen {
name,
params,
ret_ty,
type_params: _,
..
} => {
// Build WASM type for this function
Expand Down Expand Up @@ -1098,11 +1097,7 @@ impl Codegen {
for decl in &ast.decls {
match decl {
Decl::Fn {
name,
params,
body,
type_params: _,
..
name, params, body, ..
} => {
let info = self.user_fns.get(name.as_str()).cloned().ok_or_else(|| {
CodegenError(format!("BUG: function `{}` not collected", name))
Expand Down Expand Up @@ -1271,12 +1266,7 @@ impl Codegen {

// Export all user functions by name
for decl in &ast.decls {
if let Decl::Fn {
name,
type_params: _,
..
} = decl
{
if let Decl::Fn { name, .. } = decl {
if let Some(info) = self.user_fns.get(name.as_str()) {
exports.export(name.as_str(), ExportKind::Func, info.wasm_fn_idx);
}
Expand Down
4 changes: 2 additions & 2 deletions src/ephapax-wasm/src/ownership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ mod tests {
#[test]
fn single_linear_param_roundtrip() {
let e = entry(7, vec![OwnershipKind::Linear], OwnershipKind::Unrestricted);
let bytes = build_ownership_section_payload(&[e.clone()]);
let bytes = build_ownership_section_payload(std::slice::from_ref(&e));
assert_eq!(parse_ownership_section_payload(&bytes), vec![e]);
}

Expand All @@ -201,7 +201,7 @@ mod tests {
],
OwnershipKind::Linear,
);
let bytes = build_ownership_section_payload(&[e.clone()]);
let bytes = build_ownership_section_payload(std::slice::from_ref(&e));
assert_eq!(parse_ownership_section_payload(&bytes), vec![e]);
}

Expand Down
Loading