Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--ghc-option -freverse-errors is not passed to GHC #10401

Closed
toonn opened this issue Oct 1, 2024 · 9 comments
Closed

--ghc-option -freverse-errors is not passed to GHC #10401

toonn opened this issue Oct 1, 2024 · 9 comments

Comments

@toonn
Copy link
Contributor

toonn commented Oct 1, 2024

Describe the bug

I'm doing some iterative development, things are stubbed out and I'm filling things in a couple definitions at a time. Later definitions often depend on earlier ones so I prefer working through compilation errors in order but without scrolling up through all the output every time.

-freverse-errors should be good enough for now. But I'm unable to make it work with cabal-install, cabal --ghc-option -freverse-errors run test:Course has no effect.

To Reproduce
Steps to reproduce the behavior:

I ran cabal init and stuck with defaults as much as possible to set up a minimally reproducing example (I think these two are the only necessary files, let me know if you need more, I have a cabal.project because I nested this inside another project and otherwise cabal-install picks that up):

==> MRE.cabal <==
cabal-version:      3.0
name:               MRE
version:            0.1.0.0
-- synopsis:
-- description:
license:            BSD-2-Clause
license-file:       LICENSE
author:             toonn
maintainer:         codeberg@toonn.io
-- copyright:
category:           Testing
build-type:         Simple
extra-doc-files:    CHANGELOG.md
-- extra-source-files:

common warnings
    ghc-options: -Wall

executable MRE
    import:           warnings
    main-is:          Main.hs
    -- other-modules:
    -- other-extensions:
    build-depends:    base ^>=4.18.2.1
    hs-source-dirs:   app
    default-language: Haskell2010

==> app/Main.hs <==
module Main where

a :: a -> a
a _ = "(Probably) not type a"

b :: [a] -> [a]
b x y = x ++ y

main :: IO ()
main = do
  putStrLn ("First error: " ++ a 1)
  putStrLn ("Second error: " ++ show (b [1] [2]))
$ cabal --ghc-option -freverse-errors run exe:MRE

Expected behavior

I expected similar output to GHC when this option is passed:

[1 of 2] Compiling Main             ( app/Main.hs, app/Main.o )

app/Main.hs:12:39: error: [GHC-83865]
    • Couldn't match expected type: [a2] -> a0
                  with actual type: [a1]
    • The function ‘b’ is applied to two value arguments,
        but its type ‘[a1] -> [a1]’ has only one
      In the first argument of ‘show’, namely ‘(b [1] [2])’
      In the second argument of ‘(++)’, namely ‘show (b [1] [2])’
   |
12 |   putStrLn ("Second error: " ++ show (b [1] [2]))
   |                                       ^^^^^^^^^

app/Main.hs:7:1: error: [GHC-83865]
    • Couldn't match expected type: [a]
                  with actual type: [a] -> [a]
    • The equation for ‘b’ has two value arguments,
        but its type ‘[a] -> [a]’ has only one
    • Relevant bindings include
        b :: [a] -> [a] (bound at app/Main.hs:7:1)
  |
7 | b x y = x ++ y
  | ^^^^^^^^^^^^^^

app/Main.hs:4:7: error: [GHC-25897]
    • Couldn't match expected type ‘a’ with actual type ‘String’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          a :: forall a. a -> a
        at app/Main.hs:3:1-11
    • In the expression: "(Probably) not type a"
      In an equation for ‘a’: a _ = "(Probably) not type a"
    • Relevant bindings include a :: a -> a (bound at app/Main.hs:4:1)
  |
4 | a _ = "(Probably) not type a"
  |       ^^^^^^^^^^^^^^^^^^^^^^^

However, cabal-install seems to ignore the option altogether:

Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - MRE-0.1.0.0 (exe:MRE) (first run)
Preprocessing executable 'MRE' for MRE-0.1.0.0..
Building executable 'MRE' for MRE-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/toonn/src/Data61-fp-course/MRE/dist-newstyle/build/x86_64-linux/ghc-9.6.5/MRE-0.1.0.0/x/MRE/build/MRE/MRE-tmp/Main.o )

app/Main.hs:4:7: error: [GHC-25897]
    • Couldn't match expected type ‘a’ with actual type ‘String’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          a :: forall a. a -> a
        at app/Main.hs:3:1-11
    • In the expression: "(Probably) not type a"
      In an equation for ‘a’: a _ = "(Probably) not type a"
    • Relevant bindings include a :: a -> a (bound at app/Main.hs:4:1)
  |
4 | a _ = "(Probably) not type a"
  |       ^^^^^^^^^^^^^^^^^^^^^^^

app/Main.hs:7:1: error: [GHC-83865]
    • Couldn't match expected type: [a]
                  with actual type: [a] -> [a]
    • The equation for ‘b’ has two value arguments,
        but its type ‘[a] -> [a]’ has only one
    • Relevant bindings include
        b :: [a] -> [a] (bound at app/Main.hs:7:1)
  |
7 | b x y = x ++ y
  | ^^^^^^^^^^^^^^

app/Main.hs:12:39: error: [GHC-83865]
    • Couldn't match expected type: [a2] -> a0
                  with actual type: [a1]
    • The function ‘b’ is applied to two value arguments,
        but its type ‘[a1] -> [a1]’ has only one
      In the first argument of ‘show’, namely ‘(b [1] [2])’
      In the second argument of ‘(++)’, namely ‘show (b [1] [2])’
   |
12 |   putStrLn ("Second error: " ++ show (b [1] [2]))
   |                                       ^^^^^^^^^

System information

  • Operating system:
> uname -a
Linux yorp 6.6.52 #1-NixOS SMP PREEMPT_DYNAMIC Wed Sep 18 17:24:10 UTC 2024 x86_64 GNU/Linux
  • cabal, ghc versions:
> cabal --version; ghc --version
cabal-install version 3.10.3.0
compiled using version 3.10.3.0 of the Cabal library 
The Glorious Glasgow Haskell Compilation System, version 9.6.5

Additional context
Add any other context about the problem here.

@ulysses4ever
Copy link
Collaborator

No matter how I try, I can't reproduce it :-(

❯  ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.6.5

❯ cabal --version
cabal-install version 3.10.3.0
compiled using version 3.10.3.0 of the Cabal library 

❯ cat app/Main.hs 
f = 1 + a

main = f + g

❯ cabal clean && cabal --ghc-option -freverse-errors run exe:cabal-flags
Warning: The package list for 'hackage.haskell.org' is 23 days old.
Run 'cabal update' to get the latest list of available packages.
Resolving dependencies...
Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - cabal-flags-0.1.0.0 (exe:cabal-flags) (first run)
Configuring executable 'cabal-flags' for cabal-flags-0.1.0.0..
Preprocessing executable 'cabal-flags' for cabal-flags-0.1.0.0..
Building executable 'cabal-flags' for cabal-flags-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/artem/tmp/cabal-flags/dist-newstyle/build/x86_64-linux/ghc-9.6.5/cabal-flags-0.1.0.0/x/cabal-flags/build/cabal-flags/cabal-flags-tmp/Main.o )

app/Main.hs:3:12: error: [GHC-88464] Variable not in scope: g
  |
3 | main = f + g
  |            ^

app/Main.hs:1:9: error: [GHC-88464] Variable not in scope: a
  |
1 | f = 1 + a
  |         ^

@toonn
Copy link
Contributor Author

toonn commented Oct 10, 2024

@ulysses4ever, are you on Linux too? Maybe cabal.project being present affects this? My cabal-install and GHC are installed using Nix but I find it hard to believe the packaging affects the behavior of cabal-install.

I don't know what other part of the environment might affect this.

@ulysses4ever
Copy link
Collaborator

@toonn I am on Linux, and, more specifically, NixOS. My GHC and cabal-install (in this experiment) also come from nxpkgs.

It does work with cabal.project as expected for me.

I'm lost too. Could you perhaps give it another try using my little reproducer (with cabal.project) here: https://github.com/ulysses4ever/cabal-issue-10401 ? You only need to clone it, do cabal update && cabal clean && cabal run exe:cabal-flags, and check the order of errors.

@toonn
Copy link
Contributor Author

toonn commented Oct 16, 2024

Ah, that's where the confusion is!
You're passing the ghc-option from the Cabal file but that's not what my report is about.

My reproducer command is the following:

$ cabal --ghc-option -freverse-errors run exe:MRE

If you pass -fno-reverse-errors instead or remove the ghc-option from the Cabal file, you'll see that cabal-install does not respect the command-line option.

@ulysses4ever
Copy link
Collaborator

You may be a little off with the terminology here: "the Cabal file" is cabal-flags.cabal, and it does not have -freverse-errors. Perhaps, you mean "the project file", cabal.project. I used it because in your report you mentioned it. But, as I mentioned above, it doesn't make a difference for me. In particular, if I remove the flag from the project file and run the equivalent command, I see the errors in the reverse order:

cabal-flags on  main [?] via λ 9.6.5 took 7s 
❯ cat cabal.project 
packages: .
cabal-flags on  main [?] via λ 9.6.5 
❯ cabal --version
cabal-install version 3.10.3.0
compiled using version 3.10.3.0 of the Cabal library 

cabal-flags on  main [?] via λ 9.6.5 
❯ cabal clean

cabal-flags on  main via λ 9.6.5 
❯ cabal --ghc-option -freverse-errors run
Warning: Parsing the index cache failed (Data.Binary.Get.runGet at position
16: Non-matching structured hashes: d81bdd513f41b5d7ee4cd28455adadbe;
expected: f46da61e7afa58a5e8fd1d2b6fb79899). Trying to regenerate the index
cache...
Resolving dependencies...
Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - cabal-flags-0.1.0.0 (exe:cabal-flags) (first run)
Configuring executable 'cabal-flags' for cabal-flags-0.1.0.0..
Preprocessing executable 'cabal-flags' for cabal-flags-0.1.0.0..
Building executable 'cabal-flags' for cabal-flags-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/artem/tmp/cabal-flags/dist-newstyle/build/x86_64-linux/ghc-9.6.5/cabal-flags-0.1.0.0/x/cabal-flags/build/cabal-flags/cabal-flags-tmp/Main.o )

app/Main.hs:3:12: error: [GHC-88464] Variable not in scope: g
  |
3 | main = f + g
  |            ^

app/Main.hs:1:9: error: [GHC-88464] Variable not in scope: a
  |
1 | f = 1 + a
  |         ^

I updated the repo (https://github.com/ulysses4ever/cabal-issue-10401) to not use the flag in the project file, so you should be able to repro it as shown above. Please, try it locally yourself and show me the output.

@toonn
Copy link
Contributor Author

toonn commented Oct 16, 2024

I don't think I mixed up the terminology, I do mean cabal-flags.cabal when I say "the Cabal file." And before that last commit it did contain the -freverse-errors ghc-option so I'm not sure what you mean.

This works as expected:

> nix-shell -p cabal-install ghc

[nix-shell:~/src/cabal-issue-10401]$ cabal --ghc-option -freverse-errors run exe:cabal-flags
Warning: The package list for 'hackage.haskell.org' is 93 days old.
Run 'cabal update' to get the latest list of available packages.
Resolving dependencies...
Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - cabal-flags-0.1.0.0 (exe:cabal-flags) (first run)
Configuring executable 'cabal-flags' for cabal-flags-0.1.0.0..
Preprocessing executable 'cabal-flags' for cabal-flags-0.1.0.0..
Building executable 'cabal-flags' for cabal-flags-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/toonn/src/cabal-issue-10401/dist-newstyle/build/x86_64-linux/ghc-9.6.5/cabal-flags-0.1.0.0/x/cabal-flags/build/cabal-flags/cabal-flags-tmp/Main.o )

app/Main.hs:3:12: error: [GHC-88464] Variable not in scope: g
  |
3 | main = f + g
  |            ^

app/Main.hs:1:9: error: [GHC-88464] Variable not in scope: a
  |
1 | f = 1 + a
  |         ^

But these don't:

[nix-shell:~/src/cabal-issue-10401]$ cabal run exe:cabal-flags
Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - cabal-flags-0.1.0.0 (exe:cabal-flags) (first run)
Preprocessing executable 'cabal-flags' for cabal-flags-0.1.0.0..
Building executable 'cabal-flags' for cabal-flags-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/toonn/src/cabal-issue-10401/dist-newstyle/build/x86_64-linux/ghc-9.6.5/cabal-flags-0.1.0.0/x/cabal-flags/build/cabal-flags/cabal-flags-tmp/Main.o )

app/Main.hs:3:12: error: [GHC-88464] Variable not in scope: g
  |
3 | main = f + g
  |            ^

app/Main.hs:1:9: error: [GHC-88464] Variable not in scope: a
  |
1 | f = 1 + a
  |         ^

[nix-shell:~/src/cabal-issue-10401]$ cabal --ghc-option -fno-reverse-errors run exe:cabal-flags
Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - cabal-flags-0.1.0.0 (exe:cabal-flags) (first run)
Preprocessing executable 'cabal-flags' for cabal-flags-0.1.0.0..
Building executable 'cabal-flags' for cabal-flags-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/toonn/src/cabal-issue-10401/dist-newstyle/build/x86_64-linux/ghc-9.6.5/cabal-flags-0.1.0.0/x/cabal-flags/build/cabal-flags/cabal-flags-tmp/Main.o )

app/Main.hs:3:12: error: [GHC-88464] Variable not in scope: g
  |
3 | main = f + g
  |            ^

app/Main.hs:1:9: error: [GHC-88464] Variable not in scope: a
  |
1 | f = 1 + a
  |         ^

So what seems to be happening is cabal-install respects whatever options are passed to the first build but then maintains those?

Re-cloning the repo does corroborate this a bit:

[nix-shell:~/src/cabal-issue-10401]$ cabal run exe:cabal-flags  
Warning: The package list for 'hackage.haskell.org' is 93 days old.
Run 'cabal update' to get the latest list of available packages.                Resolving dependencies...                                                       Build profile: -w ghc-9.6.5 -O1                                                 
In order, the following will be built (use -v for more details):
 - cabal-flags-0.1.0.0 (exe:cabal-flags) (first run)        
Configuring executable 'cabal-flags' for cabal-flags-0.1.0.0..
Preprocessing executable 'cabal-flags' for cabal-flags-0.1.0.0..
Building executable 'cabal-flags' for cabal-flags-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/toonn/src/cabal-issue-1
0401/dist-newstyle/build/x86_64-linux/ghc-9.6.5/cabal-flags-0.1.0.0/x/cabal-flag
s/build/cabal-flags/cabal-flags-tmp/Main.o )
                    
app/Main.hs:1:9: error: [GHC-88464] Variable not in scope: a
  |
1 | f = 1 + a                           
  |         ^

app/Main.hs:3:12: error: [GHC-88464] Variable not in scope: g
  |
3 | main = f + g
  |            ^

[nix-shell:~/src/cabal-issue-10401]$ cabal --ghc-options -freverse-errors run exe:cabal-flags
Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - cabal-flags-0.1.0.0 (exe:cabal-flags) (first run)
Preprocessing executable 'cabal-flags' for cabal-flags-0.1.0.0..
Building executable 'cabal-flags' for cabal-flags-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/toonn/src/cabal-issue-10401/dist-newstyle/build/x86_64-linux/ghc-9.6.5/cabal-flags-0.1.0.0/x/cabal-flags/build/cabal-flags/cabal-flags-tmp/Main.o )

app/Main.hs:1:9: error: [GHC-88464] Variable not in scope: a
  |
1 | f = 1 + a
  |         ^

app/Main.hs:3:12: error: [GHC-88464] Variable not in scope: g
  |
3 | main = f + g
  |

This is a lot more confusing than I expected TBH. And technically it's not true that cabal-install doesn't respect the option. However, there's clearly something screwy going on here.

@ulysses4ever
Copy link
Collaborator

... I do mean cabal-flags.cabal when I say "the Cabal file." And before that last commit it did contain the -freverse-errors ghc-option

You can inspect the last commit (ulysses4ever/cabal-issue-10401@610a3f5) to make sure that cabal-flags.cabal was not touched.

So what seems to be happening is cabal-install respects whatever options are passed to the first build but then maintains those?

Yes, this is a caching issue known as #7816, so I'll close this as a dup if you don't mind. A workaround is to do cabal clean manually before you change --ghc-options.

@toonn
Copy link
Contributor Author

toonn commented Oct 17, 2024

You're right, I saw the common stanza with a ghc-options key and did not look any closer.

I'll start following that issue, thanks.

@ulysses4ever
Copy link
Collaborator

You're right, I saw the common stanza with a ghc-options key and did not look any closer.

Ah, that's alright. The stanza is a product of cabal init—the fastest way to start a project from scratch. However, it's not ideal for minimal working examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants