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

Singleton Map Recursion fails to compile due to recursion #416

@Byter09

Description

@Byter09

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions