Skip to content

Commit 055f9a9

Browse files
committed
Fix error for invalid deku_id generation on generic enum
Add/Fixup lifetime for generated code for enum ext id finding. Lifetime __deku needs to be added to the deku_id_type, and the impl.
1 parent 5799ff4 commit 055f9a9

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

deku-derive/src/macros/deku_read.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,12 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
409409

410410
// Implement `DekuEnumExt`
411411
if let Some(deku_id_type) = deku_id_type {
412-
tokens.extend(quote! {
413-
impl #imp DekuEnumExt<#lifetime, (#deku_id_type)> for #ident #wher {
412+
if !imp.to_token_stream().is_empty() {
413+
// Generics (#imp) are not supported, as our __deku
414+
// would need to be appended to #imp
415+
} else {
416+
tokens.extend(quote! {
417+
impl<'__deku> #imp ::#crate_::DekuEnumExt<#lifetime, (#deku_id_type)> for #ident #wher {
414418
#[inline]
415419
fn deku_id(&self) -> core::result::Result<(#deku_id_type), DekuError> {
416420
match self {
@@ -420,6 +424,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
420424
}
421425
}
422426
});
427+
}
423428
}
424429

425430
// println!("{}", tokens.to_string());

deku-derive/src/macros/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use syn::parse::Parser;
44
use syn::punctuated::Punctuated;
55
use syn::spanned::Spanned;
66
use syn::token::Comma;
7+
use syn::Lifetime;
78

89
use crate::Num;
910

@@ -211,6 +212,10 @@ fn gen_type_from_ctx_id(
211212
if let syn::FnArg::Typed(pat_type) = arg {
212213
if let syn::Pat::Ident(ident) = &*pat_type.pat {
213214
if id == ident.ident {
215+
let mut pat_type = pat_type.clone();
216+
if let syn::Type::Reference(r) = pat_type.ty.as_mut() {
217+
r.lifetime = Some(Lifetime::new("'__deku", Span::call_site()));
218+
}
214219
let ty = &pat_type.ty;
215220
t = Some(quote! {#ty});
216221
}

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ pub trait DekuUpdate {
521521
}
522522

523523
/// "Extended Enum" trait: obtain additional enum information
524-
pub trait DekuEnumExt<'a, T> {
524+
pub trait DekuEnumExt<'__deku, T> {
525525
/// Obtain `id` of a given enum variant
526526
fn deku_id(&self) -> Result<T, DekuError>;
527527
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use deku::prelude::*;
2+
3+
#[derive(DekuRead)]
4+
#[deku(id_type = "u8")]
5+
pub enum Body<T: for<'a> DekuReader<'a>> {
6+
#[deku(id = "0x0001")]
7+
First(T),
8+
}
9+
10+
fn main() {
11+
let n = Body::<u8>::First(1);
12+
n.deku_id();
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0599]: no method named `deku_id` found for enum `Body` in the current scope
2+
--> tests/test_compile/cases/no_deku_id_generic_enum.rs:12:7
3+
|
4+
5 | pub enum Body<T: for<'a> DekuReader<'a>> {
5+
| ---------------------------------------- method `deku_id` not found for this enum
6+
...
7+
12 | n.deku_id();
8+
| ^^^^^^^ method not found in `Body<u8>`
9+
|
10+
= help: items from traits can only be used if the trait is implemented and in scope
11+
= note: the following trait defines an item `deku_id`, perhaps you need to implement it:
12+
candidate #1: `deku::DekuEnumExt`

0 commit comments

Comments
 (0)