Description
spawned off of #24728 (comment)
In an example like:
fn main() {
let vs = vec![1, 2, 3, 4];
for v in &vs {
match v {
1 => {}
_ => {}
}
}
}
which yields the error message:
<anon>:4:5: 9:6 error: type mismatch resolving \ (linebreak solely for presentation here)
`<core::slice::Iter<'_, _> as core::iter::Iterator>::Item == _`:
expected &-ptr,
found integral variable [E0271]
<anon>:4 for v in &vs {
<anon>:5 match v {
<anon>:6 1 => {}
<anon>:7 _ => {}
<anon>:8 }
<anon>:9 }
i find it frustrating that the first line prints the integral type variable as just _
.
It is not a completely unconstrained type; it must be some kind of integer.
(It is true that one should be able to figure this out from the third line. But I think we can still do better on the first line itself.)
I am thinking something like this could suffice:
error: type mismatch resolving \
`<core::slice::Iter<'_, _> as core::iter::Iterator>::Item == iN`
Another slightly more verbose option (but less prone to misinterpretation when e.g. unsigned integers are involved, or when the user has defined a type named iN
) would be:
error: type mismatch resolving \
`<core::slice::Iter<'_, _> as core::iter::Iterator>::Item == <int type>`
Yet another option, which is both succinct but will not collide with user definitions (at least not today):
error: type mismatch resolving \
`int? == <core::slice::Iter<'_, _> as core::iter::Iterator>::Item`
and likewise one would imagine for the FloatVar
case
error: type mismatch resolving \
`float? == <core::slice::Iter<'_, _> as core::iter::Iterator>::Item`
I forced the int?
and float?
to be on the left-hand side to ensure that they did not get mistaken for a question mark ending the error message itself. (I did consider ?int
and ?float
but I worry a little that those would get confused with the generalization marker ?Sized
... maybe that is a small price to pay...)
Activity
pnkfelix commentedon Apr 24, 2015
(it might also be interesting to try to just write
core::slice::Iter<'_, _>::Item
when there is no other trait in scope that defines an associated type namedItem
, to further condense this error message to its core. But I digress.)pnkfelix commentedon Apr 24, 2015
also, from #14007 i infer that we used to do better here ? Was it a deliberate choice to stop printing
<generic integer #1>
and print_
instead?pnkfelix commentedon Apr 24, 2015
cc @nikomatsakis
pnkfelix commentedon Apr 24, 2015
Seems like the use of
_
for int-type variables was introduced in commit a2624fc (PR #18264); I am not sure what code paths produced the print outs that @zwarich referenced in #14007pnkfelix commentedon Apr 24, 2015
ah, seems like it was a deliberate choice, based on the argument presented here by @nikomatsakis
But I think that the code in this ticket's description is a strong counter-example to that claim: the failure to unify
&T
with<integral typevar>
is precisely due to the distinction between normal type variables and integral ones.nikomatsakis commentedon Apr 24, 2015
Some thoughts:
pnkfelix commentedon Apr 24, 2015
Another option i just thought of while brainstorming is to print
i32
forinfer_ty(IntVar)
. The argument for doing so is that if we have not yet seen some constraint forces this to be a more specificint
type (e.g.u8
), then there's a good chance that all of the evidence we have so far (and maybe all of the evidence we will ever see in this compilation unit) will still lead us to just apply the integer fallback toi32
.(Likewise, we would print
f64
forinfer_ty(FloatVar)
.)eddyb commentedon Mar 12, 2016
I think we should use "integer type" and "floating-point type" instead of "integral variable" and "floating-point variable".
durka commentedon Aug 23, 2016
I think this can be closed.