gren-lang / gren-lang/compiler-common

Parser accepts custom-type variants with more than one bare-constructor argument

Open
#32 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
No language data
Stars
1
Forks
1
PR merge metrics
No merged PRs in 30d

Description

Per the Gren 24w release notes (gren-lang.org/news/161224_gren_24w),
custom-type variants are limited to 0 or 1 argument:

A change with bigger impact is that custom types are now limited to either 0
or 1 parameters, where they previously could have many more.

Code like this is no longer valid:

type Person = Person String Int

If you want to associate multiple fields with a variant, you can use a
record instead:

type Person = Person { name : String, age : Int }

The parser does not enforce this. type Person = Person String Int
parses without error. Perhaps it should be checked after the parse,
but there are other related parser failures which make me thinks this is probably
an error in the parser.

The parser accepts an arbitrary chain of bare, unparenthesized
constructor-name (Int, String, Float, …) arguments with no limit.

The parser only ever rejects a multi-argument variant when one of the
non-final arguments is something other than a bare constructor name.
So that's why I think it's a parser bug.

Also, because of this ordering problem, the same two arguments parse or fail to parse depending on their order.

Symptom 1 — unlimited bare-constructor arguments accepted

module Person exposing (..)


type Person
    = Person String Int

Parses successfully. (Confirmed against the gren-format --pre-ast)
The same holds for 3+ arguments:

type X
    = Ctor Int Float String

Also parses successfully.

Symptom 2 — argument-order-dependent parse failures

Given the same two arguments, whether the variant parses depends on which
argument comes last:

-- FAILS to parse (right after `b`):
type X b
    = Ctor b Int

-- PARSES (same two arguments, order swapped):
type X b
    = Ctor Int b
-- FAILS to parse (right after the closing `)`):
type X a
    = Ctor (Array a) Float

-- PARSES (same two arguments, order swapped):
type X a
    = Ctor Float (Array a)
-- FAILS to parse (right after the closing `}`):
type X
    = Ctor { field : Bool } Char

The error messages

The parse errors look like this:

-- FAILED TO PARSE ------------------------------------------------

    = Ctor b Int
             ^

Expected end of file
Expected keyword 'port'
Expected keyword 'type'
Invalid character in variable name

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the examples with gren-format --pre-ast, comparing bare-constructor arguments in each order and the record form. Start by tracing the parser's handling of custom-type variants and determine where the ordering-dependent behavior occurs. Done means multi-argument variants are rejected consistently while valid zero- or one-argument variants still parse.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.