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

unexpected type error when packing a module alias #6982

Closed
vicuna opened this issue Sep 8, 2015 · 2 comments
Closed

unexpected type error when packing a module alias #6982

vicuna opened this issue Sep 8, 2015 · 2 comments
Assignees

Comments

@vicuna
Copy link

vicuna commented Sep 8, 2015

Original bug ID: 6982
Reporter: @sliquister
Assigned to: @garrigue
Status: closed (set by @xavierleroy on 2017-02-16T14:14:59Z)
Resolution: fixed
Priority: normal
Severity: minor
Version: 4.02.2
Fixed in version: 4.03.0+dev / +beta1
Category: typing
Monitored by: @gasche @hcarty

Bug description

When building the code below, I get the error:

File "std_internal.ml", line 25, characters 18-25:
Error: The type t in this module cannot be exported.
Its type contains local dependencies:
(module %M.A_S)

As you can see in the test, it only happens when I pack an alias, not if I use the module pointed to by the alias, and not if I force the alias to be expanded. Since the code types when not using an alias, I would expect it to type when using an alias.

Apparently, in Typemod.type_package, the typer rewrites (module Some_alias) into (module let %M = Some_alias in %M), and then complains that %M is free in the package type.
I think if the pattern that matches Tmod_ident also matches aliases, that would fix the problem. Perhaps using nondep_supertype somewhere would also fix it, but that sounds more heavyweight.

Steps to reproduce

Build:

module A = struct
module type A_S = sig
end

type t = (module A_S)
end

module type S = sig type t end

let f (type a) (module X : S with type t = a) = ()

let _ = f (module A) (* ok *)

module A_annotated_alias : S with type t = (module A.A_S) = A

let _ = f (module A_annotated_alias) (* ok )
let _ = f (module A_annotated_alias : S with type t = (module A.A_S)) (
ok *)

module A_alias = A
module A_alias_expanded = struct include A_alias end

let _ = f (module A_alias_expanded : S with type t = (module A.A_S)) (* ok )
let _ = f (module A_alias_expanded) (
ok *)

let _ = f (module A_alias : S with type t = (module A.A_S)) (* doesn't type )
let _ = f (module A_alias) (
doesn't type either *)

@vicuna
Copy link
Author

vicuna commented Sep 8, 2015

Comment author: @sliquister

Also with more parens on the second to last line, it can be accepted:

let _ = f (module (A_alias : S with type t = (module A.A_S))) (* ok *)

@vicuna
Copy link
Author

vicuna commented Sep 9, 2015

Comment author: @garrigue

Fixed in trunk at revision 16410.
Indeed, module aliases require a coercion, which made the pattern-matching fail.
While the extra example shows that this had no impact on other code paths, they are probably not equivalent in expressiveness.

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

2 participants