-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add std::ops::Index support for infering #2592
Conversation
cc @flodiebold |
Seem like this PR itself is not enough to prove all trait associated types for impl<T, I> ops::Index<I> for [T]
where I: SliceIndex<[T]>
{
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &I::Output {
index.index(self)
}
} |
I have some input on the issue of the example and a little on the new
helper func, but currently stuck in public transit so it will be an hour or
so :)
…On Thu, 19 Dec 2019, 06:47 Edwin Cheng, ***@***.***> wrote:
Seem like this PR is not enough to prove all trait associated types for
[T] impl for std::ops::Index ?
impl<T, I> ops::Index<I> for [T]
where I: SliceIndex<[T]>
{
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &I::Output {
index.index(self)
}
}
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#2592>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABTDKPQVZRGNMHQWQVHCUTQZMDGNANCNFSM4J427GCA>
.
|
As for the issue with the example above, the problem is two-fold:
|
Also just thought of the following: Once this is in place it can be trivially copied and adapted to handle custom BinOp implementations! |
r? @flodiebold
See #1694 (comment). I think index is different from other binops in this case, but I might be mistaken. |
Ahh you've had the same thought already :) Right, that conclusion does make some sense, keeping it seperate seems like it will remove a layer of enum matching when handling |
@kiljacken And I found that the following case do not work too and I don't know how to add that struct Bar;
struct Foo;
trait IndexWithOutput {
type Output;
}
impl IndexWithOutput for u32 {
type Output = Foo;
}
impl<T:IndexWithOutput> std::ops::Index<T> for Bar {
type Output = T::Output;
}
fn test() {
let a = Bar;
let b = a[1];
b<|>;
} |
Without investigating in detail, I'd suspect rust-lang/chalk#234 for this. As I mentioned in #2454, that bug sadly prevents associated type normalization from working in a lot of non-trivial cases. Of course it could very well be something else, but I'm currently a bit reluctant to investigate associated type issues deeply because of it...
Hmm, actually this probably also does autoref, right? Should it be handled like method resolution? (It took quite a bit of care to get the order in which candidates are considered right there...) I haven't actually checked how rustc handles this... (does it lower to a method call, or just share method resolution code, or do something completely separate?) As for autoderef, basically you just call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Actually, this might be a really complicated case... The |
I just added it as an expectation on the infer of the inner expr in my initial attempt at this, that seemed to do the trick, although I'm not quite sure if it was "correct". |
If you mean adding an expectation of |
Oh right, hadn't considered that. That does indeed seem like a great can of worms |
I just checked, it do not works even without struct Bar;
struct Foo;
struct Baz;
trait IndexWithOutput {
type Output;
}
impl IndexWithOutput for Baz {
type Output = Foo;
}
impl<T:IndexWithOutput> std::ops::Index<T> for Bar {
type Output = T::Output;
fn index(&self, _index: T) -> &Self::Output { unimplemented!() }
}
fn main() {
let a = Bar;
let c = Baz;
let b = a[c]; // b is unknown
} |
Yeah, I don't think we'll get this working right now, but we should still merge this. Although I guess we could detect when the parameter is an int variable and try using |
@flodiebold, indeed. I just opened another issue to tracking part of it. |
The librustc_typeck source seems to point some light on it being a bit different from method handling, and quite an ordeal! |
@edwin0cheng I'd be fine with r+ing this, unless you first want to try getting autoderef working? |
@flodiebold Um.. I want to wait for rust-lang/chalk#234 to be fixed before implementing autodref working. |
bors r+ |
2592: Add std::ops::Index support for infering r=edwin0cheng a=edwin0cheng see also #2534 Seem like this can't fix #2534 for this case: ```rust fn foo3(bar: [usize; 2]) { let baz = bar[1]; // <--- baz is still unknown ? println!("{}", baz); } ``` Co-authored-by: Edwin Cheng <[email protected]>
Build succeeded
|
see also #2534
Seem like this can't fix #2534 for this case: