Repository navigation
overflowing_literals error is confusing because of type inference #79744
Description
Activity
- addedC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Dec 5, 2020 e2also has typei8, because you push it onto the sameVecaselem, so the error message is correct – the literal is out of range for the target typei8While that is true (and as I mentioned, I do not expect this to work) the problem is the error reported by the compiler doesn't help the user resolve the problem. In a small example like this it's easy to see where the problem lies but in a larger one the compiler error would send the user in the wrong direction.
okay, marking as a diagnostics enhancement
- addedA-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.and removedC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
on Dec 5, 2020 - addedA-inferenceArea: Type inferenceArea: Type inferenceE-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.Call for participation: Hard difficulty. Experience needed to fix: A lot.
on Dec 5, 2020 I'm guessing this would be hard to implement since we'd need to somehow track the spot(s) that caused us to infer a particular type.
5 remaining items
Reposting my idea from Zulip:
Perhaps we could store something in the
TyCtxtorSessthat maps every AST node to its "inference source". There would be a structInferenceSourcethat would hold the spans that caused this node to be inferred to be a particular type:pub struct InferenceSource { pub source_spans: Vec<Span>, }
Over time we could add more fields if we wanted more detailed diagnostics.
I'm not sure how feasible that is, but seems potentially possible.
One thing we'd need to figure out is when and how much to show of the inference-source stack. In some situations, it may not be helpful, and in others it may be too much information.
In the first example, all the compiler knows is that
e2is an integer, so when it sees you push it into what it's inferred to be aVec<i8>, it says "OK! I guesse2must be ani8".This had me confused for a bit as well, i.e. I'm first pushing e2 onto the Vector so I thought it would infer it to be
Vec<i32>and then complain about adding thei8but I guess the inference engine builds some kind of constraint model and uses thei8even though it is pushed second because thee2literal is not explicitly typed.I experimented with
let e2 = 2300;andlet e2 = 2300i16;and in the first case it again reportsliteral out of range for 'i8'while in the second it reportsmismatched typesso I think I understand the inference model a little better!One thing we'd need to figure out is when and how much to show of the inference-source stack. In some situations, it may not be helpful, and in others it may be too much information.
From an end-user perspective I couldn't follow much of what you said but if the diagnostic was to point to the line where the element was pushed (or otherwise used in a manner that causes a type mismatch) and not where it has its value set, that would be better.
I experimented with let e2 = 2300; and let e2 = 2300i16;
I think this suggests an inexpensive way forward for a diagnostic here: suggest that they add a suffix and recompile. For example, it could see the
230and say something like "help: if you're unsure why it was inferred asi8, try changing it to230_u8and seeing where you get a type error". (Of course, if it's already suffixed, like300_u8, then it shouldn't suggest that.)That’s a good idea! :)
- addedE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.Call for participation: Medium difficulty. Experience needed to fix: Intermediate.and removedE-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.Call for participation: Hard difficulty. Experience needed to fix: A lot.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
on Dec 11, 2020 - added 2 commits that reference this issue
on Feb 16, 2021 - added a commit that references this issue
on Feb 17, 2021
While experimenting with the Rust By Example playground on the Inference section at https://doc.rust-lang.org/stable/rust-by-example/types/inference.html I came across what I believe is an error in the error produced by the compiler.
I do not expect this example to work but the error
literal out of range for 'i8'is reported against line 4let e2 = 230;which is a perfectly valid statement. The problem is lower down where two different types are pushed onto the same Vector but possibly due to the way the inference engine works this is being incorrectly reported against line 4. If I comment out the linevec.push(e2);, the example works fine, apart from awarning: unused variable: 'e2'.Code
Meta
rustc --version --verbose: I am unable to determine the exact compiler version in the Rust By Example playground. I have run the same example on my Fedora 32 Workstation machine and with the same result. The rustc version details for this machine are as followsError output
Backtrace
Sorry I don't know exactly how to provide this.