Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0004827OCamlOCaml generalpublic2009-06-18 18:102013-07-24 22:38
Assigned To 
PlatformOSOS Version
Product Version3.11.0 
Target Version4.01.1+devFixed in Version 
Summary0004827: Module typing weirdness
DescriptionThe following file "" leads to a funny compile error:

module type Sig = sig
  type t

  val f : t -> unit

module type Test_sig = sig
  module Make (S : sig end) : Sig with type t = int
  module X : Sig

module Test : Test_sig = struct
  module Make (S : sig end) = struct
    type t = int

    let f =
      match 0 with
      | 0 -> fun _ -> ()
      | _ -> fun _ -> ()

  module X =
      include Make (struct end)

The error message:

      File "", line 12, characters 25-242:
      Error: Signature mismatch:
             Modules do not match:
                 module Make :
                   functor (S : sig end) -> sig type t = int val f : t -> unit end
                 module X : sig type t = int val f : t -> unit end
             is not included in
             Modules do not match:
               sig type t = int val f : t -> unit end
             is not included in
             Values do not match:
               val f : t -> unit
             is not included in
               val f : t -> unit

The last few lines, which state that "val f : t -> unit" is not included in itself, are clearly counterintuitive.

The problem is obviously related to non-generalizable type variables. The function "f" can take any type, but since it is generated through an expression, the type variable is not generalized. There are two interesting observations here:

1) Deleting either Make or X from Test_sig will make the file compile.
2) Removing "struct", "end" and "include" from the definition of X, i.e. just directly binding the result of the functor application to X, will also get rid of errors.

Besides the counterintuitive error message, especially 2) seems weird. There is no obvious reason why this code should not be accepted.

I'm not sure whether there is an easy fix for this in the compiler. In case anybody needs to work around this problem, simply constraining the type of the argument to f at the point of definition should always work, because this gets rid of the non-generalized type variable. E.g.:

  let f =
    match 0 with
    | 0 -> fun (_ : t) -> ()
    | _ -> fun _ -> ()
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
There are no notes attached to this issue.

- Issue History
Date Modified Username Field Change
2009-06-18 18:10 mottl New Issue
2011-05-31 15:52 doligez Status new => acknowledged
2012-07-11 14:42 doligez Target Version => 4.01.0+dev
2012-07-31 13:36 doligez Target Version 4.01.0+dev => 4.00.1+dev
2012-09-17 14:32 doligez Target Version 4.00.1+dev => 4.01.0+dev
2013-07-24 22:38 doligez Target Version 4.01.0+dev => 4.01.1+dev

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker