Opened 4 years ago

Closed 4 years ago

#10498 closed bug (fixed)

"if ... then \case -> else ..." causes a "missing else clause" error

Reported by: dramforever Owned by:
Priority: normal Milestone: 7.10.3
Component: Compiler (Parser) Version: 7.10.1
Keywords: Cc: MikeIzbicki
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Other Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s): Phab:D1309
Wiki Page:

Description

The following program:

{-# LANGUAGE LambdaCase #-}

foo =
    if True
    then
        \case ->
            1 -> 2
    else id

Produces this message:

problem.hs:4:5:
    parse error in if statement: missing required else clause

The problem in the code is that there's a -> after the \case.

I don't know if a better error message can be generated, but this one is really unhelpful.

Change History (11)

comment:1 Changed 4 years ago by dramforever

I ran into this in another more complex program yesterday. It took me 15 mins to find out the real cause of the error.

comment:2 Changed 4 years ago by rwbarton

Regression since 7.8 ("parse error on input ‘->’"), so I guess it is caused by Phab:D201.

comment:3 Changed 4 years ago by thomie

Cc: MikeIzbicki added
Milestone: 7.10.3

@MikeIzbicki: as the author of Phab:D201, could you have a look?

comment:4 Changed 4 years ago by MikeIzbicki

I'm sorry, but I doubt I'll have time to look into this anytime soon.

comment:5 Changed 4 years ago by thomie

Keywords: newcomer added

comment:6 Changed 4 years ago by thomie

Keywords: newcomer removed

I'm inclined to just the delete the parser changes from Phab:D201. They were supposed to make error messages better, but instead they make them worse.

Here's an example from the testsuite (parser/should_fail/readFail020):

f = let x = 42 } in x
-- before:
parse error on input ‘}’
-- after:
parse error in let binding: missing required 'in'

Here's another:

f = if module then True else False
-- before:
parse error on input ‘module’
-- after:
parse error in if statement: naked if statement

For that last one, the parser code looks like this:

| 'if' error      {% hintIf (getLoc $1) "naked if statement" }
| 'if' exp optSemi error                              {% ... something ... }
| 'if' exp optSemi 'then' error                       {% ... something ... }
| 'if' exp optSemi 'then' exp optSemi error           {% ... something ... }
| 'if' exp optSemi 'then' exp optSemi 'else' error    {% ... something ... }

What this means is that a lexical error in the condition of an if-expression, that we don't handle gracefully in the parser, will be reported as "naked if statement".

The example from the description has the same cause.

comment:7 Changed 4 years ago by thomie

Differential Rev(s): Phab:D1309
Status: newpatch

comment:8 Changed 4 years ago by simonmar

Worth double-checking to see whether the set of shift/reduce conflicts in Parser.y needs updating.

comment:9 Changed 4 years ago by Austin Seipp <austin@…>

In e2b579e8/ghc:

Parser: revert some error messages to what they were before 7.10

Among doing other things, Phab:D201 (bc2289e13d9586be087bd8136943dc35a0130c88)
tried to improve the error messages thrown by the parser. For example a missing
else clause now prints "parse error in if statement: else clause empty" instead
of "parse error (possibly incorrect indentation or mismatched brackets)".

Some error messages got much worse however (see tests), and the result seems to
be a net negative. Although not entirely satisfactory, this commits therefore
reverts those parser changes.

Reviewed By: austin

Differential Revision: https://phabricator.haskell.org/D1309

GHC Trac Issues: #10498

comment:10 Changed 4 years ago by thomie

Status: patchmerge

comment:11 Changed 4 years ago by bgamari

Resolution: fixed
Status: mergeclosed
Note: See TracTickets for help on using tickets.