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

Removal of shadowed constructors of extensible types can break the structure of definitions #6510

Closed
vicuna opened this issue Aug 8, 2014 · 5 comments
Assignees

Comments

@vicuna
Copy link

vicuna commented Aug 8, 2014

Original bug ID: 6510
Reporter: @alainfrisch
Assigned to: @lpw25
Status: closed (set by @xavierleroy on 2016-12-07T10:34:26Z)
Resolution: fixed
Priority: low
Severity: minor
Fixed in version: 4.02.0+dev
Category: typing
Monitored by: @gasche

Bug description

There is some logic to drop constructors of extensible types when they are shadowed by a constructor of the same name later in the structure:

type t = ..;;

type t = ..

module X = struct type t+= A type t+= X type t+= A end;;

module X : sig type t += X type t += A end

Individual constructors can also be dropped from a declaration containing multiple ones:

module X = struct type t+= A|B type t+= X type t+= A end;;

module X : sig type t += B type t += X type t += A end

But because of the way declarations of multiple constructors in a single declaration is encoded in the internal representation of signatures, this can "merge" a constructor with a preceding declaration:

module X = struct type t+= C type t+= A|B type t+= X type t+= A end;;

module X : sig type t += C | B type t += X type t += A end

This can be considered as a bug, since all the logic to keep a structured representation of multiple declarations is there to allow showing signatures that respect the original code. Here the constructors C and B were declared independently but they end up printed together.

But it is even worse, since the same applies if C is added to another type:

type s = ..;;

type s = ..

module X = struct type s+= C type t+= A|B type t+= X type t+= A end;;

module X : sig type s += C | B type t += X type t += A end

Here the printed signature is just plain wrong.

Note: this only applies for inferred signatures. Explicit signatures are probably supported.

File attachments

@vicuna
Copy link
Author

vicuna commented Aug 8, 2014

Comment author: @alainfrisch

I've attached a patch (very lightly tested). I'm still wondering whether using a flat internal representation is the right approach. Leo: do you see major drawbacks in using a more structured representation (closer to the Parsetree/Typedtree structure)?

@vicuna
Copy link
Author

vicuna commented Aug 8, 2014

Comment author: @lpw25

do you see major drawbacks in using a more structured representation (closer to the Parsetree/Typedtree structure)?

I think that it would make correct handling of ascription harder. In typing terms each extension constructor is a separate element of the module, so almost all code treats them independently. The only place where we care about how they are grouped is in printing.

@vicuna
Copy link
Author

vicuna commented Aug 8, 2014

Comment author: @lpw25

I've attached a patch (very lightly tested)

The patch looks correct to me.

@vicuna
Copy link
Author

vicuna commented Aug 8, 2014

Comment author: @alainfrisch

Thanks for the review. The patch is committed to 4.02 (15071) and to trunk (15072).

@vicuna
Copy link
Author

vicuna commented Aug 8, 2014

Comment author: @mshinwell

Closing, since this is apparently fixed.

@vicuna vicuna closed this as completed Dec 7, 2016
@vicuna vicuna added the typing label Mar 14, 2019
@vicuna vicuna added the bug label Mar 20, 2019
avsm pushed a commit to avsm/ocaml that referenced this issue Jun 21, 2020
…can break the structure of definitions.

git-svn-id: http://caml.inria.fr/svn/ocaml/version/4.02@15071 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
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