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

Trait Coherence bug #6232

Open
Braqzen opened this issue Jul 5, 2024 · 6 comments
Open

Trait Coherence bug #6232

Braqzen opened this issue Jul 5, 2024 · 6 comments

Comments

@Braqzen
Copy link
Contributor

Braqzen commented Jul 5, 2024

Context

A contract calls another contract to return a struct.
This results in an error message indicating that AbiDecode trait must be implemented.
Upon implementing a template AbiDecode trait the subsequent forc build errors with a Trait Coherence error meaning the attached repo cannot be built with or without the trait - blocking production in a deadlock.

Check out the following minimal repo which pins the version to 0.60.0

https://github.com/Braqzen/sway-trait-coherence-bug

@Braqzen
Copy link
Contributor Author

Braqzen commented Jul 5, 2024

Once fixed the repo will be deleted.

@ironcev
Copy link
Member

ironcev commented Jul 5, 2024

How does the original struct looks like? Does it contains anything that cannot be automatically encoded/decoded?

I ask because in the minimum repro, the empty MyType will get the auto-generated AbiDecode implementation which will clash with the one implemented manually. I assume that's the reason for the trait coherence error.

The question is why the original type cannot be encoded/decoded. And if it can't, there should be no auto-impl and thus no trait coherence issues if an implementation is provided.

CC: @xunilrj

@SwayStar123
Copy link
Member

I dont know if this is the intended solution but simply importing the type in contract a will allow the contract to be compiled
aka


use libraries::{ContractA, ContractB, MyType};
use std::constants::ZERO_B256;

impl ContractA for Contract {
    fn contract_a_call() {             
        let contract_b = abi(ContractB, ZERO_B256);
        let _ = contract_b.contract_b_call();
    }
}

Incase it is the intended solution the error should be improved. Either way, i hope you can use that as a workaround for now

@Braqzen
Copy link
Contributor Author

Braqzen commented Jul 5, 2024

If MyType has fields, but is not imported as above, the error persists.

Once it is imported into ContractA as per Sway's suggestion, the error disappears regardless of whether it has fields.

@xunilrj
Copy link
Contributor

xunilrj commented Jul 5, 2024

I think this is already fixed by this commit: f4f9c13

@Braqzen
Copy link
Contributor Author

Braqzen commented Jul 22, 2024

In version 0.61.2 the following code produces the trait coherence error

contract;

use std::constants::ZERO_B256;

abi MyContract {
    fn call_a();
}

abi Module {
    fn call_b();
}

configurable {
    CONTRACT: ContractId = ContractId::from(ZERO_B256),
}

impl MyContract for Contract {
    fn call_a() {
        let a = abi(Module, CONTRACT.bits());
        let b = abi(Module, CONTRACT.bits());
    }
}

The problem is CONTRACT.bits() for var b.
If we extract the clean method call into another line id = CONTRACT.bits() and then use the id in place of CONTRACT.bits() then it works.

Strange bug. We should be able to write the code above instead of extracting into another line to pass in the variable into the abi

@xunilrj

1

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

No branches or pull requests

4 participants