Skip to content

Commit 4bbe27f

Browse files
authored
Merge branch 'main' into linux-and-mac-compatibility-branched
2 parents 7b92af8 + d477bf3 commit 4bbe27f

35 files changed

Lines changed: 280 additions & 157 deletions

.github/workflows/cargo-semver-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,5 @@ jobs:
3939
uses: obi1kenobi/cargo-semver-checks-action@v2
4040
with:
4141
manifest-path: firmware/
42-
exclude: defmt-semihosting
42+
exclude: defmt-semihosting,defmt-test
4343
# rust-target: thumbv7em-none-eabihf

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
if: matrix.os == 'ubuntu-latest'
3737
run: sudo apt-get update && sudo apt-get install libudev-dev libusb-1.0-0-dev
3838
- name: Check that all crates that can be compiled for the host build, check that defmt compiles with different features, run all unit tests on the host
39-
run: cargo xtask -d test-host ${{ matrix.toolchain == '1.83' && '--skip-ui-tests' || '' }}
39+
run: cargo xtask -d test-host ${{ matrix.toolchain == 'stable' && '--skip-ui-tests' || '' }}
4040

4141
cross:
4242
strategy:

CHANGELOG.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ We have several packages which live in this repository. Changes are tracked sepa
6969
* [#983] Add `Format` implementation for `core::num::Wrapping<T>`
7070
* [#1022] Re-fix accidental breaking change in `Format` macro
7171
* [#1041] Ignore RUSTSEC-2026-0009
72+
* [#1052] Pin UI tests to host MSRV
7273

7374
### [defmt-v1.0.1] (2025-04-01)
7475

@@ -439,6 +440,7 @@ Initial release
439440

440441
### [defmt-macros-next]
441442

443+
* [#1044]: Add support for `bound` attribute via a `#[defmt(bound(T: MyCustomBound))]`
442444
* [#956]: Link LICENSE-* in the crate folder
443445

444446
### [defmt-macros-v1.0.1] (2025-04-01)
@@ -888,7 +890,8 @@ Initial release
888890

889891
### [defmt-test-next]
890892

891-
* No changes
893+
* [#1049] Pin trybuild to 1.0.89
894+
* [#1046] Replace `cortex-m-semihosting` with generic `semihosting` crate to support non-Cortex-M thumb targets
892895

893896
### [defmt-test-v0.4.0] (2025-04-01)
894897

@@ -969,7 +972,7 @@ Initial release
969972

970973
### [qemu-run-next]
971974

972-
* No changes
975+
* [#1048] Fixed UART read timeout issue ([#1047])
973976

974977
### [qemu-run-v0.1.1]
975978

@@ -1004,6 +1007,12 @@ Initial release
10041007

10051008
---
10061009

1010+
[#1052]: https://github.com/knurling-rs/defmt/pull/1052
1011+
[#1049]: https://github.com/knurling-rs/defmt/pull/1049
1012+
[#1048]: https://github.com/knurling-rs/defmt/pull/1048
1013+
[#1047]: https://github.com/knurling-rs/defmt/pull/1047
1014+
[#1046]: https://github.com/knurling-rs/defmt/pull/1046
1015+
[#1044]: https://github.com/knurling-rs/defmt/pull/1044
10071016
[#1041]: https://github.com/knurling-rs/defmt/pull/1041
10081017
[#1036]: https://github.com/knurling-rs/defmt/pull/1036
10091018
[#1028]: https://github.com/knurling-rs/defmt/pull/1028

book/src/format.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,27 @@ struct Header {
5656
}
5757
```
5858

59+
## `#[derive(Format)]`'s `bound()` attribute
60+
61+
Sometimes, the bounds generated by the `Format` derive can be incorrect for your use-case (ie: using a generic as a flavored ZST).
62+
63+
```rs
64+
#[derive(Format)]
65+
struct Foo<T: AssociatedStrType>(T::Str);
66+
```
67+
68+
will generate a `T: ::defmt::Format` bound over the `Format` implementation even if `T` isn't actually used.
69+
70+
For cases like these you can use the `bound()` attribute:
71+
72+
```rs
73+
#[derive(Format)]
74+
#[defmt(bound())] // empties out the default generated bounds
75+
#[defmt(bound(T::Str: ::defmt::Format))] // overwrites the default generated bounds
76+
struct Foo<T: AssociatedStrType>(T::Str);
77+
```
78+
79+
5980
## Manual implementation with `write!`
6081

6182
It is also possible to implement the `Format` trait manually.

defmt/tests/derive-bounds.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(dead_code)]
12
extern crate defmt as defmt2;
23

34
fn main() {
@@ -56,3 +57,25 @@ struct Transparent<T: Foo>(Quux<T>);
5657
#[defmt(crate = defmt3, crate = defmt2)]
5758
#[allow(dead_code)]
5859
struct Variations<T: Foo>(Quux<T>);
60+
61+
struct Flavor;
62+
63+
trait FlavorT {
64+
type List<'a, T: 'a + ::defmt::Format>: ::defmt::Format;
65+
}
66+
67+
impl FlavorT for Flavor {
68+
type List<'a, T: 'a + ::defmt::Format> = &'a [T];
69+
}
70+
71+
#[derive(defmt::Format)]
72+
#[defmt(bound())] // fixes the compile error from `ui/derive_bound_overflow.rs`
73+
enum Flavored<F: FlavorT + 'static> {
74+
Str(F::List<'static, Self>),
75+
}
76+
77+
const _: () = {
78+
const fn implements_format<T: defmt::Format>() {}
79+
80+
implements_format::<Flavored<Flavor>>();
81+
};

defmt/tests/ui/derive-invalid-crate-overwrite.stderr

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,8 @@ error[E0432]: unresolved import `unresolved`
1818
|
1919
= note: this error originates in the derive macro `defmt::Format` (in Nightly builds, run with -Z macro-backtrace for more info)
2020

21-
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `unresolved`
21+
error[E0433]: failed to resolve: use of undeclared crate or module `unresolved`
2222
--> tests/ui/derive-invalid-crate-overwrite.rs:2:17
2323
|
2424
2 | #[defmt(crate = unresolved)]
25-
| ^^^^^^^^^^ use of unresolved module or unlinked crate `unresolved`
26-
27-
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `unresolved`
28-
--> tests/ui/derive-invalid-crate-overwrite.rs:2:17
29-
|
30-
2 | #[defmt(crate = unresolved)]
31-
| ^^^^^^^^^^ use of unresolved module or unlinked crate `unresolved`
32-
|
33-
= help: if you wanted to use a crate named `unresolved`, use `cargo add unresolved` to add it to your `Cargo.toml`
25+
| ^^^^^^^^^^ use of undeclared crate or module `unresolved`
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
struct Flavor;
2+
3+
trait FlavorT {
4+
type List<'a, T: 'a + ::defmt::Format>: ::defmt::Format;
5+
}
6+
7+
impl FlavorT for Flavor {
8+
type List<'a, T: 'a + ::defmt::Format> = &'a [T];
9+
}
10+
11+
#[derive(defmt::Format)]
12+
// #[defmt(bound())] // fixes the compile error
13+
enum Flavored<F: FlavorT + 'static> {
14+
Str(F::List<'static, Self>),
15+
}
16+
17+
const _: () = {
18+
const fn implements_format<T: defmt::Format>() {}
19+
20+
implements_format::<Flavored<Flavor>>(); // overflow by the compiler, can only be fixed by removing the bound
21+
};
22+
23+
fn main() {}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
error[E0275]: overflow evaluating the requirement `<F as FlavorT>::List<'static, Flavored<F>>: Format`
2+
--> tests/ui/derive_bound_overflow.rs:14:9
3+
|
4+
14 | Str(F::List<'static, Self>),
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: required for `Flavored<F>` to implement `Format`
8+
--> tests/ui/derive_bound_overflow.rs:11:10
9+
|
10+
11 | #[derive(defmt::Format)]
11+
| ^^^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
12+
12 | // #[defmt(bound())] // fixes the compile error
13+
13 | enum Flavored<F: FlavorT + 'static> {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
note: required by a bound in `FlavorT::List`
16+
--> tests/ui/derive_bound_overflow.rs:4:27
17+
|
18+
4 | type List<'a, T: 'a + ::defmt::Format>: ::defmt::Format;
19+
| ^^^^^^^^^^^^^^^ required by this bound in `FlavorT::List`
20+
= note: this error originates in the derive macro `defmt::Format` (in Nightly builds, run with -Z macro-backtrace for more info)
21+
22+
error[E0275]: overflow evaluating the requirement `Flavored<Flavor>: Format`
23+
--> tests/ui/derive_bound_overflow.rs:20:5
24+
|
25+
20 | implements_format::<Flavored<Flavor>>(); // overflow by the compiler, can only be fixed by removing the bound
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
|
28+
note: required by a bound in `implements_format`
29+
--> tests/ui/derive_bound_overflow.rs:18:35
30+
|
31+
18 | const fn implements_format<T: defmt::Format>() {}
32+
| ^^^^^^^^^^^^^ required by this bound in `implements_format`
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
struct Flavor;
2+
3+
trait FlavorT {
4+
type Str;
5+
}
6+
7+
impl FlavorT for Flavor {
8+
type Str = &'static str;
9+
}
10+
11+
#[derive(defmt::Format)]
12+
#[defmt(bound())]
13+
#[defmt(bound(F: Sized))]
14+
enum Flavored<F: FlavorT> {
15+
Str(F::Str),
16+
}
17+
18+
const _: () = {
19+
const fn implements_format<T: defmt::Format>() {}
20+
21+
implements_format::<Flavored<Flavor>>();
22+
};
23+
24+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the trait bound `<F as FlavorT>::Str: Format` is not satisfied
2+
--> tests/ui/derive_removed_bound.rs:11:10
3+
|
4+
11 | #[derive(defmt::Format)]
5+
| ^^^^^^^^^^^^^ the trait `Format` is not implemented for `<F as FlavorT>::Str`
6+
|
7+
note: required by a bound in `defmt::export::fmt`
8+
--> src/export/mod.rs
9+
|
10+
| pub fn fmt<T: Format + ?Sized>(f: &T) {
11+
| ^^^^^^ required by this bound in `fmt`
12+
= note: this error originates in the derive macro `defmt::Format` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)