Skip to content

Tentative fix for #7372 (GADTs and inline records)#824

Closed
alainfrisch wants to merge 1 commit intoocaml:trunkfrom
alainfrisch:fix7372
Closed

Tentative fix for #7372 (GADTs and inline records)#824
alainfrisch wants to merge 1 commit intoocaml:trunkfrom
alainfrisch:fix7372

Conversation

@alainfrisch
Copy link
Contributor

@alainfrisch alainfrisch commented Sep 26, 2016

This is a tentative fix for MPR#7372 (http://caml.inria.fr/mantis/view.php?id=7372). As far as I understand, the cause of the bug is the internal encoding of inline records as record types whose parameters are derived from the set of free type variables in the record. The problem is that, in case of an open, this set can be computed for the same type in two different contexts, where the internal ids attached to the type variables are not in the same ordering, resulting in different orderings for the list of parameters.

The proposed fix consists in producing a list of parameters following the syntactic ordering (taking the first occurrence of each free variable in the record into account).

@garrigue Does this sound right to you?

@lpw25
Copy link
Contributor

lpw25 commented Sep 26, 2016

Isn't the syntactic ordering also not stable? For example:

type ('a, 'b) bpair = 'b * 'a
type _ t = Pair : ('a, 'b) bpair -> ('a * 'b) pair

is equal to:

type _ t = Pair : 'b * 'a -> ('a * 'b) pair

@alainfrisch
Copy link
Contributor Author

alainfrisch commented Sep 26, 2016

Indeed, but I'm not sure this is problematic here. The trouble is that the we compute constructor descriptions (with Datarepr) several times for the same type declaration, but with different substitutions applied to it, and substitutions change the ordering between ids of type variables. (In particular, we apply two "identity" substitution for the opened signature -- one caused by the loading of the persistent structure and another by open_signature; but only one "identity" substitution when computing components of Bug1.t.) The suggested fix ensures that the ordering of parameters does not change when such substitutions are applied.

I admit it seems quite brittle, though.

@alainfrisch
Copy link
Contributor Author

Perhaps to clarify: the problem comes from the fact that there are two different (incompatible) constructor_descriptions for the same constructor in the same context (one coming from the open Bug1 , the other constructed when "module components" of Bug1 are computed). I'm not very confident about it, but I believe that as long as the ordering is invariant under "identity substitution", the problem would not appear; another fix could be to implement open by inserting components from the module, instead of recomputing them from its signature.

@alainfrisch
Copy link
Contributor Author

alainfrisch commented Sep 28, 2016

To elaborate a bit again, I think the reason why the fact signaled by @lpw25 doesn't (currently) lead to a bug is that even if a constructor X.t.A is re-exported as Y.t.A, the internal record types for these two constructors are not considered as being equal:

module X = struct
  type t =
    | A : { x: int } -> t
end

module Y = struct
  type t = X.t =
    | A : { x: int } -> t
end

let _ =
  match X.A {x = 2} with
  | Y.A r -> Y.A r  (* ok ! *)

let _ =
  match X.A {x = 2} with
  | Y.A r -> X.A r  (* error ! *)

The error message for the last line is:

Error: This expression has type Y.t.A but an expression was expected of type
         X.t.A

i.e. the path is not normalized by taking equality of the two types Y.t == X.t into account.

@mshinwell
Copy link
Contributor

@garrigue Could you please have a look at this patch?

@damiendoligez damiendoligez modified the milestone: 4.05-or-later Feb 15, 2017
@damiendoligez
Copy link
Member

@alainfrisch is this superseded by #834?

@alainfrisch
Copy link
Contributor Author

Yes, indeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants