Skip to content
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

Generalize binary operators #23673

Merged
merged 5 commits into from Mar 30, 2015

Conversation

Projects
None yet
8 participants
@nikomatsakis
Copy link
Contributor

nikomatsakis commented Mar 24, 2015

The current binary operator code assumed that if the LHS was a scalar (i32 etc), then the RHS had to match. This is not true with multidispatch. This PR generalizes the existing code to (primarily) use the traits -- this also allows us to defer the precise type-checking when the types aren't fully known. The one caveat is the unstable SIMD types, which don't fit in with the current traits -- in that case, the LHS type must be known to be SIMD ahead of time.

There is one semi-hacky bit in that during writeback, for builtin operators, if the types resolve to scalars (i32 etc) then we clear the method override. This is because we know what the semantics are and it is more efficient to generate the code directly. It also ensures that we can use these overloaded operators in constants and so forth.

cc @japaric
cc @aturon

Fixes #23319 (and others).

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Mar 24, 2015

r? @pnkfelix

(rust_highfive has picked a reviewer for you, use r? to override)

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 24, 2015

hmm the rebase is encountering a problem, I may push a tweaked version soon

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Mar 24, 2015

Huzzah!

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 24, 2015

OK, things are looking good locally. I'll push a revised version shortly that passes make check.

@nikomatsakis nikomatsakis force-pushed the nikomatsakis:issue-23319-binops-ng-5 branch 2 times, most recently from 1c310fb to e4fcdea Mar 25, 2015

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 25, 2015

For some odd reason I see a failure locally in the tempfile test. I think this a local problem though.

@nikomatsakis nikomatsakis force-pushed the nikomatsakis:issue-23319-binops-ng-5 branch from e4fcdea to 82fdbdb Mar 25, 2015

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 25, 2015

oh and cc @eddyb -- this changed the flow around coercions a bit, though nothing that should really affect you

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 25, 2015

@bors try

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Mar 25, 2015

⌛️ Trying commit 82fdbdb with merge 05f83b9...

bors added a commit that referenced this pull request Mar 25, 2015

Auto merge of #23673 - nikomatsakis:issue-23319-binops-ng-5, r=<try>
The current binary operator code assumed that if the LHS was a scalar (`i32` etc), then the RHS had to match. This is not true with multidispatch. This PR generalizes the existing code to (primarily) use the traits -- this also allows us to defer the precise type-checking when the types aren't fully known. The one caveat is unstable SIMD types, which don't fit in with the current traits -- in that case, the types must be known ahead of time.

There is one semi-hacky bit in that during writeback, for builtin operators, if the types resolve to scalars (i32 etc) then we clear the method override. This is because we know what the semantics are and it is more efficient to generate the code directly. It also ensures that we can use these overloaded operators in constants and so forth.

cc @japaric
cc @aturon 

Fixes #23319 (and others).
@bors

This comment has been minimized.

Copy link
Contributor

bors commented Mar 25, 2015

💔 Test failed - try-bsd

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Mar 25, 2015

☔️ The latest upstream changes (presumably #23681) made this pull request unmergeable. Please resolve the merge conflicts.

@nikomatsakis nikomatsakis force-pushed the nikomatsakis:issue-23319-binops-ng-5 branch 2 times, most recently from 40f1d55 to 5265d57 Mar 25, 2015

map.insert(i, i);
}

// measure
b.iter(|| {
let k = rng.gen() % n;
let k = rng.gen::<usize>() % n;

This comment has been minimized.

@tbu-

tbu- Mar 25, 2015

Contributor

This should likely not be usize.

This comment has been minimized.

@nikomatsakis

nikomatsakis Mar 25, 2015

Author Contributor

Hmm, I presume because that would alter what is being tested when run on 32-bit and 64-bit systems? Makes sense. I can change to u32.

@nikomatsakis nikomatsakis force-pushed the nikomatsakis:issue-23319-binops-ng-5 branch from 5265d57 to 1dbddda Mar 25, 2015

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Mar 25, 2015

@nikomatsakis don't run the tempfile test with RUST_BACKTRACE=1, that breaks it IME.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 25, 2015

@eddyb ah, that might indeed be the problem...

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Mar 25, 2015

We should consider trying to remove that fragility, perhaps in a similar manner that run-pass/backtrace.rs does

@@ -23,4 +23,6 @@ fn main() {
unsafe { libc::exit(0 as libc::c_int); }
});
2_usize + (loop {});
//~^ ERROR E0277

This comment has been minimized.

@pnkfelix

pnkfelix Mar 25, 2015

Member

Hmm. I don't think you should have moved this test into compile-fail.

Were you intending to make a copy of it?

Could you fix the test by explicitly forcing the type of the looping expression, e.g.:

(2 + { let x: i8 = loop { }; x });

This comment has been minimized.

@pnkfelix

pnkfelix Mar 25, 2015

Member

(this was supposed to be a comment on commit f8a658c ; maybe its resolved in follow-on commits.)

This comment has been minimized.

@pnkfelix

pnkfelix Mar 25, 2015

Member

(of course it might be even nicer to not require the type annotation at all, since after all the addition is an unreachable expression in the control flow. but I'd be satisfied with an annotation rather than trying to go further.)

This comment has been minimized.

@nikomatsakis

nikomatsakis Mar 25, 2015

Author Contributor

ok, let me try that

pnkfelix referenced this pull request in nikomatsakis/rust Mar 25, 2015

Driveby cleanup of the impl for negation, which had some kind of
surprising casts. This version more obviously corresponds to the builtin
semantics.

pnkfelix referenced this pull request in nikomatsakis/rust Mar 25, 2015

Implement new type-checking strategy for binary operators. Basically,
the plan is to treat all binary operators as if they were overloaded,
relying on the fact that we have impls for all the builtin scalar
operations (and no more). But then during writeback we clear the
overload if the types correspond to a builtin op.

This strategy allows us to avoid having to know the types of the
operands ahead of time. It also avoids us overspecializing as we did in
the past.
@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Mar 25, 2015

@nikomatsakis okay. Overall I think this is a nice cleanup compared to the previous code.

its mostly just a bunch of questions from me. Along with a few things that might have been mistakes on your part; hopefully its clear from the comments.

You can r=me (preferably after addressing the review notes, though).

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 25, 2015

@pnkfelix the problem with lang-item-public had to do with the fact that there are no impls for Add, so you get type errors in the end iirc. I did debate about that for a while. I guess I could bring in the Add trait to keep the original code.

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Mar 28, 2015

☔️ The latest upstream changes (presumably #23796) made this pull request unmergeable. Please resolve the merge conflicts.

Implement new type-checking strategy for binary operators. Basically,
the plan is to treat all binary operators as if they were overloaded,
relying on the fact that we have impls for all the builtin scalar
operations (and no more). But then during writeback we clear the
overload if the types correspond to a builtin op.

This strategy allows us to avoid having to know the types of the
operands ahead of time. It also avoids us overspecializing as we did in
the past.

nikomatsakis added some commits Mar 24, 2015

Driveby cleanup of the impl for negation, which had some kind of
surprising casts. This version more obviously corresponds to the builtin
semantics.
Fallout where types must be specified.
This is due to a [breaking-change] to operators. The primary affected
code is uses of the `Rng` trait where we used to (incorrectly) infer the
right-hand-side type from the left-hand-side, in the case that the LHS
type was a scalar like `i32`. The fix is to add a type annotation like
`x + rng.gen::<i32>()`.
Add test case for #22743.
Fixes #22743.
Fixes #19035.
Fixes #22099.

(Those all seem to be exactly the same scenario.)

@nikomatsakis nikomatsakis force-pushed the nikomatsakis:issue-23319-binops-ng-5 branch from 1dbddda to 7595c25 Mar 30, 2015

@nikomatsakis

This comment has been minimized.

Copy link
Contributor Author

nikomatsakis commented Mar 30, 2015

@bors r=pnkfelix 7595c25

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Mar 30, 2015

⌛️ Testing commit 7595c25 with merge 9de34a8...

bors added a commit that referenced this pull request Mar 30, 2015

Auto merge of #23673 - nikomatsakis:issue-23319-binops-ng-5, r=pnkfelix
The current binary operator code assumed that if the LHS was a scalar (`i32` etc), then the RHS had to match. This is not true with multidispatch. This PR generalizes the existing code to (primarily) use the traits -- this also allows us to defer the precise type-checking when the types aren't fully known. The one caveat is the unstable SIMD types, which don't fit in with the current traits -- in that case, the LHS type must be known to be SIMD ahead of time.

There is one semi-hacky bit in that during writeback, for builtin operators, if the types resolve to scalars (i32 etc) then we clear the method override. This is because we know what the semantics are and it is more efficient to generate the code directly. It also ensures that we can use these overloaded operators in constants and so forth.

cc @japaric
cc @aturon 

Fixes #23319 (and others).

@bors bors merged commit 7595c25 into rust-lang:master Mar 30, 2015

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@andersk

This comment has been minimized.

Copy link
Contributor

andersk commented Mar 31, 2015

This necessitated extra type annotations in the rand library (rust-random/rand#38, rust-random/rand#39); is that intentional?

@andersk

This comment has been minimized.

Copy link
Contributor

andersk commented Mar 31, 2015

Oh, I guess it must be, since c92bdcb made the same change to rustc’s internal copy of rand.

andersk added a commit to andersk/nalgebra-rs that referenced this pull request Mar 31, 2015

Add type annotation required by rustc 2015-03-31
Resolves this error, which is fallout from
rust-lang/rust#23673:

src/structs/dmat.rs:501:43: 501:74 error: type annotations required: cannot resolve `<f64 as core::ops::Div<_>>::Output == f64` [E0284]
src/structs/dmat.rs:501         let normalizer: N    = Cast::from(1.0f64 / Cast::from(self.nrows));
                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Anders Kaseorg <andersk@mit.edu>

andersk added a commit to andersk/nalgebra-rs that referenced this pull request Mar 31, 2015

Add type annotation required by rustc 2015-03-31
Resolves this error, which is fallout from
rust-lang/rust#23673:

src/structs/dmat.rs:501:43: 501:74 error: type annotations required: cannot resolve `<f64 as core::ops::Div<_>>::Output == f64` [E0284]
src/structs/dmat.rs:501         let normalizer: N    = Cast::from(1.0f64 / Cast::from(self.nrows));
                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Anders Kaseorg <andersk@mit.edu>

SSheldon added a commit to SSheldon/rust-objc that referenced this pull request Apr 2, 2015

Updated for generalized binary operators.
Type inference with operators was changed in rust-lang/rust#23673.

@nikomatsakis nikomatsakis deleted the nikomatsakis:issue-23319-binops-ng-5 branch Mar 30, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.