You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ICE due to ambiguity between impl and where-clause #22110
use std::vec::Vec;use std::iter::Iterator;use std::slice::{AsSlice,Split,SliceExt};pubstructPath{repr:Vec<u8>,// assumed to never be empty or contain NULs}pubtypeComponents<'a> = Split<'a,u8,fn(&u8) -> bool>;pubfnis_sep_byte(u:&u8) -> bool{true}implPath{fncomponents<'a>(&'aself) -> Components<'a>where fn(&u8) -> bool:FnMut(&u8) -> bool{let v = &self.repr[1..];let is_sep_byte:fn(&u8) -> bool = is_sep_byte;// coerce to fn ptrletmut ret = v.split(is_sep_byte);if v.is_empty(){
ret.next();}
ret
}}fnmain(){}
fails with
<anon>:21:25: 21:43 error: internal compiler error: coherence failed to report ambiguity: cannot locate the impl of the trait `for<'r> core::ops::FnMut<(&'r u8,)>` for the type `fn(&u8) -> bool`
<anon>:21 let mut ret = v.split(is_sep_byte);
^~~~~~~~~~~~~~~~~~
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libsyntax/diagnostic.rs:129
playpen: application terminated with error code 101
Program ended.
This is because the compiler considers both the bridging impl from Fn to FnMut is an option and the where-clause to be valid options. Choosing between where-clauses and impls seems to be tricky.
At minimum, the code that checks for overlap between the where-clause and the impl seems to have the subtyping relationship backwards. However, I am not sure whether it's a good idea to check anything, or maybe better to simply always prefer where-clauses.
use std::vec::Vec;use std::iter::Iterator;use std::slice::{AsSlice,Split,SliceExt};structPath;traitFoo<A>{fnfoo(&self,a:A);}impl<A,F:Fn(A)>Foo<A>forF{fnfoo(&self,a:A){}}fnbaz<F:for<'a>Foo<(&'aPath,)>>(f:F){}implPath{fncomponents<T>(&self,t:fn(&Path))where fn(&Path):for<'a>Foo<(&'aPath,)>,{baz(t)}}fnmain(){}
That version only works because we don't seem to be enforcing the rules against where-clauses with no type parameters fully. This alternate version also fails to compile but obeys those rules:
use std::vec::Vec;use std::iter::Iterator;use std::slice::{AsSlice,Split,SliceExt};structPath;traitFoo<A>{fnfoo(&self,a:A);}impl<A,F:Fn(A)>Foo<A>forF{fnfoo(&self,a:A){}}fnbaz<A,F:for<'a>Foo<(&'aA,)>>(f:F){}fncomponents<T,A>(t:fn(&A))where fn(&A):for<'a>Foo<(&'aA,)>,{baz(t)}fnmain(){}
but the error is different:
traits-issue-22110.rs:34:5: 34:8 error: unable to infer enough type information about `_`; type annotations required [E0282]
use std::slice::Iter;fnfoo<'a,T>(v:Iter<'a,T>) -> Option<T>whereIter<'a,T>:Iterator{
v.next()}fnmain(){}
Here the explicit where clause matches, interfering with later attempts to project the type Item, and hence we get:
<anon>:6:5: 6:13 error: mismatched types:
expected `core::option::Option<T>`,
found `core::option::Option<<core::slice::Iter<'a, T> as core::iter::Iterator>::Item>`
(expected type parameter,
found associated type) [E0308]
<anon>:6 v.next()
^~~~~~~~
error: aborting due to previous error
playpen: application terminated with error code 101
The fix in #22407 is simply to always allow where clauses to override impls. This seems like a conservative step -- everything where clauses tell you must be derived from an impl, after all. In he future, I'd like to improve the engine so that it can take advantage of impls as well to possibly glean more information than the where-clause is telling us, but it's tricky, because impls have preconditions.
Activity
nikomatsakis commentedon Feb 9, 2015
A more standalone version of that test:
nikomatsakis commentedon Feb 9, 2015
That version only works because we don't seem to be enforcing the rules against where-clauses with no type parameters fully. This alternate version also fails to compile but obeys those rules:
but the error is different:
nikomatsakis commentedon Feb 9, 2015
A related example:
Here the explicit where clause matches, interfering with later attempts to project the type
Item, and hence we get:jroesch commentedon Feb 9, 2015
cc me
nikomatsakis commentedon Feb 16, 2015
The fix in #22407 is simply to always allow where clauses to override impls. This seems like a conservative step -- everything where clauses tell you must be derived from an impl, after all. In he future, I'd like to improve the engine so that it can take advantage of impls as well to possibly glean more information than the where-clause is telling us, but it's tricky, because impls have preconditions.
Always prefer where-clauses over impls in trait selection. Fixes rust…
rollup merge of rust-lang#22436: nikomatsakis/issue-22246-bound-lifet…
Merge pull request rust-lang#22110 from lnicola/sync-from-rust