Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Singleton Map Recursion fails to compile due to recursion #416

Open
Byter09 opened this issue Mar 11, 2024 · 0 comments
Open

Singleton Map Recursion fails to compile due to recursion #416

Byter09 opened this issue Mar 11, 2024 · 0 comments

Comments

@Byter09
Copy link

Byter09 commented Mar 11, 2024

Hi!

I'm currently using rasn to parse ASN1. To verify outputs of various input files, I'm using serde-yaml to convert the final type into a string that I can store in files and then commit to the repository.

I'm hitting this error when trying to use the recursive version of a singleton map:

error: reached the recursion limit while instantiating `_::_serde::ser::impls::<impl Serialize for &singleton_map_recursive::SingletonMapRecursive<&singleton_map_recursive::SingletonMapRecursive<&...>>>::serialize::<...>`
   --> /home/btr/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_yaml-0.9.32/src/with.rs:981:13
    |
981 | /             self.delegate.serialize(SingletonMapRecursive {
982 | |                 delegate: serializer,
983 | |             })
    | |______________^
    |
note: `_::_serde::ser::impls::<impl Serialize for &'a T>::serialize` defined here
   --> /home/btr/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.197/src/ser/impls.rs:506:1
    |
506 | / deref_impl! {
507 | |     <'a, T: ?Sized> Serialize for &'a T where T: Serialize
508 | | }
    | |_^
    = note: the full type name has been written to '/home/btr/Projects/_unimportant_/lib/target/debug/deps/_unimportant_-df951b3711978b56.long-type.txt'
    = note: this error originates in the macro `deref_impl` (in Nightly builds, run with -Z macro-backtrace for more info)

The full type mentioned in the error looks like this:

_::_serde::ser::impls::<impl Serialize for &singleton_map_recursive::SingletonMapRecursive<&singleton_map_recursive::SingletonMapRecursive<&singleton_map_recursive::SingletonMapRecursive<&singleton_map_recursive::SingletonMapRecursive<&singleton_map_recursive::SingletonMapRecursive<&singleton_map_recursive::SingletonMapRecursive<&iso_9506_mms_1::_::<impl Serialize for TypeSpecification>::serialize::__SerializeWith<'_>>>>>>>>::serialize::<singleton_map_recursive::SingletonMapRecursive<singleton_map_recursive::SingletonMapRecursive<singleton_map_recursive::SingletonMapRecursive<&mut serde_yaml::Serializer<&mut Vec<u8>>>>>>

The types involved in this recursion currently look like this:

/// ASN1:
/// See ISO 9506-1 14.2.1
#[derive(AsnType, Clone, Debug, Decode)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[rasn(choice)]
pub(crate) enum TypeDescription {
    #[rasn(tag(1))]
    Array(Box<Array>),
    #[rasn(tag(2))]
    Structure(Structure),
    #[rasn(tag(3))]
    Boolean(()),
    #[rasn(tag(4))]
    BitString(Integer32),
    #[rasn(tag(5))]
    Integer(Unsigned8),
    #[rasn(tag(6))]
    Unsigned(Unsigned8),
    #[rasn(tag(9))]
    OctetString(Integer32),
    #[rasn(tag(10))]
    VisibleString(Integer32),
    #[rasn(tag(11))]
    GeneralizedTime(()),
    #[rasn(tag(12))]
    BinaryTime(bool),
    #[rasn(tag(13))]
    BCD(Unsigned8),
    #[rasn(tag(15))]
    ObjectID(()),
}

#[derive(AsnType, Clone, Debug, Decode)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub(crate) struct Structure {
    #[rasn(tag(0), default(false))]
    packed: bool,
    #[rasn(tag(1))]
    components: SequenceOf<Component>,
}

#[derive(AsnType, Clone, Debug, Decode)]
#[cfg_attr(feature = "serde", derive(Serialize))]
struct Component {
    #[rasn(tag(0))]
    component_name: Option<Identifier>,
    #[rasn(tag(explicit(1)))]
    component_type: TypeSpecification,
}

#[derive(AsnType, Clone, Debug, Decode)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[rasn(choice)]
pub(crate) enum TypeSpecification {
    #[rasn(tag(explicit(0)))]
    Name(ObjectName),
    #[cfg_attr(
        feature = "serde",
        serde(with = "serde_yaml::with::singleton_map_recursive")
    )]
    Description(TypeDescription),
}

Also a minimal example would probably look like this? I can't seem to reproduce the above error in the playground.

#[derive(Clone, Debug, Serialize)]
enum TypeDescription {
    Structure(Structure),
}

#[derive(Clone, Debug, Serialize)]
struct Structure {
    components: Vec<Component>,
}

#[derive(Clone, Debug, Serialize)]
struct Component {
    component_type: TypeSpecification,
}

#[derive(Clone, Debug, Serialize)]
enum TypeSpecification {
    #[serde(with = "serde_yaml::with::singleton_map_recursive")]
    Description(TypeDescription),
}

I know there's recursion handling in runtime code (probably not related to this), but this is something that fails to compile, and something like the recursion_limit attribute does not help.

I'm not sure if there's even a solution for this. In the meantime I'm using just "singleton_map", but obviously my output is missing data. Not optimal, but not the worst for now, as my dbg!() output told me the result is good as it is.

Any advice on this? Is there maybe a fix? Anything I can do?

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

No branches or pull requests

1 participant