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

Functor breaks with an equivalent argument signature #5914

Closed
vicuna opened this Issue Feb 1, 2013 · 4 comments

Comments

Projects
None yet
2 participants
@vicuna
Copy link
Collaborator

vicuna commented Feb 1, 2013

Original bug ID: 5914
Reporter: @mmottl
Assigned to: @garrigue
Status: closed (set by @xavierleroy on 2015-12-11T18:19:56Z)
Resolution: fixed
Priority: normal
Severity: minor
Version: 4.00.1
Target version: 4.01.0+dev
Fixed in version: 4.01.0+dev
Category: typing
Monitored by: "Julien Signoles" @mmottl

Bug description

Valid signatures that merely differ in the order of their entries should usually be considered equivalent. But here is an example where flipping the order of two function entries in an argument signature can break a functor. It seems this is related in some bizarre way to unification of recursive types, but the behavior is just downright weird. Here is the error message when running "ocaml" on file "bug.ml" below:

File "bug.ml", line 39, characters 21-22:
Error: Signature mismatch:
...
Values do not match:
val bar : unit -> ('a M.a M.wrap as 'a)
is not included in
val bar : unit -> t
File "bug.ml", line 32, characters 2-21: Expected declaration
File "bug.ml", line 18, characters 6-9: Actual declaration

The signatures "Good" and "Bad" are clearly equivalent modulo the order of the two function entries (foo and bar). Nevertheless, the application of Func_good succeeds whereas Func_bad fails. Note that removing the signature constraint ": S" from module M will make the example pass the typechecker again, too.


module type S = sig
type 't a = [ `A ]

type 't wrap = 't constraint 't = [> 't wrap a ]
val foo : 't wrap -> 't wrap -> unit
end

(* module M = struct *)
module M : S = struct
type 't a = [ `A ]
type 't wrap = 't constraint 't = [> 't wrap a ]
let foo x y = ()
end

module T = struct
type t = t M.a M.wrap
include M
let bar : unit -> ('a M.a M.wrap as 'a) = fun () -> `A
end

include T

module type Good = sig
type t
val bar : unit -> t
val foo : t -> t -> unit
end

module type Bad = sig
type t
val foo : t -> t -> unit
val bar : unit -> t
end

module Func_good (Arg : Good) = struct end
module Func_bad (Arg : Bad) = struct end

module X = Func_good (T)
module Y = Func_bad (T)

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Jun 19, 2013

Comment author: @damiendoligez

Confirmed. I'm setting 4.01.0 as the target in the hope that there is a simple fix. If this is not the case, just push it back to 4.02.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Jun 21, 2013

Comment author: hnrgrgr

Here is a shorter reproduction case:


type 't a = [ `A ]
type 't wrap = 't constraint 't = [> 't wrap a ]
type t = t a wrap

module T = struct
let foo : 't wrap -> 't wrap -> unit = fun _ _ -> ()
let bar : ('a a wrap as 'a) = `A
end

module Good : sig
val bar: t
val foo: t -> t -> unit
end = T

module Bad : sig
val foo: t -> t -> unit
val bar: t
end = T

(* One can not reproduce if 'foo' has only one parameter *)

module T' = struct
let foo : 't wrap -> unit = fun _ -> ()
let bar : ('a a wrap as 'a) = `A
end

module Good' : sig
val bar: t
val foo: t -> unit
end = T'

module Bad' : sig
val foo: t -> unit
val bar: t
end = T'

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Jun 21, 2013

Comment author: @garrigue

This is accepted when using ocamlc -principal.
So this seems related to the expansion-sharing optimization applied when -principal is not used.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Jun 22, 2013

Comment author: @garrigue

Fixed in trunk and 4.01, at revision 13829 and 13830.
The row variable of polymorphic variants was not correctly instantiated in moregen_row.

@vicuna vicuna closed this Dec 11, 2015

@vicuna vicuna added the typing label Mar 14, 2019

@vicuna vicuna added this to the 4.01.0 milestone Mar 14, 2019

@vicuna vicuna added the bug label Mar 20, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.