include functor support for OxCaml - #1452
Conversation
18499bf to
ca9079a
Compare
Signed-off-by: Marek Kubica <marek@tarides.com>
Signed-off-by: Marek Kubica <marek@tarides.com>
Signed-off-by: Marek Kubica <marek@tarides.com>
ca9079a to
a6c9652
Compare
art-w
left a comment
There was a problem hiding this comment.
Thanks a lot, this looks great! I only have minor feedback but nothing blocking :)
| >>= | ||
| match allow_functor with | ||
| | true -> assert_functor | ||
| | false -> assert_not_functor) |
There was a problem hiding this comment.
Can we avoid the ~allow_functor is we match on | Signature s | Functor (_ Signature s) -> s or would that hide some logic errors? (since both assert_.._functor fail with assert false anyway, I assume the error reporting isn't a concern)
There was a problem hiding this comment.
Yes - at the very least we ought to rename the argument. I'd quite like to double check the semantics here though, as we've got at least one instance of this bit going wrong: #960
There was a problem hiding this comment.
Truth be told I am a bit confused about the purpose of assert_not_functor:
- Why do we need to make sure the module expression is not a functor?
- The function doesn't actually just assert (I thought I could just remove it to allow for functors, but then the types don't match), it also unpacks the signature.
Hence to answer @art-w's question, I don't know - it would change semantics as then it would always allow functors; in which case we could rewrite it into something like
and assert_signature : type err. expansion -> (Component.Signature.t, err) result
= function
| Signature sg -> Ok sg
| Functor (_, mty) -> (
match mty with Signature sg -> Ok sg | _ -> assert false)
| _ -> assert false| (** This is a Module where the type is named and then included. *) | ||
| module type Make = (_ : sig type t end) -> sig type included end | ||
| type t | ||
| include functor Make |
There was a problem hiding this comment.
Out of curiosity, can we test the behavior with (** @inline *)?
|
I think there's a chunk of logic missing from this PR. At the moment, all it does AFAICT is get the expansion of the functor and splice it into the expansion of the include. While this works for simple examples, it's not sufficient for more involved cases. As a simple example, consider this: module F ( I : sig type t end ) = struct
type myt = I.t
end
module M = struct
type t = float
include functor F
endRunning this through module F : functor (I : sig type t end) -> sig type myt = I.t end
module M : sig type t = float type myt = float endIf we just simply get the signature of the functor body and splice it in, we end up something more like: ...
module M : sig
type t = float
type myt = I.t
endand obviously that I suspect the most straightforward implementation of this would be to do exactly what the docs suggest it does internally. Treat it more like: module M = struct
module __DUMMY__ = struct
type t = float
end
include __DUMMY__
include F(__DUMMY__)
endWe can ensure that the dummy module is hidden, meaning that the include will just inline the contents, |
78e4383 to
e8b5ba1
Compare
This PR is a follow up to #1368 and adds support for
include functorwhere it now displays that the items were included via the functor.