From e5534d1532bb5402a1ac981323e9685fac3a2658 Mon Sep 17 00:00:00 2001 From: Brummel Date: Tue, 2 Jun 2026 02:14:15 +0200 Subject: [PATCH] refactor: clear clippy code lints across the workspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Machine-applicable clippy fixes plus three by-hand cleanups; all semantics-preserving (full workspace test suite green). Auto-applied (cargo clippy --fix): - dropped `.clone()` on the Copy type ParamMode (ret_mode/param_mode) - map_or(false, p) -> is_some_and(p) - removed redundant closures and an explicit .into_iter() - useless format!, a needless deref, an as_bytes-after-slice By hand: - ailang-codegen: named the loop-frame tuple types (LoopFrame / LoopBinderSlot) instead of the bare nested Vec<(String, Vec<(String, String, String, Type)>)>, clearing the type-complexity lint and documenting what each slot holds. - ailang-check: collapsed the two identical pass-through arms of the Type-Con qualifier (already-dotted / primitive) into one `||` guard. - ailang-core: converted a stale `///` block (it described a test that was relocated, documenting nothing) back to a plain `//` comment. Remaining clippy output is 16 markdown list-indentation nits in prose doc comments — doc formatting, not code, left for a docs pass. --- crates/ail/tests/ord_int_intercept_ir_pin.rs | 2 +- crates/ailang-check/src/lib.rs | 19 +++++++++---------- crates/ailang-check/src/linearity.rs | 6 +++--- crates/ailang-check/src/lower_to_mir.rs | 4 ++-- crates/ailang-check/src/mono.rs | 2 +- crates/ailang-codegen/src/drop.rs | 2 +- crates/ailang-codegen/src/lib.rs | 11 ++++++++++- crates/ailang-core/src/desugar.rs | 2 +- crates/ailang-core/src/workspace.rs | 11 +++++------ crates/ailang-core/tests/design_index_pin.rs | 4 ++-- 10 files changed, 35 insertions(+), 28 deletions(-) diff --git a/crates/ail/tests/ord_int_intercept_ir_pin.rs b/crates/ail/tests/ord_int_intercept_ir_pin.rs index ae87034..1c5be8e 100644 --- a/crates/ail/tests/ord_int_intercept_ir_pin.rs +++ b/crates/ail/tests/ord_int_intercept_ir_pin.rs @@ -47,7 +47,7 @@ fn emit_ir(fixture: &str) -> String { /// call sites (which also mention `@ail_prelude_(`) don't /// match. fn extract_fn_body(ir: &str, sym: &str) -> (String, String) { - let needle = format!("define "); + let needle = "define ".to_string(); let mut cursor = 0; let sym_marker = format!("@ail_prelude_{sym}("); loop { diff --git a/crates/ailang-check/src/lib.rs b/crates/ailang-check/src/lib.rs index 23155b2..fe3a1dd 100644 --- a/crates/ailang-check/src/lib.rs +++ b/crates/ailang-check/src/lib.rs @@ -128,7 +128,7 @@ impl Subst { ret: Box::new(self.apply(ret)), effects: effects.clone(), param_modes: param_modes.clone(), - ret_mode: ret_mode.clone(), + ret_mode: *ret_mode, }, Type::Forall { vars, constraints, body } => Type::Forall { vars: vars.clone(), @@ -4727,7 +4727,7 @@ fn strip_own_module_qual(t: &Type, module: &str) -> Type { params: params.iter().map(|p| strip_own_module_qual(p, module)).collect(), param_modes: param_modes.clone(), ret: Box::new(strip_own_module_qual(ret, module)), - ret_mode: ret_mode.clone(), + ret_mode: *ret_mode, effects: effects.clone(), }, Type::Var { .. } => t.clone(), @@ -4756,13 +4756,12 @@ fn strip_own_module_qual(t: &Type, module: &str) -> Type { fn rewrite_type_cons(t: &Type, rewrite_bare: &dyn Fn(&str) -> Option) -> Type { match t { Type::Con { name, args } => { - // The first two guards both pass the name through unchanged - // but express semantically distinct reasons (already - // qualified; primitive needs no qualification). Only a bare, - // non-primitive name is offered to `rewrite_bare`. - let qualified_name = if name.contains('.') { - name.clone() - } else if ailang_core::primitives::is_primitive_name(name) { + // Pass a name through unchanged if it is already qualified + // (contains a dot) or primitive — neither needs qualifying. + // Only a bare, non-primitive name is offered to `rewrite_bare`. + let qualified_name = if name.contains('.') + || ailang_core::primitives::is_primitive_name(name) + { name.clone() } else { rewrite_bare(name).unwrap_or_else(|| name.clone()) @@ -4784,7 +4783,7 @@ fn rewrite_type_cons(t: &Type, rewrite_bare: &dyn Fn(&str) -> Option) -> .collect(), param_modes: param_modes.clone(), ret: Box::new(rewrite_type_cons(ret, rewrite_bare)), - ret_mode: ret_mode.clone(), + ret_mode: *ret_mode, effects: effects.clone(), }, Type::Forall { vars, constraints, body } => Type::Forall { diff --git a/crates/ailang-check/src/linearity.rs b/crates/ailang-check/src/linearity.rs index 932a154..e642637 100644 --- a/crates/ailang-check/src/linearity.rs +++ b/crates/ailang-check/src/linearity.rs @@ -405,7 +405,7 @@ fn check_fn( ParamMode::Own => 0, }, is_value: param_tys.get(i).map(type_is_value).unwrap_or(false), - fn_param_modes: param_tys.get(i).and_then(|t| fn_modes_of(t)), + fn_param_modes: param_tys.get(i).and_then(fn_modes_of), }; checker.binders.insert(name.clone(), initial); } @@ -582,7 +582,7 @@ impl<'a> Checker<'a> { .let_binder_types .get(&(self.def_name.to_string(), name.clone())); let is_value = teed.map(type_is_value).unwrap_or(false); - let fn_param_modes = teed.and_then(|t| fn_modes_of(t)); + let fn_param_modes = teed.and_then(fn_modes_of); self.with_binder( name, BinderState { is_value, fn_param_modes, ..BinderState::default() }, @@ -684,7 +684,7 @@ impl<'a> Checker<'a> { saved_for_params.insert(p.clone(), self.binders.remove(p)); let st = BinderState { is_value: param_tys.get(i).map(type_is_value).unwrap_or(false), - fn_param_modes: param_tys.get(i).and_then(|t| fn_modes_of(t)), + fn_param_modes: param_tys.get(i).and_then(fn_modes_of), ..BinderState::default() }; self.binders.insert(p.clone(), st); diff --git a/crates/ailang-check/src/lower_to_mir.rs b/crates/ailang-check/src/lower_to_mir.rs index 72f653c..fd11951 100644 --- a/crates/ailang-check/src/lower_to_mir.rs +++ b/crates/ailang-check/src/lower_to_mir.rs @@ -90,7 +90,7 @@ fn wildcard_residual_metavars(t: &Type) -> Type { params: params.iter().map(wildcard_residual_metavars).collect(), param_modes: param_modes.clone(), ret: Box::new(wildcard_residual_metavars(ret)), - ret_mode: ret_mode.clone(), + ret_mode: *ret_mode, effects: effects.clone(), }, Type::Forall { vars, constraints, body } => Type::Forall { @@ -486,7 +486,7 @@ fn lower_term(ctx: &mut Ctx, t: &Term) -> Result { .enumerate() .map(|(i, a)| { let mut m = lower_term(ctx, a)?; - if binder_tys.get(i).map_or(false, is_str_ty) { + if binder_tys.get(i).is_some_and(is_str_ty) { if let MTerm::Str { rep, .. } = &mut m { *rep = StrRep::Heap; } diff --git a/crates/ailang-check/src/mono.rs b/crates/ailang-check/src/mono.rs index 2e6faff..45e15ab 100644 --- a/crates/ailang-check/src/mono.rs +++ b/crates/ailang-check/src/mono.rs @@ -1122,7 +1122,7 @@ fn localize_own_types(t: &Type, defining_module: &str, own_type_names: &BTreeSet ret: Box::new(localize_own_types(ret, defining_module, own_type_names)), effects: effects.clone(), param_modes: param_modes.clone(), - ret_mode: ret_mode.clone(), + ret_mode: *ret_mode, }, Type::Forall { vars, constraints, body } => Type::Forall { vars: vars.clone(), diff --git a/crates/ailang-codegen/src/drop.rs b/crates/ailang-codegen/src/drop.rs index 4c3b2f8..7cd31e6 100644 --- a/crates/ailang-codegen/src/drop.rs +++ b/crates/ailang-codegen/src/drop.rs @@ -1005,7 +1005,7 @@ impl<'a> Emitter<'a> { (vars, Type::Con { args, .. }) if !vars.is_empty() && vars.len() == args.len() => { - vars.iter().cloned().zip(args.into_iter()).collect() + vars.iter().cloned().zip(args).collect() } _ => BTreeMap::new(), }; diff --git a/crates/ailang-codegen/src/lib.rs b/crates/ailang-codegen/src/lib.rs index e193daf..40e6a8c 100644 --- a/crates/ailang-codegen/src/lib.rs +++ b/crates/ailang-codegen/src/lib.rs @@ -741,6 +741,15 @@ fn main_is_void(t: &Type) -> bool { } } +/// One loop binder's storage on the recur stack: `(binder name, its +/// alloca SSA, the LLVM type string, the AILang type)`. +type LoopBinderSlot = (String, String, String, Type); + +/// A loop frame: `(loop header block label, the binder slots active in +/// that loop)`. Pushed on entry to a `Term::Loop`, popped on exit, and +/// read by `Term::Recur` to store back into the right allocas. +type LoopFrame = (String, Vec); + struct Emitter<'a> { module: &'a Module, /// Typed fn bodies for this module (the post-mono `MTerm` per @@ -917,7 +926,7 @@ struct Emitter<'a> { /// it. Saved/reset/restored at the lambda-lowering boundary /// alongside `binder_allocas` (a `recur` cannot cross a lambda /// boundary). - loop_frames: Vec<(String, Vec<(String, String, String, Type)>)>, + loop_frames: Vec, /// Side buffer for `alloca` instructions emitted during body /// lowering but hoisted to the fn's entry block. Flushed once /// into `self.body` at `entry_block_end_marker` after diff --git a/crates/ailang-core/src/desugar.rs b/crates/ailang-core/src/desugar.rs index 2e9c75b..3bb36a7 100644 --- a/crates/ailang-core/src/desugar.rs +++ b/crates/ailang-core/src/desugar.rs @@ -826,7 +826,7 @@ impl Desugarer { free_vars_in_term(&desugared_body, &local_bound, &mut frees); let captures: Vec = frees .iter() - .filter(|f| scope.contains_key(*f)) + .filter(|f| scope.contains_key(f)) .cloned() .collect(); diff --git a/crates/ailang-core/src/workspace.rs b/crates/ailang-core/src/workspace.rs index 4d22e51..2329cc1 100644 --- a/crates/ailang-core/src/workspace.rs +++ b/crates/ailang-core/src/workspace.rs @@ -2387,12 +2387,11 @@ mod tests { .expect("qualified Constraint.class in ClassDef-method Forall is the canonical form post-canonical-class-form"); } - /// on-disk fixture for `BareCrossModuleTypeRef`. Bare - /// `Ordering` Term::Ctor with no imports; the validator catches it - /// after prelude injection (so the candidate list contains - /// `prelude.Ordering`). - // `ct1_fixture_bare_xmod_rejected` relocated to - // `crates/ailang-core/tests/workspace_pin.rs` in iter pd.2. + // on-disk fixture for `BareCrossModuleTypeRef`. Bare `Ordering` + // Term::Ctor with no imports; the validator catches it after + // prelude injection (so the candidate list contains + // `prelude.Ordering`). `ct1_fixture_bare_xmod_rejected` relocated + // to `crates/ailang-core/tests/workspace_pin.rs` in iter pd.2. /// on-disk fixture for `BadCrossModuleTypeRef`. Qualified /// `Mystery.Type` with `Mystery` not a known module. diff --git a/crates/ailang-core/tests/design_index_pin.rs b/crates/ailang-core/tests/design_index_pin.rs index b6b6bdd..3a8a282 100644 --- a/crates/ailang-core/tests/design_index_pin.rs +++ b/crates/ailang-core/tests/design_index_pin.rs @@ -216,7 +216,7 @@ fn contracts_carry_no_decision_record_prose() { let mut from = 0; while let Some(i) = line[from..].find(kw) { let p = from + i + kw.len(); - if line[p..].chars().next().map_or(false, |c| c.is_ascii_digit()) { + if line[p..].chars().next().is_some_and(|c| c.is_ascii_digit()) { return true; } from = p; @@ -230,7 +230,7 @@ fn contracts_carry_no_decision_record_prose() { if line.contains("21.g") { return Some("21.g"); } if let Some(s) = line.find(" sketch") { let pre = line[..s].as_bytes(); - if pre.last().map_or(false, u8::is_ascii_alphanumeric) + if pre.last().is_some_and(u8::is_ascii_alphanumeric) && pre.iter().rev() .take_while(|c| c.is_ascii_alphanumeric()) .any(u8::is_ascii_digit)