Skip to content

#[derive(BorshSchema)] chokes on PhantomData in enums #329

@peer2f00l

Description

@peer2f00l

Background

I'm working on a smart contract that uses the #[near] macro from near-sdk, which is how I discovered this issue.

User Story

I have a type-parameterized enum that contains PhantomData which I wish to annotate with #[derive(BorshSchema)].

Sample code:

use std::marker::PhantomData;

use borsh::BorshSchema;

#[derive(BorshSchema)]
pub struct MyStruct<T> {
    item: PhantomData<T>,
}

#[derive(BorshSchema)]
pub enum MyEnum<T> {
    Item(PhantomData<T>),
}

MyStruct compiles without issue. I would expect MyEnum to compile fine as well, but I get the following compilation error:

error[E0401]: can't use generic parameters from outer item
  --> src/lib.rs:12:22
   |
11 | pub enum MyEnum<T> {
   |                 - type parameter from outer item
12 |     Item(PhantomData<T>),
   |                      ^ use of generic parameter from outer item

For more information about this error, try `rustc --explain E0401`.
error: could not compile `borsh-schema-test` (lib) due to 1 previous error

Interestingly enough, it compiles fine if I change PhantomData<T> to Vec<T> or apparently any other generic type. In fact, simply wrapping PhantomData<T> in a newtype struct is apparently sufficient, as this compiles fine:

#[derive(BorshSchema)]
pub enum MyEnum<T> {
    Item(MyPhantomData<T>),
}

#[derive(BorshSchema)]
pub struct MyPhantomData<T>(PhantomData<T>);

So, something weird is going on specifically with this enum-PhantomData pairing.

Acceptance Criteria

This code should compile:

#[derive(BorshSchema)]
pub enum MyEnum<T> {
    Item(PhantomData<T>),
}

Resources & Additional Notes

No response

Priority

🟢 P3 : Normal

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions