-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Primitive vs struct antipattern? #72199
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
Comments
The slice version does mut dereference first. So the struct behavior between slice and vec both deref the left-hand side then the right-hand side. Slice doesn't call Index or IndexMut though, it dereferences directly from the slice. I'm sure there is some desugaring going on to cause the behavior, but I'm not sure it should work this way? |
Someone in an IRLO discussion pointed here. Here’s a full explanation. First, as (thankfully documented) by the reference, there is a special case with regards to order-of-evaluation for operators like
The second piece to the equation is two-phase borrows. I couldn’t find anything about them in the reference, but here’s an explanation in the rustc development guide. Two-phase borrows are a more permissive version of mutable borrows that allow nested method calls such as
So the reference is slightly inaccurate about the The third piece of information is that slice’s indexing operation is compiler-implemented while Now, to explain the three cases.
|
This is coming from a stack overflow question.
My answer didn't sit well with me. While it's true that the
add_assign
isn't called in the primitive case, the fact that it's called shouldn't cause a compilation failure because the Vec isn't being passed in.The below fails to compile:
With this message:
However this works:
Looking at the MIR, the only difference I can see is in the primitive case Index is called before IndexMut whereas in the struct case that is reversed. I don't see why the struct needs to behave differently.
I expected to see this happen: the primitive case and the struct case should either both fail or both succeed. In my mind, they should both succeed as the dereference for
b[1]
can complete beforeb[0]
.If the mutable struct needs to exist first for some reason then the slice version should also fail, but this works:
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: