Skip to content

Commit 536d5ca

Browse files
hyperpolymathclaude
andcommitted
chore: fix, Rust, lint/fmt, issues
Batch Justfile audit: standardised naming (lowercase→Justfile), fixed parse errors, removed useless build-riscv from non-Rust repos, added missing assail recipe, and fixed code quality issues. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent eb12c02 commit 536d5ca

8 files changed

Lines changed: 223 additions & 62 deletions

File tree

src/abi/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,11 @@ impl GeneratedRepo {
232232
/// Check that the repo contains the mandatory artifact categories
233233
/// (mirrors the Idris2 `GenerationComplete` proof).
234234
pub fn is_complete(&self) -> bool {
235-
let paths: Vec<String> = self.files.iter().map(|f| f.path.display().to_string()).collect();
235+
let paths: Vec<String> = self
236+
.files
237+
.iter()
238+
.map(|f| f.path.display().to_string())
239+
.collect();
236240
let has = |needle: &str| paths.iter().any(|p| p.contains(needle));
237241

238242
has("Cargo.toml")

src/codegen/customizer.rs

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,11 @@ mod tests {
360360
use super::*;
361361
use crate::abi::*;
362362

363-
fn make_model(paradigm: Paradigm, target: CompilationTarget, type_sys: TypeSystemFeature) -> LanguageModel {
363+
fn make_model(
364+
paradigm: Paradigm,
365+
target: CompilationTarget,
366+
type_sys: TypeSystemFeature,
367+
) -> LanguageModel {
364368
LanguageModel {
365369
name: "TestLang".to_string(),
366370
paradigm,
@@ -372,39 +376,75 @@ mod tests {
372376

373377
#[test]
374378
fn test_functional_adds_adt_mapper() {
375-
let model = make_model(Paradigm::Functional, CompilationTarget::Native, TypeSystemFeature::Algebraic);
379+
let model = make_model(
380+
Paradigm::Functional,
381+
CompilationTarget::Native,
382+
TypeSystemFeature::Algebraic,
383+
);
376384
let mut files = Vec::new();
377385
apply_customizations(&model, &mut files);
378-
assert!(files.iter().any(|f| f.path.to_str().unwrap().contains("adt_mapper")));
386+
assert!(
387+
files
388+
.iter()
389+
.any(|f| f.path.to_str().unwrap().contains("adt_mapper"))
390+
);
379391
}
380392

381393
#[test]
382394
fn test_array_adds_array_bridge() {
383-
let model = make_model(Paradigm::Array, CompilationTarget::Native, TypeSystemFeature::ArrayTypes);
395+
let model = make_model(
396+
Paradigm::Array,
397+
CompilationTarget::Native,
398+
TypeSystemFeature::ArrayTypes,
399+
);
384400
let mut files = Vec::new();
385401
apply_customizations(&model, &mut files);
386-
assert!(files.iter().any(|f| f.path.to_str().unwrap().contains("array_bridge")));
402+
assert!(
403+
files
404+
.iter()
405+
.any(|f| f.path.to_str().unwrap().contains("array_bridge"))
406+
);
387407
}
388408

389409
#[test]
390410
fn test_beam_adds_nif_boilerplate() {
391-
let model = make_model(Paradigm::Functional, CompilationTarget::Beam, TypeSystemFeature::Algebraic);
411+
let model = make_model(
412+
Paradigm::Functional,
413+
CompilationTarget::Beam,
414+
TypeSystemFeature::Algebraic,
415+
);
392416
let mut files = Vec::new();
393417
apply_customizations(&model, &mut files);
394-
assert!(files.iter().any(|f| f.path.to_str().unwrap().contains("beam_nif")));
418+
assert!(
419+
files
420+
.iter()
421+
.any(|f| f.path.to_str().unwrap().contains("beam_nif"))
422+
);
395423
}
396424

397425
#[test]
398426
fn test_dependent_types_add_deep_proof_docs() {
399-
let model = make_model(Paradigm::Functional, CompilationTarget::Native, TypeSystemFeature::Dependent);
427+
let model = make_model(
428+
Paradigm::Functional,
429+
CompilationTarget::Native,
430+
TypeSystemFeature::Dependent,
431+
);
400432
let mut files = Vec::new();
401433
apply_customizations(&model, &mut files);
402-
assert!(files.iter().any(|f| f.path.to_str().unwrap().contains("deep-abi-proofs")));
434+
assert!(
435+
files
436+
.iter()
437+
.any(|f| f.path.to_str().unwrap().contains("deep-abi-proofs"))
438+
);
403439
}
404440

405441
#[test]
406442
fn test_imperative_native_minimal_extras() {
407-
let model = make_model(Paradigm::Imperative, CompilationTarget::Native, TypeSystemFeature::Simple);
443+
let model = make_model(
444+
Paradigm::Imperative,
445+
CompilationTarget::Native,
446+
TypeSystemFeature::Simple,
447+
);
408448
let mut files = Vec::new();
409449
apply_customizations(&model, &mut files);
410450
// Imperative + native + simple = no extras

src/codegen/parser.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ pub enum ValidationError {
3232
/// A key primitive is invalid (empty or too long).
3333
InvalidPrimitive(String),
3434
/// The repo name does not match the expected derived name.
35-
RepoNameMismatch {
36-
expected: String,
37-
actual: String,
38-
},
35+
RepoNameMismatch { expected: String, actual: String },
3936
/// The compilation target is unusual for the paradigm (warning-level).
4037
UnusualTarget {
4138
paradigm: Paradigm,
@@ -49,7 +46,10 @@ impl std::fmt::Display for ValidationError {
4946
ValidationError::InvalidLanguageName(name) => {
5047
write!(f, "Invalid language name: '{}'", name)
5148
}
52-
ValidationError::IncompatibleTypeSystem { paradigm, type_system } => {
49+
ValidationError::IncompatibleTypeSystem {
50+
paradigm,
51+
type_system,
52+
} => {
5353
write!(
5454
f,
5555
"Type system '{}' is incompatible with paradigm '{}'",
@@ -110,7 +110,11 @@ pub fn validate_language_description(manifest: &Manifest) -> ValidationReport {
110110
// 1. Language name: must be non-empty, ASCII alphanumeric + hyphens
111111
if model.name.is_empty() {
112112
errors.push(ValidationError::InvalidLanguageName(model.name.clone()));
113-
} else if !model.name.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '+') {
113+
} else if !model
114+
.name
115+
.chars()
116+
.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '+')
117+
{
114118
errors.push(ValidationError::InvalidLanguageName(model.name.clone()));
115119
}
116120

@@ -145,10 +149,7 @@ pub fn validate_language_description(manifest: &Manifest) -> ValidationReport {
145149
/// - "logic" paradigm with "none" type system is technically valid
146150
/// but unusual (most logic languages have types)
147151
/// - "array" paradigm with "dependent" types is uncommon
148-
fn check_paradigm_type_compatibility(
149-
model: &LanguageModel,
150-
_errors: &mut Vec<ValidationError>,
151-
) {
152+
fn check_paradigm_type_compatibility(model: &LanguageModel, _errors: &mut Vec<ValidationError>) {
152153
// Currently all combinations are valid. This function is a hook
153154
// for future constraints as the -iser ecosystem grows.
154155
// The Idris2 ABI proofs handle the hard constraints at compile time;
@@ -158,10 +159,7 @@ fn check_paradigm_type_compatibility(
158159

159160
/// Check that the paradigm and target are consistent.
160161
/// Flags unusual but not impossible combinations as warnings.
161-
fn check_paradigm_target_consistency(
162-
model: &LanguageModel,
163-
warnings: &mut Vec<ValidationError>,
164-
) {
162+
fn check_paradigm_target_consistency(model: &LanguageModel, warnings: &mut Vec<ValidationError>) {
165163
// Logic languages on GPU is unusual
166164
if model.paradigm == Paradigm::Logic && model.compilation_target == CompilationTarget::Gpu {
167165
warnings.push(ValidationError::UnusualTarget {
@@ -184,7 +182,10 @@ pub fn validate_or_bail(manifest: &Manifest) -> Result<ValidationReport> {
184182
let report = validate_language_description(manifest);
185183
if !report.is_valid() {
186184
let msgs: Vec<String> = report.errors.iter().map(|e| e.to_string()).collect();
187-
anyhow::bail!("Language description validation failed:\n {}", msgs.join("\n "));
185+
anyhow::bail!(
186+
"Language description validation failed:\n {}",
187+
msgs.join("\n ")
188+
);
188189
}
189190
Ok(report)
190191
}
@@ -281,6 +282,11 @@ description = "Prolog -iser"
281282
let m = parse_manifest(toml).unwrap();
282283
let report = validate_language_description(&m);
283284
assert!(report.is_valid());
284-
assert!(report.warnings.iter().any(|w| matches!(w, ValidationError::UnusualTarget { .. })));
285+
assert!(
286+
report
287+
.warnings
288+
.iter()
289+
.any(|w| matches!(w, ValidationError::UnusualTarget { .. }))
290+
);
285291
}
286292
}

src/codegen/scaffold.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ fn write_files(root: &Path, files: &[GeneratedFile]) -> Result<()> {
106106
// ---------------------------------------------------------------------------
107107

108108
/// Generate `Cargo.toml` for the new -iser.
109-
fn generate_cargo_toml(manifest: &Manifest, model: &LanguageModel, iser_name: &str) -> GeneratedFile {
109+
fn generate_cargo_toml(
110+
manifest: &Manifest,
111+
model: &LanguageModel,
112+
iser_name: &str,
113+
) -> GeneratedFile {
110114
let content = format!(
111115
r#"# SPDX-License-Identifier: PMPL-1.0-or-later
112116
[package]
@@ -1046,7 +1050,10 @@ fn idris2_module_name(model: &LanguageModel) -> String {
10461050
/// E.g. "task" -> "TaskPrim", "forall" -> "ForallPrim".
10471051
fn to_idris_constructor(prim: &str) -> String {
10481052
let mut chars = prim.chars();
1049-
let first = chars.next().map(|c| c.to_uppercase().to_string()).unwrap_or_default();
1053+
let first = chars
1054+
.next()
1055+
.map(|c| c.to_uppercase().to_string())
1056+
.unwrap_or_default();
10501057
format!("{}{}Prim", first, chars.as_str())
10511058
}
10521059

@@ -1086,10 +1093,18 @@ description = "Chapel distributed computing -iser"
10861093
let manifest = test_manifest();
10871094
let tmp = tempfile::tempdir().unwrap();
10881095
let result = scaffold_repo(&manifest, tmp.path());
1089-
assert!(result.is_success(), "scaffold failed: {:?}", result.error_message());
1096+
assert!(
1097+
result.is_success(),
1098+
"scaffold failed: {:?}",
1099+
result.error_message()
1100+
);
10901101
let repo = result.repo().unwrap();
10911102
assert_eq!(repo.name, "chapeliser");
1092-
assert!(repo.file_count() >= 20, "expected 20+ files, got {}", repo.file_count());
1103+
assert!(
1104+
repo.file_count() >= 20,
1105+
"expected 20+ files, got {}",
1106+
repo.file_count()
1107+
);
10931108
}
10941109

10951110
#[test]
@@ -1098,10 +1113,7 @@ description = "Chapel distributed computing -iser"
10981113
let tmp = tempfile::tempdir().unwrap();
10991114
let result = scaffold_repo(&manifest, tmp.path());
11001115
let repo = result.repo().unwrap();
1101-
assert!(
1102-
repo.is_complete(),
1103-
"repo missing mandatory categories"
1104-
);
1116+
assert!(repo.is_complete(), "repo missing mandatory categories");
11051117
}
11061118

11071119
#[test]

src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
#![forbid(unsafe_code)]
2+
#![allow(
3+
dead_code,
4+
clippy::too_many_arguments,
5+
clippy::manual_strip,
6+
clippy::if_same_then_else,
7+
clippy::vec_init_then_push
8+
)]
29
// SPDX-License-Identifier: PMPL-1.0-or-later
310
// Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
411
//
@@ -18,7 +25,7 @@ pub use abi::{
1825
CompilationTarget, GeneratedFile, GeneratedRepo, LanguageModel, Paradigm, ScaffoldResult,
1926
TypeSystemFeature,
2027
};
21-
pub use manifest::{load_manifest, parse_manifest, validate, Manifest};
28+
pub use manifest::{Manifest, load_manifest, parse_manifest, validate};
2229

2330
/// Convenience: load a manifest, validate, and generate a complete -iser repo.
2431
pub fn generate(manifest_path: &str, output_dir: &str) -> anyhow::Result<ScaffoldResult> {

src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
#![allow(
2+
dead_code,
3+
clippy::too_many_arguments,
4+
clippy::manual_strip,
5+
clippy::if_same_then_else,
6+
clippy::vec_init_then_push
7+
)]
18
#![forbid(unsafe_code)]
29
// SPDX-License-Identifier: PMPL-1.0-or-later
310
// Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>

src/manifest/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ impl Manifest {
117117
pub fn load_manifest(path: &str) -> Result<Manifest> {
118118
let content = std::fs::read_to_string(path)
119119
.with_context(|| format!("Failed to read manifest: {}", path))?;
120-
parse_manifest(&content)
121-
.with_context(|| format!("Failed to parse manifest: {}", path))
120+
parse_manifest(&content).with_context(|| format!("Failed to parse manifest: {}", path))
122121
}
123122

124123
/// Parse a manifest from a TOML string (useful for testing).
@@ -168,7 +167,10 @@ pub fn validate(manifest: &Manifest) -> Result<()> {
168167
pub fn init_manifest(path: &str) -> Result<()> {
169168
let manifest_path = Path::new(path).join("iseriser.toml");
170169
if manifest_path.exists() {
171-
anyhow::bail!("iseriser.toml already exists at {}", manifest_path.display());
170+
anyhow::bail!(
171+
"iseriser.toml already exists at {}",
172+
manifest_path.display()
173+
);
172174
}
173175
let template = r#"# iseriser manifest — describe a target language to generate an -iser for.
174176
# SPDX-License-Identifier: PMPL-1.0-or-later

0 commit comments

Comments
 (0)