I just got this friendly error message:
24 | Int64.(to_int32 (logand b64 0xFFFFFFFF))
^^^^^^^^^^
Error: This expression has type int but an expression was expected of type
int64
Hint: Did you mean `4294967295L'?
The hint is correct , but it would be more helpful if instead it said:
Hint: Did you mean `0xFFFFFFFFL'?
I was just about to file a bug for this on the ocaml/ocaml
GitHub repo, then I realised that it’s perhaps not 100% clear cut – the hint is correct, it’s just that for my purposes, it would be more useful if it used the original notation (hexadecimal).
Is this a bug or a feature request?
Given it is still correct I don’t think this is a bug, but this would be a worthwhile feature request indeed.
2 Likes
Great, thanks for the guidance! I have filed the feature request here:
opened 12:44PM - 14 Nov 21 UTC
closed 06:34PM - 14 Jul 22 UTC
feature-wish
# Context
There's code in `typecore.ml` to output a helpful hint in case some… one forgets to add the appropriate suffix to a number literal. As far as I can tell, this hint always uses decimal notation stripped of any underscores.
That is fine if the original literal was in decimal and without underscores:
```
File "hints.ml", line 1, characters 16-18:
1 | let _ : int32 = 11
^^
Error: This expression has type int but an expression was expected of type
int32
Hint: Did you mean `11l'?
```
If the original literal is in decimal but with underscores, those are dropped:
```
File "hints.ml", line 1, characters 16-21:
1 | let _ : int32 = 1_000
^^^^^
Error: This expression has type int but an expression was expected of type
int32
Hint: Did you mean `1000l'?
```
If the original literal was expressed in another base, the hint gets a bit confusing: especially as the number gets large, it is not immediately obvious how the hint relates to the original literal:
```
File "hints.ml", line 1, characters 16-19:
1 | let _ : int32 = 0xB
^^^
Error: This expression has type int but an expression was expected of type
int32
Hint: Did you mean `11l'?
```
Perhaps it is clear that `0xB` and `11` mean the same thing, but how about if the original literal was `0xFFFFFFFF` and the type hint says something about `4294967295L`?
The following simply confirm that octal and binary literals are translated to decimal notation in the hint as well:
```
File "hints.ml", line 1, characters 16-20:
1 | let _ : int32 = 0o13
^^^^
Error: This expression has type int but an expression was expected of type
int32
Hint: Did you mean `11l'?
```
```
File "hints.ml", line 1, characters 16-22:
1 | let _ : int32 = 0b1011
^^^^^^
Error: This expression has type int but an expression was expected of type
int32
Hint: Did you mean `11l'?
```
# Proposal 1
I think that ideally, the way the literal is rendered in the hint should be the same as in the original literal. I'm using `int32` in these examples, the formatting should be preserved for `in64` and `nativeint` in the same way:
- `let _ : int32 = 11` should hint at `11l` as currently
- `let _ : int32 = 1_000` should hint at `1_000l` (and underscores preserved for hexadecimal, octal and binary notation too)
- `let _ : int32 = 0xB` should hint at `0xBl`
- `let _ : int32 = 0o13` should hint at `0x13l`
- `let _ : int32 = 0b1011` should hint at `0b1011l`
# Proposal 2
As a step towards formatting the hint more closely to how the original literal was formatted, it would help if the base was preserved even if underscores are dropped.
# Proposal 3
As a very first step, if the hint included _all_ notations, that may also be an improvement over the status quo. But it may also be the case that this could confuse people.
Something along the lines of:
```
File "hints.ml", line 1, characters 16-22:
1 | let _ : int32 = 0b1011
^^^^^^
Error: This expression has type int but an expression was expected of type
int32
Hint: Did you mean `11l'?
(Alternative notations: `0xBl', `0o13l', `0b1101l')
```
1 Like