Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enums defined in a contract interface are unusable when imported #2116

Closed
NtTestAlert opened this issue Nov 2, 2022 · 6 comments
Closed
Assignees
Labels

Comments

@NtTestAlert
Copy link

NtTestAlert commented Nov 2, 2022

Tested on newest emulator

Problem

Enums defined in a contract interface are unusable in implementing contract

Steps to Reproduce

// Iface.cdc
pub contract interface Iface {
 pub enum TestEnum: UInt8 {
   pub case Initialized
   pub case Other
 }
 // error: enum interfaces are not supported
 //pub enum interface TestEnumI {
 //   pub case Initialized
 //   pub case Other
 //}
}

// TestContract.cdc

import Iface from "./Iface.cdc"
pub contract TestContract {
    pub enum TestEnum: UInt8 {
        pub case Initialized
        pub case Other
    }
    pub var canUseType:Iface.TestEnum?
    //                 ^^^^^^^^^^^^^^ works properly
    pub fun crashes() {
        self.canUseType = Iface.TestEnum.Initialized
        // ERROR          ^^^^^ not found in this scope
        //    cannot find variable in this scope: `Iface`
    }
    pub fun alsoCrashes(): Bool {
        return self.canUseType! == Iface.TestEnum.Initialized
        // ERROR                   ^^^^^ not found in this scope
        //    cannot find variable in this scope: `Iface`
    }
    pub fun alsoCrashes2(): Bool {
        return self.canUseType! == TestEnum.Initialized
        // ERROR error: cannot apply binary operation == to types: `Iface.TestEnum`, `TestContract.TestEnum`
    }

    init() {
        self.canUseType = nil
        // works
    }
}
@SupunS
Copy link
Member

SupunS commented Nov 2, 2022

Nested types (structs, resources, enums) defined in interfaces are only "type requirements", but not concrete type definitions: (see: https://developers.flow.com/cadence/language/interfaces#nested-type-requirements).

i.e: They only mandate the interface implementations to also implement the type. Moreover, since they are not concrete type definitions: they cannot be used to create a value or used as a value (enum cases are values).

This can be somewhat confusing. Because of the same reason, there is a proposal to remove this "type requirement" feature: #1283.

@turbolent
Copy link
Member

This works as expected, so closing.

@NtTestAlert let us know if you have any questions regarding this!

@NtTestAlert
Copy link
Author

NtTestAlert commented Nov 3, 2022

Oh, ok.

The type requirement is not enforced though:

import Iface from "./Iface.cdc"
pub contract TestContract {
    pub var canUseType:Iface.TestEnum?
    init() {
        self.canUseType = nil
        // works
    }
}

(This deploys fine with the above interface)
Possibly not yet implemented for enums.

IMO if possible the abstract type should not be allowed to be used in var declarations/typing, to reduce confusion.

I assume the behavior that I was trying to achieve (allow common enum type for integration with custom contracts implementing an interface) will be added along with enum interface at a later time?

@SupunS
Copy link
Member

SupunS commented Nov 3, 2022

Type requirements are enforced only if a contract conforms to a contract interface.
i.e:

pub contract TestContract: Iface {
   ...
}

@SupunS
Copy link
Member

SupunS commented Nov 3, 2022

Once you add the conformance like above, the enum TestContract.TestEnum would implicitly conforms to the enum Iface.TestEnum.

Then you can do the assignment like:

pub fun test() {
        self.canUseType = TestEnum.Initialized
}

Note that, if you want to compare, then you'll first need to downcast it to the intended type:

return (self.canUseType! as! TestEnum) == TestEnum.Initialized

@NtTestAlert
Copy link
Author

NtTestAlert commented Nov 3, 2022

Ok, thank you :)

(indeed forgot to put the conformance in this test case, sorry)

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

No branches or pull requests

3 participants