Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module inclusion check and constraint in type declarations #7703

Closed
vicuna opened this issue Jan 3, 2018 · 6 comments
Closed

Module inclusion check and constraint in type declarations #7703

vicuna opened this issue Jan 3, 2018 · 6 comments

Comments

@vicuna
Copy link

vicuna commented Jan 3, 2018

Original bug ID: 7703
Reporter: igarnier
Assigned to: @garrigue
Status: feedback (set by @garrigue on 2018-01-05T05:07:34Z)
Resolution: open
Priority: low
Severity: feature
Platform: x86_64
OS: Linux
Version: 4.06.0
Category: typing
Monitored by: @Drup @gasche

Bug description

It seems that the subtyping relation induced by the following constraints is not taken into account in the module inclusion check process. The following example (courtesy of Gabriel Radanne) doesn't type check.

module M
: sig type +'a t = [< A | B ] as 'a end
= struct type +'a t = [< `A ] as 'a end

@vicuna
Copy link
Author

vicuna commented Jan 5, 2018

Comment author: @garrigue

I'm not sure this would be sound.
And if it is in this precise case, I'm not sure what the condition is to make it sound in general.
This may be related to @gache's work on subtyping for GADTs.

@vicuna
Copy link
Author

vicuna commented Jan 5, 2018

Comment author: @Drup

That was my initial reaction as well, but I was not able to find a counter example. @gasche, do you have one?

@vicuna
Copy link
Author

vicuna commented Jan 8, 2018

Comment author: @gasche

I don't understand the type-checking of "constraints" very well. When are they applied?

When experimenting with this question, in general it looks safe because the constraint is substituted for the type. For example, if you write

module type Get = sig
type +'a t = [< `A of int ] as 'a
val get : 'a t -> int
end

then the inferred signature is actually

val get : [< `A of int ] t -> int

(instead of a polymorphic ('a . 'a t -> int)) so there is no way to cause mischief by injecting a `B later.

On the other hand, the following would be unsound and must be rejected:

module Test : sig
type +'a t = [< A of int | B ] as 'a
val get : 'a t -> int
end
= struct
type +'a t = [< A of int ] as 'a let get = function A n -> n
end

Checking the implementation of get against its specification must happen after the constraints have been substituted in the signature of get -- if this happens, then it should be rejected.

@github-actions
Copy link

github-actions bot commented May 7, 2020

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 7, 2020
@Drup
Copy link
Contributor

Drup commented May 7, 2020

Without any feedback, I propose we keep rejecting such forms and close this.

@xavierleroy
Copy link
Contributor

Closing as suggested.

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

No branches or pull requests

4 participants