Skip to content

Conversation

hawkw
Copy link
Member

@hawkw hawkw commented Sep 24, 2025

No description provided.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

license-eye has totally checked 603 files.

Valid Invalid Ignored Fixed
602 1 0 0
Click to see the invalid file list
  • lib/ereport/examples/test-expanded.rs

@@ -0,0 +1,121 @@
#![feature(prelude_import)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#![feature(prelude_import)]
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
#![feature(prelude_import)]

@hawkw
Copy link
Member Author

hawkw commented Sep 26, 2025

Okay, so the current approach as of e2e5106 seems to be more or less functional. But, there's one big flaw: it turns out there isn't really a way to take something like the current trait:

pub trait EreportData: Encode<()> {
/// The maximum length of the CBOR-encoded representation of this value.
///
/// The value is free to encode fewer than this many bytes, but may not
/// encode more.
const MAX_CBOR_LEN: usize;
}

and write a function like

pub fn encode_ereport<'buf, E: EreportData>(
    ereport: &E,
    buf: &'buf mut [u8; E::MAX_CBOR_LEN],
) -> &'buf [u8] {
    let mut encoder = Encoder::new(buf);
    todo!()
}

because this runs afoul of

error: generic parameters may not be used in const operations
  --> lib/ereport/src/lib.rs:22:25
   |
22 |     buf: &'buf mut [u8; E::MAX_CBOR_LEN],
   |                         ^^^^^^^^^^^^^^^ cannot perform const operation using `E`
   |
   = note: type parameters may not be used in const expressions
   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

This feels pretty unfortunate, as a function like this is basically the UX I was hoping to be able to have. Currently, the user can get the type to tell it what the right length for the buffer is, and use it to construct a buffer, but we can't easily have an API that ensures you use the correct-length buffer when encoding, which is too bad.

We could just enable the nightly-only #![feature(generic_const_exprs)] and have it work, but I think we're trying to avoid adding new nightly features.

Another option I'm thinking about is changing the trait to something like:

pub trait EreportData: Encode<()> {
    /// The maximum length of the CBOR-encoded representation of this value.
    ///
    /// The value is free to encode fewer than this many bytes, but may not
    /// encode more.
    const MAX_CBOR_LEN: usize;
    type NeededBuf: AsRef<[u8]> + AsMut<[u8]>;
}

and having the derive macro generate a NeededBuf associated type that's [u8; MAX_CBOR_LEN]. We could then have an encode function that's like

pub fn encode_ereport<'buf, E: EreportData>(
    ereport: &E,
    buf: &'buf mut E::NeededBuf,
) -> &'buf [u8] {
   // ...
}

and you wouldn't be able to call it with a too-short array. But, this might be overthinking it...

@hawkw
Copy link
Member Author

hawkw commented Sep 29, 2025

Update: nope, the approach proposed in #2246 (comment) still ends up using a generic parameter in a const expression if the type is generic over another type implementing EreportData. So, we really just can't quite do that without #![feature(generic_const_exprs)]. I think the current state of this is still useful as it at least gives us a way to "manually" construct a correct-length buffer. You can choose to misuse the derived implementation with a wrong-length buffer, but...you could do this before, too. It would be nice to have a misuse-resistant API, but I can accept just having an API that does the Right Thing if you don't misuse it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant