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

Make sure type inference with a..b as good as range(a,b) #21806

Merged
merged 2 commits into from
Feb 1, 2015

Conversation

edwardw
Copy link
Contributor

@edwardw edwardw commented Jan 31, 2015

The new ::ops::Range has separated implementations for each of the
numeric types, while the old ::iter::Range has one for type Int.
However, we do not take output bindings into account when selecting
traits. So it confuses typeck and makes the new range does not work as
good as the old one when it comes to type inference.

This patch implements Iterator for the new range for one type Int.
This limitation could be lifted, however, if we ever reconsider the
output types' role in type inference.

Closes #21595
Closes #21649
Closes #21672

@rust-highfive
Copy link
Collaborator

r? @alexcrichton

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

@ghost
Copy link

ghost commented Jan 31, 2015

I am curious what happens with a negative range eg. -1..10
I'll test this with your PR and let you know. Currently started compiling rust locally.

@edwardw
Copy link
Contributor Author

edwardw commented Jan 31, 2015

It should work as expected since after type inference, the numeric fallback will kick in and -1..10 will then be equivalent to -1i32..10.

@bluss
Copy link
Member

bluss commented Jan 31, 2015

Does this still allow impl Iterator for Range<MyLocalType> ? I don't think that's something we require or designed for, but I'm curious nonetheless.

return Some(result);
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Int> ExactSizeIterator for ::ops::Range<A> {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately with the definition as-is I don't think that we can have this ExactSizeIterator impl here. As defined it's possible for size_hint to return (0, None) which goes against the contract of ExactSizeIterator.

While we don't have negative bounds, perhaps the ExactSizeIterator trait could still just be manually defined for each primitive type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, the hybrid implementations for range work!

@edwardw
Copy link
Contributor Author

edwardw commented Jan 31, 2015

Hmm, good question. I think so offhand, as long as Range<T: Int> and Range<MyLocalType> are not considered conflict implementations.

@ghost
Copy link

ghost commented Jan 31, 2015

my local compilation reports this:

test [compile-fail] compile-fail/xc-private-method2.rs ... ok
test [compile-fail] compile-fail/xcrate-private-by-default.rs ... ok

failures:

---- [compile-fail] compile-fail/range-1.rs stdout ----

error: expected error on line 19 not found: `core::iter::Iterator` is not implemented for the type `core::ops::Range<f32>`
status: exit code: 101
command: x86_64-unknown-linux-gnu/stage2/bin/rustc /home/emacs/build/rust/src/test/compile-fail/range-1.rs -L x86_64-unknown-linux-gnu/test/compile-fail --target=x86_64-unknown-linux-gnu -L x86_64-unknown-linux-gnu/test/compile-fail/range-1.stage2-x86_64-unknown-linux-gnulibaux -C prefer-dynamic -o x86_64-unknown-linux-gnu/test/compile-fail/range-1.stage2-x86_64-unknown-linux-gnu --cfg rtopt -O -L x86_64-unknown-linux-gnu/rt
stdout:
------------------------------------------

------------------------------------------
stderr:
------------------------------------------
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:15:13: 15:23 error: start and end of range have incompatible types: expected `usize`, found `isize` (expected usize, found isize) [E0308]
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:15     let _ = 0us..10is;
                                                                       ^~~~~~~~~~
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:19:5: 26:8 error: the trait `core::num::Int` is not implemented for the type `f32` [E0277]
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:19     for i in 0f32..42f32 {}
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:20     //~^ ERROR `core::iter::Iterator` is not implemented for the type `core::ops::Range<f32>`
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:21     //~^^ ERROR
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:22     //~^^^ ERROR
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:23     // FIXME(#21528) not fulfilled obligation error should be reported once, not thrice
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:24 
                                                           ...
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:27:17: 27:24 error: the trait `core::marker::Sized` is not implemented for the type `[usize]` [E0277]
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:27     let range = *arr..;
                                                                           ^~~~~~~
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:27:17: 27:24 note: `[usize]` does not have a constant size known at compile-time
/home/emacs/build/rust/src/test/compile-fail/range-1.rs:27     let range = *arr..;
                                                                           ^~~~~~~
error: aborting due to 3 previous errors

------------------------------------------

thread '[compile-fail] compile-fail/range-1.rs' panicked at 'explicit panic', /home/emacs/build/rust/src/compiletest/runtest.rs:1458



failures:
    [compile-fail] compile-fail/range-1.rs

test result: FAILED. 1643 passed; 1 failed; 22 ignored; 0 measured

thread '<main>' panicked at 'Some tests failed', /home/emacs/build/rust/src/compiletest/compiletest.rs:252
/home/emacs/build/rust/mk/tests.mk:729: recipe for target 'tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-cfail.ok' failed
make: *** [tmp/check-stage2-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-cfail.ok] Error 101


The new `::ops::Range` has separated implementations for each of the
numeric types, while the old `::iter::Range` has one for type `Int`.
However, we do not take output bindings into account when selecting
traits. So it confuses `typeck` and makes the new range does not work as
good as the old one when it comes to type inference.

This patch implements `Iterator` for the new range for one type `Int`.
This limitation could be lifted, however, if we ever reconsider the
output types' role in type inference.

Closes rust-lang#21595
Closes rust-lang#21649
Closes rust-lang#21672
@edwardw
Copy link
Contributor Author

edwardw commented Feb 1, 2015

Thanks @emanueLczirai, the fallout has been fixed.

@edwardw
Copy link
Contributor Author

edwardw commented Feb 1, 2015

r? @alexcrichton

@ghost
Copy link

ghost commented Feb 1, 2015

Compiles successfully for me now. Thanks! (and numeric fallback is as you said earlier: i32)

One question: is that commented FIXME that you removed no longer necessary there? as in, is it fixed or no longer makes sense due to this PR?

@edwardw
Copy link
Contributor Author

edwardw commented Feb 1, 2015

It is simply not there any more. I doubt it has anything to do with this PR though.

@alexcrichton
Copy link
Member

@bors: r+ b9c055c

Thanks!

@bors
Copy link
Contributor

bors commented Feb 1, 2015

⌛ Testing commit b9c055c with merge c2bda2a...

bors added a commit that referenced this pull request Feb 1, 2015
The new `::ops::Range` has separated implementations for each of the
numeric types, while the old `::iter::Range` has one for type `Int`.
However, we do not take output bindings into account when selecting
traits. So it confuses `typeck` and makes the new range does not work as
good as the old one when it comes to type inference.

This patch implements `Iterator` for the new range for one type `Int`.
This limitation could be lifted, however, if we ever reconsider the
output types' role in type inference.

Closes #21595
Closes #21649
Closes #21672
@bors bors merged commit b9c055c into rust-lang:master Feb 1, 2015
@edwardw edwardw deleted the new-range-impl branch February 2, 2015 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants