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 typing bug? #2696

Closed
vicuna opened this issue Mar 3, 2001 · 2 comments
Closed

module typing bug? #2696

vicuna opened this issue Mar 3, 2001 · 2 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Mar 3, 2001

Original bug ID: 299
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)
Related to: #5984

Bug description

Here's an example of a .ml and .mli file (the original .mli generated
by ocamlc -i -c) that cause a compilation failure in 3.00+22 but are fine
in 3.00. I did a fair bit of snipping but I can show the original code if
it's helpful

(* polyset.mli *)
module type OrderedType = sig type 'a t val compare : 'a t -> 'a t -> int end

module ClassicalType :
sig
type 'a t = 'a
val compare : 'a -> 'a -> int
end

module type S =
sig
type 'a elt
and 'a t
val empty : 'a t
val is_empty : 'a t -> bool
end

module Make(Ord : OrderedType) : (S with type 'a elt = 'a Ord.t)

module Set :
sig
type 'a elt = 'a
and 'a t =
Empty
| Node of 'a t * 'a elt * 'a t * int
val empty : 'a t
val is_empty : 'a t -> bool
end

(* polyset.ml *)
module type OrderedType =
sig
type 'a t
val compare: 'a t -> 'a t -> int
end

module ClassicalType =
struct
type 'a t = 'a
let compare = Pervasives.compare
end

module type S =
sig
type 'a elt
type 'a t
val empty : 'a t
val is_empty : 'a t -> bool
end

module Make (Ord : OrderedType) : (S with type 'a elt = 'a Ord.t) =
struct
type 'a elt = 'a Ord.t
type 'a t = Empty | Node of 'a t * 'a elt * 'a t * int

let empty = Empty

let is_empty = function Empty -> true | _ -> false

end

module Set = Make(ClassicalType)


ocamlc -c polyset.ml
The implementation polyset.ml does not match the interface polyset.cmi:
Modules do not match:
sig
type 'a elt = 'a ClassicalType.t
and 'a t = 'a Make(ClassicalType).t
val empty : 'a t
val is_empty : 'a t -> bool
end
is not included in
sig
type 'a elt = 'a
and 'a t = Empty | Node of 'a t * 'a elt * 'a t * int
val empty : 'a t
val is_empty : 'a t -> bool
end
Type declarations do not match:
type 'a elt = 'a ClassicalType.t
is not included in
type 'a elt = 'a

-- Brian

@vicuna
Copy link
Author

vicuna commented Mar 5, 2001

Comment author: administrator

Fixed by Jacques on 2001-03-04, but not yet real propagation.

@vicuna
Copy link
Author

vicuna commented Mar 5, 2001

Comment author: administrator

Here's an example of a .ml and .mli file (the original .mli generated
by ocamlc -i -c) that cause a compilation failure in 3.00+22 but are fine
in 3.00. I did a fair bit of snipping but I can show the original code if
it's helpful
[...]
Type declarations do not match:
type 'a elt = 'a ClassicalType.t
is not included in
type 'a elt = 'a

This one seems to be caused by the non-propagation of type variances
in functor application and with constraints. I completely forgot this
part of the problem when adding variances.
That is, 'a elt is marked as covariant in the interface, where the
signature was expanded by hand, but is left as non-variant in the
implementation, since Ord.t was supposed to be nonvariant, and the
variance of ClassicalType.t was not propagated.

Since propagating them will not be easy, I first did the simple part:
only compare variances when the type in the interface is abstract
(i.e., no representation and no expansion). If it is not abstract, its
variance has already been checked anyway.

You can get the corrected version from CVS.

Even after correcting this bug, I get the error:
Type declarations do not match:
type 'a t = 'a Make(ClassicalType).t
is not included in
type 'a t = Empty | Node of 'a t * 'a elt * 'a t * int

And looking at your code, this seems true: t is abstract in S, and
signatures are opaque in ocaml.
After removing this equation from polyset.mli, I could compile with no
error.

So, the problem is solved if you don't care about subtyping, but there
is still an open problem, namely that variance is not properly
propagated in functor application, which means that one may have to
write explicitely an interface to recover the variance, if he needs it
for subtyping.

Jacques

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

No branches or pull requests

1 participant