Skip to content

Introduce new default Curry case mode and factor out CaseModeCheck

Fredrik Wieczerkowski requested to merge case-mode-check into master

Fixes #140 (closed), fixes #141 (closed)

This PR tackles the two issues via the following four major changes:

  • A new default case mode (curry) is introduced, which behaves like haskell, but emits warnings for wrong casings
  • The existing case modes (haskell, prolog, goedel) are made stricter by emitting errors instead of warnings
  • The case mode logic is factored out from the WarnCheck into a separate CaseModeCheck
  • The messages emitted by the new CaseModeCheck are made more descriptive

To illustrate, here is an example program:

data x = a

f :: A -> A
f X = X

Previous Situation

Compiling the program would not emit any errors or warnings due to the default case mode free. Even with -c haskell, the user would get relatively obscure warnings that make sense if the user is already familiar with Curry's case modes, but can appear confusing if not:

src/CaseMode.curry:3:6 Warning:
    Wrong case mode in symbol `x' due to selected case mode `haskell`, try renaming to X instead
   | 
 3 | data x = a
   |      ^

src/CaseMode.curry:3:10 Warning:
    Wrong case mode in symbol `a' due to selected case mode `haskell`, try renaming to A instead
   | 
 3 | data x = a
   |          ^

src/CaseMode.curry:5:6 Warning:
    Wrong case mode in symbol `A' due to selected case mode `haskell`, try renaming to a instead
   | 
 5 | f :: A -> A
   |      ^

src/CaseMode.curry:5:11 Warning:
    Wrong case mode in symbol `A' due to selected case mode `haskell`, try renaming to a instead
   | 
 5 | f :: A -> A
   |           ^

src/CaseMode.curry:6:3 Warning:
    Wrong case mode in symbol `X' due to selected case mode `haskell`, try renaming to x instead
   | 
 6 | f X = X
   |   ^

After this PR

After this PR, what the user will see in the default case mode (curry) is the following:

src/CaseMode.curry:3:6 Warning:
    Symbol `x' is a data declaration name, but the selected case mode is `curry`, try renaming to X instead
   | 
 3 | data x = a
   |      ^

src/CaseMode.curry:3:10 Warning:
    Symbol `a' is a constructor name, but the selected case mode is `curry`, try renaming to A instead
   | 
 3 | data x = a
   |          ^

src/CaseMode.curry:5:6 Warning:
    Symbol `A' is a variable name, but the selected case mode is `curry`, try renaming to a instead
   | 
 5 | f :: A -> A
   |      ^

src/CaseMode.curry:5:11 Warning:
    Symbol `A' is a variable name, but the selected case mode is `curry`, try renaming to a instead
   | 
 5 | f :: A -> A
   |           ^

src/CaseMode.curry:6:3 Warning:
    Symbol `X' is a variable name, but the selected case mode is `curry`, try renaming to x instead
   | 
 6 | f X = X
   |   ^

The messages immediately point out that the symbols are variables (not e.g. promoted constructors or other types). Users can still opt into the classic behavior via -c free to disable all warnings/errors about casings, the defaults should now be much less confusing to programmers familiar with Haskell syntax though.

Merge request reports