Skip to content

Conversation

@Octachron
Copy link
Member

@Octachron Octachron commented Oct 17, 2024

Both true and false should not be escaped using the raw identifier syntax if they appear in a context where a variant constructor is expected. For instance, in

let x = true 0

we don't want to escape true in

Error: The constructor true expects 0 argument(s),
      but is applied here to 1 argument(s)

Similarly, it is better to print Path.To.(true) as Path.To.(true) and not Path.To.true nor Path.To.\#true.

This PRs tweak the constructor printer in Oprint to handle this last case and adds a specific printer for variant constructor longident for error messages in Pprintast.

Along the way, it removes a backpatched printer in Env that has not been needed since the implementation of the longident printers has moved to Pprintast rather than Printtyp, and it fixes a missing inline code tag in a nearby error message.

Close #13263

Both `true` and `false` should not be escaped using the raw identifier
syntax if they appear in a context where a variant constructor is
expected.
Copy link
Member

@gasche gasche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks okay and it does improve the testsuite output. I made a few nitpick comments.

let open Format_doc.Doc in
let longident l = Format_doc.doc_printer longident l.Location.txt in
let longident ?(is_constr=false) l =
Format_doc.doc_printer (any_longident ~is_constr) l.Location.txt in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: I would re-declare longident and constr here.

let name = Datatype_kind.label_name kind in
let pr = match kind with
| Datatype_kind.Record -> quoted_longident
| Datatype_kind.Variant -> quoted_constr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It smells a bit weird to me to handle record field labels and constructor variant labels differently here. I understand that true and false are variant constructors and not record fields, but I would vote for handling them in the same way here unless this creates issues.

Copy link
Member Author

@Octachron Octachron Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point is that with raw identifiers true is now both a valid record field and a valid constructor, but the record field must be escaped

type r = { \#true: int }

whereas the variant constructor must be left unescaped

type s = true

In practice, the variant case doesn't happen because this error path is only reachable with qualified name, and
M.true is a syntax error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that the root of evil here is to pretend that the constructor true is an identifier; things would be simpler if reserved keywords also had reserved AST constructs.

Copy link
Member Author

@Octachron Octachron Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option would be to forbid \#true and \#false because according to OCaml lexing rule true and false clearly start with a capital letter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this would also be perfectly reasonable. I have no opinion and I think that not showing \#true in real-world programs is probably more important than precisely how we deal with oddball programs, so I would follow your preference.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am inclined to fix first the printing bugs with this PR and continue the discussion later in #13246 .

@Octachron Octachron added this to the 5.3 milestone Oct 21, 2024
@Octachron Octachron merged commit 6756917 into ocaml:trunk Oct 21, 2024
Octachron added a commit that referenced this pull request Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Printing issue of reserved keywords

2 participants