Fix #678 (Quantifiers escape their scopes)#710
Conversation
core/typeSugar.ml
Outdated
| let escaped_quantifier ~pos ~var ~annotation ~escapees = | ||
| let quant_policy () = { (error_policy ()) with Types.Print.quantifiers = true } in | ||
| let show_type ty = | ||
| Types.string_of_datatype ~policy:quant_policy ~refresh_tyvar_names:true ty in |
There was a problem hiding this comment.
@SimonJF, please rethink how variable name generation is handled in escaped_quantifier:
~refresh_tyvar_namesdefaults totrueforTypes.string_of_datatypeso it is redundant here.Grippersmodule overridesTypes.string_of_datatypeand sets~refresh_tyvar_names:false, with the intention being that everything is done manually by callingbuild_tyvar_names/add_tyvar_names. It's a fairly low level API, I know, but that's how it's designed to work at the moment.- When you say
List.map display_ty escapeesit callsTypes.string_of_datatype ~refresh_tyvar_names:truefor every element in the list, which means every type gets a fresh set of type variables. Most likely this is not what you want. This will lead to bugs in the likes of Fix type variable name generation in error messages #704. - A matter of style: I'm not convinced it is worth having
show_typebinding, given that it is only used once.
| Printf.sprintf "%s: %s" var ppr_ty in | ||
| let displayed_tys = | ||
| List.map display_ty escapees | ||
| |> String.concat (nli ()) in |
There was a problem hiding this comment.
Maybe we should have a combinator for it? lines?
|
Thanks, @jstolarek -- I was unsure about the type variable printing API and your comments are very helpful. I have (I hope) fixed the type variable printing issue, and have implemented (Previous CI failure on Azure looked transient). |
core/typeSugar.ml
Outdated
| build_tyvar_names (annotation :: escaped_tys); | ||
| let policy () = { (error_policy ()) with Types.Print.quantifiers = true } in | ||
| let display_ty (var, ty) = | ||
| let ppr_ty = Types.string_of_datatype ~policy ty in |
There was a problem hiding this comment.
Again, not Types.string_of_datatype but string_of_datatype. Types.string_of_datatype will refresh type variables on each call, string_of_datatype will not.
There was a problem hiding this comment.
Also, might be worth inlining ppr_ty.
There was a problem hiding this comment.
Gotcha -- I think you mean show_type? (string_of_datatype doesn't seem to be defined). But that doesn't allow me to pass in a policy (and I require one here in order to show the quantifiers in the error message).
I think my best bet would therefore to be explicit and say
Types.string_of_datatype ~policy ~refresh_tyvar_names:false
There was a problem hiding this comment.
Why not:
Printf.sprintf "%s: %s" var (string_of_datatype ~policy ty) inAm I missing something obvious here?
There was a problem hiding this comment.
Ah, yes. I am missing something obvious - just realized what you mean by show_type. Give me a moment to look at the code.
There was a problem hiding this comment.
string_of_datatype doesn't seem to exist in the scope unqualified:
File "core/typeSugar.ml", line 1530, characters 37-55:
Error: Unbound value string_of_datatype
There was a problem hiding this comment.
Yes, you're absolutely right. Apparently the API is a bit confusing and easily leads to bugs (e.g. on line 1501 in typeSugar.ml). This probably needs rethinking.
I wonder of it would make sense to display quantifiers by default in error messages?
There was a problem hiding this comment.
But either way, this is beyond the scope of this PR.
|
Thanks for the review! I'll merge after CI passes. |
This patch does a fairly simple fix which ensures that given an explicitly-quantified signature, that the quantifiers do not appear in the typing environment after typechecking the body. The check is only performed when a function has explicit quantifiers. As an example, the program from links-lang#678: ``` var f = id(id); sig g : forall a. (a) -> a fun g(x) { f(x) } ``` Now gives the error: ``` squid-bug.links:4: Type error: The quantifiers in the type of function g: forall a.(a) -b-> a escape their scope, as they are present in the types: f: (a) -b-> a In expression: fun g(x) { f(x) }. ```
This patch does a fairly simple fix which ensures that given an explicitly-quantified signature, that the quantifiers do not appear in the typing environment after typechecking the body. The check is only performed when a function has explicit quantifiers.
As an example, the program from #678:
Now gives the error: