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

implementation does not match the interface (inferred signature) #8548

Closed
trefis opened this issue Mar 26, 2019 · 3 comments

Comments

Projects
None yet
2 participants
@trefis
Copy link
Contributor

commented Mar 26, 2019

foo.ml

module type Endpoint_intf = sig
  type t
end

module type S = sig
  module Endpoint : Endpoint_intf

  type finite = [ `Before of Endpoint.t ]
  type infinite = [ `Until_infinity ]

  type +'a range = private { until : 'a } constraint 'a = [< finite | infinite ]

  val until : 'a range -> 'a
end

module type Ranged = sig
  module Endpoint : Endpoint_intf
  module Range : S with type Endpoint.t = Endpoint.t
end

Compiles fine pre 4.08, and is currently broken on 4.08 and trunk with:

Error: The implementation ./foo.ml
       does not match the interface (inferred signature):
       ...
       At position module type Ranged = sig module Range : <here> end
       Values do not match:
         val until :
           ([< `Before of Endpoint.t | `Until_infinity ] as 'a) range -> 'a
       is not included in
         val until :
           ([< `Before of Endpoint.t | `Until_infinity ] as 'a) range -> 'a
       File "./foo.ml", line 13, characters 2-28: Expected declaration
       File "./foo.ml", line 13, characters 2-28: Actual declaration

@trefis trefis added bug typing labels Mar 26, 2019

@trefis trefis added this to the 4.08 milestone Mar 26, 2019

@trefis

This comment has been minimized.

Copy link
Contributor Author

commented Mar 27, 2019

git bisect seems to indicate that the issue was introduced by #1980.
I'll investigate.

@trefis

This comment has been minimized.

Copy link
Contributor Author

commented Mar 27, 2019

So, there is one thing that is obviously wrong but also benign is that Mtype.freshen (which is called when typing module types with with-constraints) makes all the idents in the signature locally scoped.
Unfortunately, fixing that does not fix the issue (one could have hoped, considering the test case).

Includemod also does call Subst in various places, which here too makes a bunch of idents locals, but then calls things (e.g. moregeneral) which care about the scoping of things.
Changing Subst and these calls to make it create idents at a given scope, instead of local idents, does make the problem disappear.
However, playing around in ocamldebug (prior to making the issue disappear) I've seen some of these calls go through fine even though some type constructors were local (here is the diff of vd{1,2}.val_type between two calls to Includecore.value_description, one of which succeeded, and the other failed) . So I'm not quite sure what's going on just yet.

@trefis

This comment has been minimized.

Copy link
Contributor Author

commented Mar 27, 2019

OK so the difference between the two is that in the second call, [< finite ] range will expand to [< finite ] Range.range for vd1, but won't for vd2 (the difference is due to their level being different, and the scope being set incorrectly).
Whereas for the first call, neither will expand (but that's because we were checking S, and not Range.S).

I will proceed with fixing the calls to Subst.

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.