-
Notifications
You must be signed in to change notification settings - Fork 17
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
Remove trait indirection when the impl is known #210
base: main
Are you sure you want to change the base?
Conversation
I think a diff like this in Eurydice should unblock you:
although other patterns in this list probably need to be updated as well -- do you know how to update those patterns? I don't know how to compute them myself apart from trying to trigger the error |
(at least it removed the failure from my end, although I do get another, seemingly unrelated error later on) |
So I went pretty far in trying to update eurydice to deal with this PR. But honestly, I'm pretty stuck so I think it'd be great if you could help me fix these patterns. Here's the part that confuses me: - parse_pattern "SliceIndexShared<'_, @T>", Builtin.slice_index;
- parse_pattern "SliceIndexMut<'_, @T>", Builtin.slice_index;
- parse_pattern "core::ops::index::Index<[@T], core::ops::range::Range<usize>>::index", Builtin.slice_subslice;
- parse_pattern "core::ops::index::IndexMut<[@T], core::ops::range::Range<usize>>::index_mut", Builtin.slice_subslice;
+ parse_pattern "core::ops::index::Index<[@], core::ops::range::Range<usize>>::index", Builtin.slice_index;
+ parse_pattern "core::ops::index::IndexMut<[@], core::ops::range::Range<usize>>::index_mut", Builtin.slice_index;
+ parse_pattern "core::slice::index::{core::ops::index::Index<[@T], @I>}::index<@, core::ops::range::Range<usize>>", Builtin.slice_subslice;
+ parse_pattern "core::slice::index::{core::ops::index::IndexMut<[@T], @I>}::index_mut<@, core::ops::range::Range<usize>>", Builtin.slice_subslice; This is an attempt to deal with your changes. The branches I'm using are:
which is the most comprehensive Eurydice test we have right now. What confuses me is that I don't understand whether I'm doing the right thing. In particular, the new pattern for I'm also hitting a new pattern: To reproduce, run I'll leave this aside for now and hopefully let's sync up on Monday if you haven't managed to fix this already. Thanks so much! (Also CC @W95Psp who might be able to help.) |
I think I'm starting to understand. It now seems like the patterns are no longer canonical and I might encounter either
or
I'm not sure if this is intentional, but it looks like I need to duplicate every pattern in my list to account for both forms. Since I don't know whether this is an intentional effect, I'll stop here, and you should be able to fix this quickly by patching my branch and re-running c.sh with every pattern in both forms. Thanks! |
It looks like the pass which removes trait indirections misses some cases. For the patterns you copy-pasted I see:
|
Hmm, it would be nice if patterns for the impl could also match on the methods |
I think I get what you are saying. Now, depending on whether the trait instance has been statically resolved, or whether it's referring to a trait clause in scope, I may get different kinds of pattern (an impl or a decl, respectively). Agree that it would be nice if this could be uniform, although probably not the end of the world if I have to write both. My main difficulty is that right now I manually run my test suite, notice that there's an assertion failure, look at my debug print above that says "the pattern for this code is XXX", try to guess what XXX is, then adjust my list of patterns in the code, then repeat until it converges. Is there a better way? |
There is actually a simple way of doing that: when matching a pattern with a method, you can also additionally match it with the trait reference (+ the method name). There is something which annoys me here, though, which is that I don't understand why both patterns appear. If the simplification works, then we should only see the method, not a projection of the method belonging to a specific trait impl. |
I've been thinking about it. Maybe it would work if we could automatically generate the patterns (this is what Lucas does)? For instance, we could use attributes to annotate functions/terms?... Something along the lines (not sure if it is really possible): fn f1<T, N>(x: &[T; N]) -> usize {
@[eurydice(array_length)]
x.len()
} @W95Psp how do you do exactly? |
I'm not sure to understand exactly: by pattern here you mean something to select a rust name instantiated with a given list of types? There are two mechanisms in hax:
I guess here what would be -nice is the antiquotation thing, right? I ended up having no time to implement it in a nice way for hax :( and that's probably overkill |
c49302e
to
32450a5
Compare
Alright, I understand what's up, I'm working on a fix |
This is proving to be a rabbit-hole of a fix. I'll get there eventually but I have to clarify our use of generics some more first. |
32450a5
to
de74e0e
Compare
de74e0e
to
e6167d7
Compare
Charon handles trait impls as follows: all methods definitions become top-level functions, and the trait impl simply bundles them. E.g. in:
the impl becomes something like:
Whenever we call
Struct::default()
, this is encoded as a reference to theimpl Default for Struct
bundle and then to the method in that bundle. This can make definitions more recursive than they need to.This PR adds a micro-pass that calls the top-level function directly when possible. In our example, we'd replace
Struct::default()
with a call toStruct_default()
. This of course only works when the type is known; for generic types we need to use the trait clauses in scope as usual.This fixes the problem raised in #159, though not the general case of #159.