Original bug ID: 7321 Reporter:@mmottl Assigned to:@garrigue Status: resolved (set by @garrigue on 2017-03-15T02:39:56Z) Resolution: fixed Priority: normal Severity: minor Target version: 4.05.0 +dev/beta1/beta2/beta3/rc1 Fixed in version: 4.06.0 +dev/beta1/beta2/rc1 Category: typing Child of:#5984 Monitored by:@gasche@mmottl
Bug description
Consider the following code:
module type S = sig type 'a t end
module type Sp = sig type 'a t = private 'a array end
module Id (S : S) = S
module M : Sp = struct
include Id (struct type 'a t = 'a array end)
(**)
(* type 'a t = 'a array )
( include (Id (struct type 'a t = 'a array end) : S with type 'a t := 'a t) )
end ( M *)
The compiler will fail with:
File "./foo.ml", line 6, characters 16-288:
Error: Signature mismatch:
Modules do not match:
sig type 'a t = 'a array end
is not included in
Sp
Type declarations do not match:
type 'a t = 'a array
is not included in
type 'a t = private 'a array
File "./foo.ml", line 2, characters 21-49: Expected declaration
File "./foo.ml", line 1, characters 20-29: Actual declaration
Their variances do not agree.
This makes no sense, because the whole point of the signature is to make the type private. The included functor instantiation essentially does the same thing as establishing the type definition manually, which is just an alias anyway.
When replacing the code in module M with the second section after the comment separator, the problem goes away. The included functor instantiation doesn't really contain anything in this example then, but I have real world code where some generated functions needed to be included, along with the type, which didn't work. This signature type substitution trick can be used as a workaround for what seems to be a bug.
The text was updated successfully, but these errors were encountered:
This is a direct consequence of #5984: since variance information is not propagated through functors, the variance assigned to the type in the output of the Id functor is insufficient.
A workaround could be to just ignore variance when one side is a normal abbreviation, and the other a private abbreviation, since their contents are guaranteed to be equal anyway.
Or are they really? Need to check the theory before doing it.
Only check variance when the external type declaration is abstract, or when the internal type declaration is either private or an open type.
Rationale: only abstract, private and open types have an explicit variance, in other cases it is computed from the definition, so there is no need to test for inclusion separately.
Original bug ID: 7321
Reporter: @mmottl
Assigned to: @garrigue
Status: resolved (set by @garrigue on 2017-03-15T02:39:56Z)
Resolution: fixed
Priority: normal
Severity: minor
Target version: 4.05.0 +dev/beta1/beta2/beta3/rc1
Fixed in version: 4.06.0 +dev/beta1/beta2/rc1
Category: typing
Child of: #5984
Monitored by: @gasche @mmottl
Bug description
Consider the following code:
module type S = sig type 'a t end
module type Sp = sig type 'a t = private 'a array end
module Id (S : S) = S
module M : Sp = struct
include Id (struct type 'a t = 'a array end)
(**)
(* type 'a t = 'a array )
( include (Id (struct type 'a t = 'a array end) : S with type 'a t := 'a t) )
end ( M *)
The compiler will fail with:
File "./foo.ml", line 6, characters 16-288:
Error: Signature mismatch:
Modules do not match:
sig type 'a t = 'a array end
is not included in
Sp
Type declarations do not match:
type 'a t = 'a array
is not included in
type 'a t = private 'a array
File "./foo.ml", line 2, characters 21-49: Expected declaration
File "./foo.ml", line 1, characters 20-29: Actual declaration
Their variances do not agree.
This makes no sense, because the whole point of the signature is to make the type private. The included functor instantiation essentially does the same thing as establishing the type definition manually, which is just an alias anyway.
When replacing the code in module M with the second section after the comment separator, the problem goes away. The included functor instantiation doesn't really contain anything in this example then, but I have real world code where some generated functions needed to be included, along with the type, which didn't work. This signature type substitution trick can be used as a workaround for what seems to be a bug.
The text was updated successfully, but these errors were encountered: