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

Fixes multiple trait constraints for same method. #3818

Closed
wants to merge 4 commits into from

Conversation

esdrubal
Copy link
Contributor

When multiple trait constraints were used for same method but with different types an error would occur as the replace of the declaration would pick only one trait method implementation for both constraints.

The solution was to use IdentUnique while collecting traits implemented methods. This allows to create DeclMapping mappings from one trait original method to multiple trait implementations. For instance eq method original method to both bool and u64 trait implementations.

The other step of the solution was to verify while replacing decls if the current function application being replaced matches the argument types of one decl mapping specifically.

The issue it solves is related with #3325
This is another subset of #3621

@esdrubal esdrubal self-assigned this Jan 18, 2023
@esdrubal esdrubal added bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen labels Jan 18, 2023
@esdrubal esdrubal requested a review from a team January 18, 2023 21:41
Copy link
Contributor

@emilyaherbert emilyaherbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what I'm seeing here is that the diagnosis for this bug is that it is occurring because replace_decls is replacing methods defined on E with methods defined on T? And that this is because fromT: Eq and E: Eq, both of these Eq's share a common parent?

Hmm, this is tricky. And it's tempting to block this issue behind #1267, and solving that first would make solving this one much more approachable.

continue;
}

let decl = engines.de().get(dest_decl_id.clone());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding these changes here, does it work to instead copy the code from lines 645-660 and add it to the definition of replace_decls on DeclId?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inside a for loop, I could move the whole block from 620 to 669, but I think it looks better on the context it is now.

sway-core/src/decl_engine/mapping.rs Outdated Show resolved Hide resolved
@@ -191,7 +191,7 @@ impl TypeParameter {
let mut errors = vec![];

let mut original_method_ids: BTreeMap<Ident, DeclId> = BTreeMap::new();
let mut impld_method_ids: BTreeMap<Ident, DeclId> = BTreeMap::new();
let mut impld_method_ids: BTreeMap<IdentUnique, DeclId> = BTreeMap::new();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference between Ident and IdentUnique is that it allows Span information to make idents unique when hashing and comparing them. We should not rely on span information in this part of the compiler to determine trait resolution. Among other reasons, Spans will not always be what the Sway compiler uses and may be upgraded in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I borrowed the concept of TyFunctionSig from #3878 and replaced IdentUnique usage with (Ident, TyFunctionSig).

When multiple trait constraints were used for same method but with
different types an error would occur as the replace of the declaration
would pick only one trait method implementation for both constraints.

The solution was to use IdentUnique while collecting traits implemented
methods. This allows to create `DeclMapping` mappings from
one trait original method to multiple trait implementations. For
instance eq method original method to both bool and u64 trait
implementations.

The other step of the solution was to verify while replacing decls if
the current function application beeing replaced matches the argument
types of one decl mapping specifically.
Replaces `IdentUnique` usage with `(Ident, TyFunctionSig)`.
Borrowed TyFunctionSig from 3878.
@esdrubal esdrubal force-pushed the esdrubal/3325_multiple_trait_constraints branch from f01a14c to 174438f Compare January 27, 2023 13:53
sway-types/src/ident.rs Outdated Show resolved Hide resolved
@emilyaherbert
Copy link
Contributor

emilyaherbert commented Feb 3, 2023

After some discussion offline, this ticket was found to be blocked behind #1267. While it is not intractable to solve this specific bug without #1267, this bug is a symptom of a deeper bug with the parents abstraction on the DeclEngine. Implementing #1267 would allow for the parents abstraction to be removed. Instead of patching this bug right now, I'm going to bring this PR down to a draft until #1267 is closed.

@emilyaherbert emilyaherbert marked this pull request as draft February 3, 2023 16:39
@esdrubal
Copy link
Contributor Author

esdrubal commented Feb 5, 2024

Already fixed in master. #5553 adds test case.

@esdrubal esdrubal closed this Feb 5, 2024
@esdrubal esdrubal deleted the esdrubal/3325_multiple_trait_constraints branch February 5, 2024 15:11
ironcev pushed a commit that referenced this pull request Feb 5, 2024
## Description

PR #3818 is no longer necessary and this PR proves that the test cases
added on in already pass on master without any additional change.

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants