From db03ae8b70429dbb32446d0bfc5a0ab5c2a4060d Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 9 Dec 2025 13:25:10 +0100 Subject: [PATCH 1/8] Keep overflow-checks enabled in release build and use panic=abort Keeping overflow-checks enabled in release does not measurably impact performance so there is no reason to risk hidden overflows by disabling them. Also switch to panic=abort as we do not want unwinding to happen. --- Cargo.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 47c8a06..61f4620 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,13 @@ cfg-if = "1.0.0" [dev-dependencies] insta = { version = "1.41.1", features = ["yaml"] } +[profile.dev] +panic = "abort" + +[profile.release] +overflow-checks = true +panic = "abort" + [profile.test.package.insta] opt-level = 3 From 6582ddfd25b43ec30b676023e70ee45e8b5419fa Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 9 Dec 2025 13:29:02 +0100 Subject: [PATCH 2/8] Update to Rust edition 2024 --- Cargo.toml | 2 +- src/svd/restriction.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 61f4620..b4610e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://github.com/Rahix/atdf2svd" repository = "https://github.com/Rahix/atdf2svd" keywords = ["atdf", "svd", "avr", "svd2rust"] categories = ["command-line-utilities", "embedded"] -edition = "2018" +edition = "2024" exclude = [ "tests/", diff --git a/src/svd/restriction.rs b/src/svd/restriction.rs index 8eea1a4..defda24 100644 --- a/src/svd/restriction.rs +++ b/src/svd/restriction.rs @@ -27,13 +27,13 @@ pub fn generate( }, vec![], ), - chip::ValueRestriction::Range(ref lo, ref hi) => ( + chip::ValueRestriction::Range(lo, hi) => ( Some(svd_rs::WriteConstraint::Range( svd_rs::WriteConstraintRange { min: *lo, max: *hi }, )), vec![], ), - chip::ValueRestriction::Enumerated(ref v) => { + chip::ValueRestriction::Enumerated(v) => { let mut values = v.values().collect::>(); values.sort_by(|a, b| a.value.cmp(&b.value)); From 58a987f83460e52a9614328f8fbf184135a71c9f Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 9 Dec 2025 13:32:00 +0100 Subject: [PATCH 3/8] Fix undetected partial writes into the SVD file `.write()` may only perform a partial write and then returns the number of bytes written. Use `.write_all()` instead which blocks until everything was written. --- src/svd/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/svd/mod.rs b/src/svd/mod.rs index 8fb6733..de03bde 100644 --- a/src/svd/mod.rs +++ b/src/svd/mod.rs @@ -8,7 +8,7 @@ pub mod restriction; pub fn generate(c: &crate::chip::Chip, mut w: W) -> crate::Result<()> { let device = chip::generate(c)?; let svd_xml = svd_encoder::encode(&device)?; - w.write(svd_xml.as_bytes())?; + w.write_all(svd_xml.as_bytes())?; Ok(()) } From 59034ba1d9adb5365be28dd6a9fdd483d66cad50 Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 9 Dec 2025 13:37:21 +0100 Subject: [PATCH 4/8] Fix all clippy lints --- src/atdf/chip.rs | 4 ++-- src/atdf/patch.rs | 2 +- src/error.rs | 2 +- src/lib.rs | 4 ++-- src/svd/peripheral.rs | 6 ++---- src/util.rs | 1 + 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/atdf/chip.rs b/src/atdf/chip.rs index 593daba..6c60a85 100644 --- a/src/atdf/chip.rs +++ b/src/atdf/chip.rs @@ -51,8 +51,8 @@ pub fn parse(el: &xmltree::Element) -> crate::Result { // Map interrupts from to let interrupts = interrupts - .iter() - .map(|(_, int)| (int.name.clone(), int.clone())) + .values() + .map(|int| (int.name.clone(), int.clone())) .collect(); Ok(chip::Chip { diff --git a/src/atdf/patch.rs b/src/atdf/patch.rs index bb218eb..bab415b 100644 --- a/src/atdf/patch.rs +++ b/src/atdf/patch.rs @@ -20,7 +20,7 @@ pub fn signals_to_port_fields(chip: &mut chip::Chip, tree: &xmltree::Element) -> .values_mut() .filter(|p| p.name.starts_with("PORT") && p.name.len() == 5) { - let name = port.name.chars().rev().next().unwrap(); + let name = port.name.chars().next_back().unwrap(); let pins: Vec<_> = port_module .first_child_by_attr(Some("instance"), "name", &port.name)? diff --git a/src/error.rs b/src/error.rs index 9ecfb5e..1fc6e7c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,7 @@ pub trait DisplayError { fn format(&self, w: &mut dyn std::io::Write) -> std::io::Result<()>; - fn into_panic(&self) -> ! { + fn to_panic(&self) -> ! { let mut message: Vec = "Error: ".into(); self.format(&mut message).unwrap(); panic!("{}", String::from_utf8_lossy(&message)); diff --git a/src/lib.rs b/src/lib.rs index e2545e7..334cccc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,8 +87,8 @@ pub fn run(args: Atdf2SvdOptions) { pub fn run_test(atdf: &mut dyn std::io::Read, auto_patches: Vec<&str>) -> String { let patches = HashSet::from_iter(auto_patches.iter().map(|s| s.to_string())); - let chip = atdf::parse(atdf, &patches).unwrap_or_else(|e| e.into_panic()); + let chip = atdf::parse(atdf, &patches).unwrap_or_else(|e| e.to_panic()); let mut output = Vec::new(); - svd::generate(&chip, &mut output).unwrap_or_else(|e| e.into_panic()); + svd::generate(&chip, &mut output).unwrap_or_else(|e| e.to_panic()); String::from_utf8(output).unwrap() } diff --git a/src/svd/peripheral.rs b/src/svd/peripheral.rs index 241c4f5..953d54c 100644 --- a/src/svd/peripheral.rs +++ b/src/svd/peripheral.rs @@ -7,10 +7,8 @@ fn create_address_blocks(p: &chip::Peripheral) -> crate::Result crate::Result { if let Some(hex) = s.strip_prefix("0x") { usize::from_str_radix(hex, 16) From f6699a411b7d464f528b1fe6cd00d74af85b909e Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 9 Dec 2025 13:40:44 +0100 Subject: [PATCH 5/8] Drop all uses of `as` conversion These are dangerous because they silently truncate. --- src/lib.rs | 2 ++ src/svd/field.rs | 5 ++++- src/svd/register.rs | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 334cccc..b21d89d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(clippy::as_conversions)] + #[macro_use] pub mod error; #[cfg(feature = "cli")] diff --git a/src/svd/field.rs b/src/svd/field.rs index e5fa0ec..9e36c36 100644 --- a/src/svd/field.rs +++ b/src/svd/field.rs @@ -5,7 +5,10 @@ use std::convert::TryInto; pub fn generate(f: &chip::Field) -> crate::Result { let (write_constraint, enumerated_values) = svd::restriction::generate(&f.restriction, f.width().try_into()?)?; - let (lsb, msb) = (f.range.0 as u32, f.range.1 as u32); + let (lsb, msb) = ( + u32::try_from(f.range.0).unwrap(), + u32::try_from(f.range.1).unwrap(), + ); let field = svd_rs::FieldInfo::builder() .name(f.name.clone()) diff --git a/src/svd/register.rs b/src/svd/register.rs index cff52f2..bc3c913 100644 --- a/src/svd/register.rs +++ b/src/svd/register.rs @@ -3,7 +3,7 @@ use crate::svd::restriction::generate_access; pub fn generate(r: &chip::Register, base: u32) -> crate::Result { let (write_constraint, _) = - crate::svd::restriction::generate(&r.restriction, r.size as u32 * 8)?; + crate::svd::restriction::generate(&r.restriction, u32::try_from(r.size).unwrap() * 8)?; let register = svd_rs::RegisterInfo::builder() .name(r.name.clone()) @@ -11,9 +11,9 @@ pub fn generate(r: &chip::Register, base: u32) -> crate::Result Date: Tue, 9 Dec 2025 13:41:46 +0100 Subject: [PATCH 6/8] ci: Run clippy and deny all lints --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 847a158..590bbe9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 + - run: cargo clippy -- -Dwarnings - run: cargo run -- tests/atmega328p.atdf /dev/null test: From 5c0cf1683196fcd1324a5bd0496e13c36f608495 Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 9 Dec 2025 13:45:19 +0100 Subject: [PATCH 7/8] Reorder imports according to rustfmt --- src/atdf/chip.rs | 2 +- src/atdf/field.rs | 2 +- src/atdf/interrupt.rs | 2 +- src/atdf/patch.rs | 2 +- src/atdf/peripheral.rs | 2 +- src/atdf/register.rs | 2 +- src/atdf/values.rs | 2 +- src/svd/interrupt.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/atdf/chip.rs b/src/atdf/chip.rs index 6c60a85..e7f4eea 100644 --- a/src/atdf/chip.rs +++ b/src/atdf/chip.rs @@ -1,6 +1,6 @@ +use crate::ElementExt; use crate::atdf; use crate::chip; -use crate::ElementExt; use std::collections::BTreeMap; pub fn parse(el: &xmltree::Element) -> crate::Result { diff --git a/src/atdf/field.rs b/src/atdf/field.rs index f7ff149..b835a3a 100644 --- a/src/atdf/field.rs +++ b/src/atdf/field.rs @@ -1,7 +1,7 @@ +use crate::ElementExt; use crate::atdf; use crate::chip; use crate::util; -use crate::ElementExt; pub fn parse( bitfield_el: &xmltree::Element, diff --git a/src/atdf/interrupt.rs b/src/atdf/interrupt.rs index 9d250a8..b1ff4e8 100644 --- a/src/atdf/interrupt.rs +++ b/src/atdf/interrupt.rs @@ -1,6 +1,6 @@ +use crate::ElementExt; use crate::chip; use crate::util; -use crate::ElementExt; pub fn parse(interrupt: &xmltree::Element) -> crate::Result { debug_assert!(interrupt.name == "interrupt"); diff --git a/src/atdf/patch.rs b/src/atdf/patch.rs index bab415b..aca25d3 100644 --- a/src/atdf/patch.rs +++ b/src/atdf/patch.rs @@ -1,7 +1,7 @@ //! Patches for atdf files that can generally be applied +use crate::ElementExt; use crate::chip; use crate::util; -use crate::ElementExt; use std::collections::BTreeMap; const NEW_PORT_REGS: [&str; 10] = [ diff --git a/src/atdf/peripheral.rs b/src/atdf/peripheral.rs index b5ff771..d748864 100644 --- a/src/atdf/peripheral.rs +++ b/src/atdf/peripheral.rs @@ -1,7 +1,7 @@ +use crate::ElementExt; use crate::atdf; use crate::chip; use crate::util; -use crate::ElementExt; pub fn parse_list( el: &xmltree::Element, diff --git a/src/atdf/register.rs b/src/atdf/register.rs index df1a819..6b83586 100644 --- a/src/atdf/register.rs +++ b/src/atdf/register.rs @@ -1,7 +1,7 @@ +use crate::ElementExt; use crate::atdf; use crate::chip; use crate::util; -use crate::ElementExt; use std::collections::BTreeMap; fn field_map_from_bitfield_children( diff --git a/src/atdf/values.rs b/src/atdf/values.rs index ec1647a..aef0423 100644 --- a/src/atdf/values.rs +++ b/src/atdf/values.rs @@ -1,6 +1,6 @@ +use crate::ElementExt; use crate::chip; use crate::util; -use crate::ElementExt; use std::collections::BTreeMap; pub type ValueGroups = BTreeMap>; diff --git a/src/svd/interrupt.rs b/src/svd/interrupt.rs index 9e3ca0b..51cd817 100644 --- a/src/svd/interrupt.rs +++ b/src/svd/interrupt.rs @@ -1,5 +1,5 @@ -use crate::chip; use crate::DisplayError; +use crate::chip; use std::convert::TryInto; pub fn generate(peripherals: &mut [svd_rs::Peripheral], c: &chip::Chip) -> crate::Result<()> { From c91af390a151617748767c7ff892a6585ec2397b Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 9 Dec 2025 13:48:48 +0100 Subject: [PATCH 8/8] Disable `collapsible_if` clippy lint for the time being This relies on a relatively recent compiler feature. Let's not raise the MSRV just to please clippy. --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index b21d89d..c5c9887 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ #![deny(clippy::as_conversions)] +// TODO: Remove this at some point when the rustc feature is less new +#![allow(clippy::collapsible_if)] #[macro_use] pub mod error;