Skip to content

Add a hint suggesting to use ! when a 'a ref is provided but a 'a was expected#1542

Closed
Armael wants to merge 4 commits intoocaml:trunkfrom
Armael:missing_bang_explanation
Closed

Add a hint suggesting to use ! when a 'a ref is provided but a 'a was expected#1542
Armael wants to merge 4 commits intoocaml:trunkfrom
Armael:missing_bang_explanation

Conversation

@Armael
Copy link
Copy Markdown
Member

@Armael Armael commented Dec 22, 2017

This is an other small bit extracted from #102 . This PR adds a hint "did you forget to use !" as an explanation for a type mismatch between 'a ref and 'a.

let r = ref 1 in print_int r;;
                           ^
Error: This expression has type int ref
       but an expression was expected of type int
       Hint: Did you forget to use `!' to get the content of a reference somewhere?

The first commit is as one might expect.
I'm less confident about the way the second commit is implemented. The idea is to disable the hint in the following case:

type t = { x : int };;
{ x = 3; contents = 0 };;
Error: The record field contents belongs to the type 'a ref
       but is mixed here with fields of type t

This case appears in the explanation function as a mismatch between 'a ref and t (for label contents), but for a label mismatch the ! hint obviously does not make sense.

The current patch does disable the hint in that case, but it feels a bit hackish.

@Armael Armael changed the title Add a hint suggesting using ! when a 'a ref is provided but a 'a was expected Add a hint suggesting to use ! when a 'a ref is provided but a 'a was expected Dec 22, 2017
@Drup
Copy link
Copy Markdown
Contributor

Drup commented Dec 22, 2017

While I like the idea (I haven't look at the implementation yet), one thing I'm a bit worried is the case where ! is redefined (which some library do). You could argue that only advanced library play this kind of tricks, and their user don't need the hint to begin with, but that's not extremely convincing.

Is it possible to check that ! in the environment at the point of the type error is indeed the one that has type 'a ref -> 'a. It's a bit ad-hoc, but well, that's the whole idea to begin with.

@Armael
Copy link
Copy Markdown
Member Author

Armael commented Dec 22, 2017

Good point. What should we do if it turns out ! has been redefined? I see two options: either (1) print nothing; or (2) suggest explicitly using Pervasives.(!) instead of !.

@hcarty
Copy link
Copy Markdown
Member

hcarty commented Dec 23, 2017

The message could also suggest x.Pervasives.contents

@objmagic
Copy link
Copy Markdown
Contributor

objmagic commented Dec 23, 2017

check that ! in the environment at the point of the type error is indeed the one that has type 'a ref -> 'a

Just to be pedantic here, 'a ref can also be redefined.

@Armael Armael force-pushed the missing_bang_explanation branch from 4da70c2 to 8a0bbd1 Compare December 24, 2017 14:36
@Armael
Copy link
Copy Markdown
Member Author

Armael commented Dec 26, 2017

I added a commit that disambiguates ! (by printing Pervasives.(!) instead) if it has been shadowed.

@Armael Armael force-pushed the missing_bang_explanation branch from 8a0bbd1 to 90d3079 Compare January 14, 2018 14:34
@Armael
Copy link
Copy Markdown
Member Author

Armael commented Jan 14, 2018

Any news about this? I think I implemented the suggestions above (I think this still needs review tho, especially wrt the hack mentioned in my initial post).

@Armael Armael closed this Jan 14, 2018
@Armael Armael reopened this Jan 14, 2018

let is_ref_path p =
match p with
| Pdot (Pident id, "ref", _) -> Ident.same id ident_pervasives
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe that is whatnon_shadowed_pervasive is for, and it's more compatible with the Stdlib PR.

longident lid expected provided
| Label_mismatch(lid, trace) ->
report_unification_error ppf env trace
~explain_mismatch:false
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, this commit disables all explanations for mismatched labels (ie., wrongly used record fields). This is much more than what the commit message says, and I'm not sure why this was done at all. Do you have a example where the explanation end up wrong for record fields?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See the second part of my first message and the second quoted block: it happens in a test of the testsuite. As I said midly, "it feels a bit hackish".

Error: This expression has type int ref
but an expression was expected of type int
Hint: Did you forget to use `!' to get the content of a reference somewhere?
|}];;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you add a small test for the cases where either ! or the ref types are redefined?

@gasche gasche mentioned this pull request Mar 24, 2018
@Armael
Copy link
Copy Markdown
Member Author

Armael commented Apr 5, 2018

I'll ease the job of the maintainers and close this one...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants