-
Notifications
You must be signed in to change notification settings - Fork 199
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
Implement a trait for types implementing some other trait #5195
Labels
bug
Something isn't working
Comments
5 tasks
github-merge-queue bot
pushed a commit
that referenced
this issue
Aug 2, 2024
# Description ## Problem Resolves #5195 ## Summary If I'm understanding the code correctly, when you have code like this: ```rust trait Trait { fn trait_func(self); } fn foo<T>(t: T) { Trait::trait_func(t); } ``` the compiler will search in all impls of `Trait` for a matching one. Then: - if it only finds one, it succeeds - otherwise it's an error (no matching impl found, or too many found) If an impl has a where clause, the compiler checks if that where clause matches. For example: ```rust trait One { } impl Trait for T where T: One { // ... } ``` So here there's an impl for `Trait`, it has a where clause, so the compiler checks if that `T` is `One`. And here's the thing: if there's no match, it would immediately error. I think that was the bug. In this PR, we capture that error but continue seeing if we can find a matching impl. If we can't find any impl, we use the error of the first non-matching `where` clause to help users. But... let me know if I got this wrong. I _think_ I understood the code, but I'm not sure. ## Additional Context When trying out different codes with traits and impls I noticed that we don't error if two trait impls are conflicting. For example Rust gives an error in this case: ```rust trait One {} impl One for i32 {} trait Three {} impl Three for i32 {} trait Two {} impl<T> Two for T where T: One {} impl<T> Two for T where T: Three {} ``` The error: ``` error[E0119]: conflicting implementations of trait `Two` --> src/main.rs:13:1 | 11 | impl<T> Two for T where T: One {} | ------------------------------ first implementation here 12 | 13 | impl<T> Two for T where T: Three {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation ``` I don't know if it's a requirement to do this before merging this PR. Even if there are conflicting impls in Noir, the compiler does the right thing. For example this code: ```rust trait One { } impl One for i32 { } trait Two { } impl Two for i32 { } trait Three { fn three(self); } impl<T> Three for T where T: One { fn three(self) { println("One"); } } impl<T> Three for T where T: Two { fn three(self) { println("Two"); } } fn use_one<T>(t: T) where T: One { Three::three(t); } fn use_two<T>(t: T) where T: Two { Three::three(t); } fn main() { let x: i32 = 0; use_one(x); use_two(x); } ``` prints: ``` One Two ``` ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Aim
Implement a trait for types implementing some other trait.
E.g., SerializeToSlice based on Serialize.
This seems to compile but then
triggers
Expected Behavior
Works
Bug
Not sure exactly what's going on.
To Reproduce
Project Impact
None
Impact Context
No response
Workaround
None
Workaround Description
No response
Additional Context
discussed with @TomAFrench
cc: @nventuro @Thunkar
Installation Method
None
Nargo Version
No response
NoirJS Version
No response
Would you like to submit a PR for this Issue?
None
Support Needs
No response
The text was updated successfully, but these errors were encountered: