-
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
Allow autoderef and autoref in operators #2147
Closed
Closed
Changes from 1 commit
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
80d4ce9
Eye of sauron
arielb1 a605a22
V2
arielb1 910b876
fiixed
arielb1 5f5d214
improvements
arielb1 eb55528
clarify
arielb1 0fbad4b
clarify
arielb1 9373938
Fix markdown
e1a2624
more method lookup details + examples
arielb1 fd05a42
finish eye of sauron example
arielb1 d666bed
readability
arielb1 15de261
adjustment list/adjustment -> adjustment/adjustment step
arielb1 df42b1d
document method dispatch
arielb1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,35 +74,33 @@ Like methods, operators and indexing support automatic referencing and dereferen | |
|
||
Operator type-checking behaves similarly to method type-checking. It works as follows: | ||
|
||
## S1. Subexpression checking | ||
## Step 1 - Subexpression checking | ||
|
||
Both the LHS and the RHS (if binary) of the operator are first type-checked with no expected type. | ||
|
||
This differs from rustc 1.20, in which an expected type was sometimes propagated from the LHS into the RHS, potentially triggering coercions within the RHS. I should probably come up with an example in which this matters. | ||
|
||
## S2. Adjustment selection | ||
## Step 2 - Adjustment selection | ||
|
||
Afterwards, an adjustment list is selected for both operands as follows: | ||
|
||
Adjustment lists for the LHS of an indexing operation are selected from these matching the following regular expression: | ||
Adjustment lists for the LHS of an indexing operator (the `X` in `X[Y]`) are selected from these matching the following regular expression: | ||
``` | ||
"Deref"* "Autoref(Immutable)" "ConvertArrayToSlice"? | ||
``` | ||
|
||
Adjustment lists for all other operands (including the RHS of indexing operations) are selected from these matching the following regular expression | ||
Adjustment lists for all other operands (including the RHS of indexing operator, as well as all operands of all other operators) are selected from these matching the following regular expression | ||
``` | ||
"Deref"* ( "Autoref(Immutable)" "ConvertArrayToSlice"? )? | ||
``` | ||
|
||
The adjustment lists selected are the lexicographically first pair of adjustment lists `(lhs_adjust, rhs_adjust)` (or with an unary op, just the `lhs_adjust`) such that | ||
A1. Both adjustment lists match the relevant regular expressions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fwiw this list does not render well in markdown. Perhaps add some bullets? |
||
A2. Both adjustment lists must be valid to apply to their operand types. | ||
A2. Both adjustment lists must be valid to apply to their operand types. If, due to the presence of inference variables, it can't be determined whether these adjustment lists would be valid to apply, and we didn't find a smaller adjustment list that would apply, that is a compilation error (this is the "can't autoderef because of inference variables" case). | ||
A3. After applying both adjustment lists, the adjusted operand types are a potential match for the operator trait (if there is an ambiguity because of inference variables, it is counted as a match). | ||
A3.1. NOTE: the operator trait for overloaded indexing is `Index`, not `IndexMut`, even if indexing is done in a mutable context. rustc 1.20 is inconsistent in that regard. | ||
|
||
If the smallest adjustment can't be determined because of the presence of inference variables (because it is not obvious whether an adjustment list would be valid to apply), this is a compilation error. | ||
|
||
## S3. Fixups | ||
## Step 3 - Fixups | ||
|
||
After adjustments are selected, the following fixups are made. They do not affect adjustment selection. | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This one's probably a crazy example, but the RHS is definitely dependent on the LHS and the case is rather horrible:
This needs the
&
for $reasonsFound in rust-lang/rust-clippy#2042
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.
That's a trait-system issue. Operator overloading does succeed in this case. Without the autoref, you get these trait bounds:
Because the compiler only considers each trait bound alone, it can't see that the only solution is
$0 = u16
.If you add a reference, instead yoou get
And on the first bound, only the
impl Add<&u16> for u16
impl matches, which allows a solution.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.
This also won't coerce:
&1 + &mut 1
. As soon as you have two different implementations for the RHS it stops working. That coercion only fires in such rare situations that I wonder if it's existence is by design or an accident of implementation.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.
In any case it's orthogonal to this RFC.