haskell / error-messages

72 stars 18 forks source link

Bare top-level expressions #35

Open MorrowM opened 2 years ago

MorrowM commented 2 years ago

Given this module:

sum [1,2,3,4]

We get this error when loading it into GHCi:

Main.hs:1:1: error:
    Parse error: module header, import declaration
    or top-level declaration expected.
  |
1 | sum [1,2,3,4]
  | ^^^^^^^^^^^^^
Failed, no modules loaded.

Perhaps we can:

  1. Recognize that this is a bare top-level expression.
  2. Reflect that in the error message.
  3. Suggest that the user might want to bind this bare expression to a name.

Suggested error message:

Main.hs:1:1: error:
    Parse error: module header, import declaration
    or top-level declaration expected, but encountered
    a bare expression instead.
    Perhaps you meant to bind this expression to a name?
  |
1 | sum [1,2,3,4]
  | ^^^^^^^^^^^^^
Failed, no modules loaded.

Ideally, it would also be nice if the error message didn't mention module headers or import declarations in places where it doesn't apply, such as in this example:

import Data.List
xs = [3,5,1,2]
sort xs
Main.hs:3:1: error:
    Parse error: module header, import declaration
    or top-level declaration expected.
  |
3 | sort xs
  | ^^^^^
ketzacoatl commented 2 years ago

Ideally, it would also be nice if the error message didn't mention module headers or import declarations in places where it doesn't apply, such as in this example:

What determines whether or not the module scenario applies? How does a user (or the code) know the module scenario is not applicable?

noughtmare commented 2 years ago

Module headers need to be near the top, right below the pragmas. Module headers can't go below imports or top-level bindings. Similarly imports can't go below top-level bindings and they can't go above the module header.

Ericson2314 commented 2 years ago

Should close #34 or this as duplicates?

Ericson2314 commented 2 years ago

(copied from #34 as requested)

I think the idea is that this first does parse, because of those dastardly TH implicit top level splices, and then this warning is issued.

If so, I think that does in fact mean we have enough info to make this error better: as we comb through the list of "rawer top-level items", we can vary what we suggest based on what we've already seen.

This fits well with the general principle rather than parsing an AST in nearly one pass, very incrementally parse into increasingly less liberal ASTs, starting with a super liberal one, so we get better errors.