haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.62k stars 691 forks source link

`cabal build` works, but `cabal repl` has an error. #7696

Open kindaro opened 3 years ago

kindaro commented 3 years ago

Describe the bug

I want to do something with QuickCheck. I cloned the current version from the repository. I see a strange problem: cabal build works, but cabal repl has an error when compiling Test.QuickCheck.All. This problem appears both with GHC 8.10.7 and 9.0.1.

See details… % cabal clean % cabal build Resolving dependencies... Build profile: -w ghc-9.0.1 -O1 In order, the following will be built (use -v for more details): - QuickCheck-2.14.2 (lib) (first run) Configuring library for QuickCheck-2.14.2.. Preprocessing library for QuickCheck-2.14.2.. Building library for QuickCheck-2.14.2.. [ 1 of 16] Compiling Test.QuickCheck.Exception ( src/Test/QuickCheck/Exception.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Exception.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Exception.dyn_o ) [ 2 of 16] Compiling Test.QuickCheck.Random ( src/Test/QuickCheck/Random.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Random.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Random.dyn_o ) [ 3 of 16] Compiling Test.QuickCheck.Gen ( src/Test/QuickCheck/Gen.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Gen.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Gen.dyn_o ) [ 4 of 16] Compiling Test.QuickCheck.Gen.Unsafe ( src/Test/QuickCheck/Gen/Unsafe.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Gen/Unsafe.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Gen/Unsafe.dyn_o ) [ 5 of 16] Compiling Test.QuickCheck.Arbitrary ( src/Test/QuickCheck/Arbitrary.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Arbitrary.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Arbitrary.dyn_o ) [ 6 of 16] Compiling Test.QuickCheck.Poly ( src/Test/QuickCheck/Poly.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Poly.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Poly.dyn_o ) [ 7 of 16] Compiling Test.QuickCheck.Modifiers ( src/Test/QuickCheck/Modifiers.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Modifiers.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Modifiers.dyn_o ) [ 8 of 16] Compiling Test.QuickCheck.Function ( src/Test/QuickCheck/Function.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Function.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Function.dyn_o ) [ 9 of 16] Compiling Test.QuickCheck.Text ( src/Test/QuickCheck/Text.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Text.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Text.dyn_o ) [10 of 16] Compiling Test.QuickCheck.State ( src/Test/QuickCheck/State.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/State.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/State.dyn_o ) [11 of 16] Compiling Test.QuickCheck.Property ( src/Test/QuickCheck/Property.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Property.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Property.dyn_o ) [12 of 16] Compiling Test.QuickCheck.Test ( src/Test/QuickCheck/Test.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Test.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Test.dyn_o ) [13 of 16] Compiling Test.QuickCheck.Monadic ( src/Test/QuickCheck/Monadic.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Monadic.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Monadic.dyn_o ) [14 of 16] Compiling Test.QuickCheck.All ( src/Test/QuickCheck/All.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/All.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/All.dyn_o ) [15 of 16] Compiling Test.QuickCheck.Features ( src/Test/QuickCheck/Features.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Features.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck/Features.dyn_o ) [16 of 16] Compiling Test.QuickCheck ( src/Test/QuickCheck.hs, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck.o, /tmp/quickcheck/dist-newstyle/build/x86_64-linux/ghc-9.0.1/QuickCheck-2.14.2/build/Test/QuickCheck.dyn_o ) % cabal repl Build profile: -w ghc-9.0.1 -O1 In order, the following will be built (use -v for more details): - QuickCheck-2.14.2 (lib) (ephemeral targets) Preprocessing library for QuickCheck-2.14.2.. GHCi, version 9.0.1: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/kindaro/code/dotfiles/ghci.conf [ 1 of 16] Compiling Test.QuickCheck.Exception ( src/Test/QuickCheck/Exception.hs, interpreted ) [ 2 of 16] Compiling Test.QuickCheck.Random ( src/Test/QuickCheck/Random.hs, interpreted ) [ 3 of 16] Compiling Test.QuickCheck.Gen ( src/Test/QuickCheck/Gen.hs, interpreted ) [ 4 of 16] Compiling Test.QuickCheck.Gen.Unsafe ( src/Test/QuickCheck/Gen/Unsafe.hs, interpreted ) [ 5 of 16] Compiling Test.QuickCheck.Arbitrary ( src/Test/QuickCheck/Arbitrary.hs, interpreted ) [ 6 of 16] Compiling Test.QuickCheck.Poly ( src/Test/QuickCheck/Poly.hs, interpreted ) [ 7 of 16] Compiling Test.QuickCheck.Modifiers ( src/Test/QuickCheck/Modifiers.hs, interpreted ) [ 8 of 16] Compiling Test.QuickCheck.Function ( src/Test/QuickCheck/Function.hs, interpreted ) [ 9 of 16] Compiling Test.QuickCheck.Text ( src/Test/QuickCheck/Text.hs, interpreted ) [10 of 16] Compiling Test.QuickCheck.State ( src/Test/QuickCheck/State.hs, interpreted ) [11 of 16] Compiling Test.QuickCheck.Property ( src/Test/QuickCheck/Property.hs, interpreted ) [12 of 16] Compiling Test.QuickCheck.Test ( src/Test/QuickCheck/Test.hs, interpreted ) [13 of 16] Compiling Test.QuickCheck.Monadic ( src/Test/QuickCheck/Monadic.hs, interpreted ) [14 of 16] Compiling Test.QuickCheck.All ( src/Test/QuickCheck/All.hs, interpreted ) src/Test/QuickCheck/All.hs:77:39: error: • Couldn't match type ‘a0’ with ‘a’ Expected: String -> a Actual: [Char] -> a0 because type variable ‘a’ would escape its scope This (rigid, skolem) type variable is bound by a type expected by the context: Error at src/Test/QuickCheck/All.hs:77:39-41 • In the first argument of ‘deconstructType’, namely ‘err’ In a stmt of a 'do' block: (polys, ctx, ty) <- deconstructType err ty0 In the expression: do ty0 <- fmap infoType (reify t) let err msg = error $ msg ++ ": " ++ pprint ty0 (polys, ctx, ty) <- deconstructType err ty0 case polys of [] -> return (expName t) _ -> do ... • Relevant bindings include err :: [Char] -> a0 (bound at src/Test/QuickCheck/All.hs:76:7) | 77 | (polys, ctx, ty) <- deconstructType err ty0 | ^^^ src/Test/QuickCheck/All.hs:82:31: error: • Couldn't match type ‘a0’ with ‘a’ Expected: String -> a Actual: [Char] -> a0 because type variable ‘a’ would escape its scope This (rigid, skolem) type variable is bound by a type expected by the context: Error at src/Test/QuickCheck/All.hs:82:31-33 • In the first argument of ‘monomorphiseType’, namely ‘err’ In a stmt of a 'do' block: ty' <- monomorphiseType err integer ty In the expression: do integer <- [t| Integer |] ty' <- monomorphiseType err integer ty return (SigE (expName t) ty') • Relevant bindings include err :: [Char] -> a0 (bound at src/Test/QuickCheck/All.hs:76:7) | 82 | ty' <- monomorphiseType err integer ty | ^^^ Failed, 13 modules loaded. λ Leaving GHCi.

To Reproduce

Clone the repository of QuickCheck at the commit 7ff70fe. Run cabal repl.

Expected behavior

I expect that all modules compile without error in the repl, since they compile without error when running cabal build.

System information

% cabal --version
cabal-install version 3.6.0.0
compiled using version 3.6.1.0 of the Cabal library
Mikolaj commented 3 years ago

Thank you for the report. Is it the same with with cabal exec cabal repl or cabal exec ghci or ghci alone or whatever else people use? I wonder if this might be a GHC error.

kindaro commented 3 years ago

I am not sure I understand what you want me to do. I can build the package and then run cabal exec ghci — it works alright:

% cabal clean
% cabal build
…
% cabal exec ghci
GHCi, version 8.10.7: https://www.haskell.org/ghc/  :? for help
Loaded package environment from /tmp/quickcheck/dist-newstyle/tmp/environment.-385457/.ghc.environment.x86_64-linux-8.10.7
Loaded package environment from /tmp/quickcheck/dist-newstyle/tmp/environment.-385457/.ghc.environment.x86_64-linux-8.10.7
Loaded GHCi configuration from /home/kindaro/code/dotfiles/ghci.conf
λ import Test.QuickCheck
λ import Test.QuickCheck.All
λ 
Leaving GHCi.
gbaz commented 3 years ago

I'm willing to bet the custom flags set in ghci.conf cause the code to compile differently.

jneira commented 3 years ago

Just in case i've tried to reproduce it with cabal-3.4.0.0 and 3.6.0.0 and i was not able to do it. No ghc env files nor ghci.conf one in my side.

kindaro commented 3 years ago

Yes, if I remove ~/.ghc/ghci.conf then cabal repl succeeds.

Here is the file. % cat ~/.ghc/ghci.conf :set prompt "λ " :set prompt-cont "> " :set +m :set -fdefer-typed-holes :set -fdiagnostics-color=always :set -Wpartial-type-signatures :set -XUnicodeSyntax :set -XBlockArguments :set -XTypeApplications :set -XPartialTypeSignatures :set -XFlexibleInstances :set -XFlexibleContexts :set -XMultiParamTypeClasses :set -XFunctionalDependencies :set -XRankNTypes :set -XDataKinds :set -XKindSignatures :set -XTypeOperators :set -XTypeFamilies :set -XTypeFamilyDependencies :set -XImportQualifiedPost :set -XTupleSections

Should I always do cabal build && cabal exec ghci from now on? I like my ghci.conf and I should like to keep it. Or I could write a wrapper for Cabal that carefully stashes ghci.conf in a pocket before calling Cabal and puts it back it after Cabal is done.

jneira commented 2 years ago

Afaiu cabal repl fail due to some of the language extensions set in ghci.conf. So if you could invoke ghci on that package without cabal (via a global packagedb or ghc environment files) it would fail in the same way. Is that the case? If it is so, what could do cabal to avoid that error?

kindaro commented 2 years ago
  1. Yes, axually I can do this:

    % cabal exec sh sh-5.1$ ghci src/Test/QuickCheck/All.hs

    — And see the same compilation error.

  2. Maybe some of:

    1. Cabal could make it easy for me to run cabal repl from anywhere with my favourite set of language extensions. Maybe #6481 can address this problem. Then I could remove ~/.ghc/ghci.conf and instead call cabal repl, so that Cabal reads default extensions from the default cabal manifest and gives them to ghci.
    2. Cabal could ask GHC to ignore ~/ghc/ghci.conf, and GHC could coöperate.
    3. Cabal could override all GHC extension flags to their default state when running ghci.
jneira commented 2 years ago

Thanks for the confirmation and the proposals

Cabal could make it easy for me to run cabal repl from anywhere with my favourite set of language extensions. Maybe https://github.com/haskell/cabal/issues/6481 can address this problem. Then I could remove ~/.ghc/ghci.conf and instead call cabal repl, so that Cabal reads default extensions from the default cabal manifest and gives them to ghci.

But your favourite set of language extensions are the ones in the ghci.conf and those made the load fail for that package, no? So that list of extension would made fail cabal if it picks them from other source. Otoh you can have other ghci configuration (prompt and other things) which would be good to keep.

Cabal could ask GHC to ignore ~/ghc/ghci.conf, and GHC could coöperate. Cabal could override all GHC extension flags to their default state when running ghci.

Those ones will drive to unexpected behaviour and break actual workflows for users relying in ~/.ghc/ghci.conf

Possible solution:

kindaro commented 2 years ago

Thanks for the confirmation and the proposals

At your service!

But your favourite set of language extensions are the ones in the ghci.conf and those made the load fail for that package, no?

Yes, but I only need my favourite language extensions to be present in ~/.ghc/ghci.conf when running ghci outside of any package. If instead I could run cabal repl with a default package, my favourite language extensions would live in that package's cabal manifest. So, there is no problem: I should have my extensions when outside of any package, and the relevant package's extensions when inside a project.

So that list of extension would made fail cabal if it picks them from other source. Otoh you can have other ghci configuration (prompt and other things) which would be good to keep.

So, what I am saying is that ideally only one place should be a source of truth as regards language extensions. Then there could be no mistake.

Cabal could ask GHC to ignore ~/ghc/ghci.conf, and GHC could coöperate. Cabal could override all GHC extension flags to their default state when running ghci.

Those ones will drive to unexpected behaviour and break actual workflows for users relying in ~/.ghc/ghci.conf

Cabal already has unexpected behaviour and breaks actual workflows for users relying in ~/.ghc/ghci.conf. (Me for example.) You have to be honest here and say either that:

Possible solution:

Sure, I can solve this problem for this specific case one way or another. I can figure out which language extension is causing this version of GHC to decline this version of QuickCheck, and disable that specific extension.

phadej commented 2 years ago

@kindaro use :seti, don't use :set.

kindaro commented 2 years ago

@phadej   Thank you Oleg for your thoughtful advice.

Unfortunately, my workflows rely on there being :set and not :seti. For example:

% cat X.hs
main ∷ IO ( )
main = putStrLn "Hello world"
% ghci X.hs
GHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/kindaro/code/dotfiles/ghci.conf
[1 of 1] Compiling Main             ( X.hs, interpreted )
Ok, one module loaded.
λ 

— This relies on the extension UnicodeSyntax being enabled during compilation (note the Unicode symbol in the type signature), which rules out :seti. Similarly for other extensions I want to have enabled by default.

Aside from that, I should note that your response carries the air of talking down to me and dismissing my problem. You can greatly increase my willingness to report issues I might have with Cabal in the future by acknowledging the problem and framing your advice as an advice and not as a dismissive order.

phadej commented 2 years ago

Then, I'm afraid, you cannot have your cake and eat it too. Settings set with :set -XFoo affect how GHC interprets modules, and Cabal has no means to tell GHC to load some modules without .ghci commands effects (*and subsequent :reloads), i.e. just using what .cabal file prescribes, and then tell GHCi to interpret .ghci.

The only thing Cabal could do, is to tell GHC to completely ignore .ghci file, I think you won't like that either.

jneira commented 2 years ago

Cabal promised from the outset to support arbitrary ~/.ghc/ghci.conf. Then Cabal is already breaking its promise to me.

It breaks its promises adding its language extensions to ghci.conf ones? or in other ways?

Cabal never promised to support arbitrary ~/.ghc/ghci.conf. Then Cabal can choose any behaviour without breaking any promises.

The only thing Cabal could do, is to tell GHC to completely ignore .ghci file, I think you won't like that either

Those are compatible but it will break lot of things out there so it should be guarded by a flag or something

What about set --ghc-options="-ignore-dot-ghci"?, not sure if that will work but you could set that in your global,project or package config

So, what I am saying is that ideally only one place should be a source of truth as regards language extensions. Then there could be no mistake.

That is an interesting argument, I guess it should apply to everything in which config.ghci and cabal could collide

kindaro commented 2 years ago

Cabal promised from the outset to support arbitrary ~/.ghc/ghci.conf. Then Cabal is already breaking its promise to me.

It breaks its promises adding its language extensions to ghci.conf ones? or in other ways?

If Cabal promises that its commands will work across installations (including modules being both compiled and interpreted) then its commands should work (and fail) uniformly across installations. For example, if Nick can load some modules in the read-evaluate-print loop, then Ignat should be able to do it too, given that they run from within the two clones of the same package and with the same version of GHC.

So, if Cabal promises that, then Cabal should take care of the possibility that ~/.ghc/ghci.conf sets some language extensions that are usually harmless but have adverse effect in a few edge cases. If, on the other hand, Cabal does not promise that, then Cabal is free to take care of this possibility. In any case, Cabal is not forbidden to take care of this possibility.


Then, I'm afraid, you cannot have your cake and eat it too. Settings set with :set -XFoo affect how GHC interprets modules, and Cabal has no means to tell GHC to load some modules without .ghci commands effects (*and subsequent :reloads), i.e. just using what .cabal file prescribes, and then tell GHCi to interpret .ghci.

The only thing Cabal could do, is to tell GHC to completely ignore .ghci file, I think you won't like that either.

But Cabal has the means to tell GHC to load arbitrary scripts. For example, it can ask GHC to load a script that resets all language extensions to their default state. Even if there was no special flag for this case (and there is — -ghci-script), Cabal has control over the standard input of the ghci process — it can do anything. Even if that was not the case, we could ask the GHC people to add a feature to this end. Surely it is not a problem in principle to tell GHC which extensions to enable and which to disable!

phadej commented 2 years ago

For example, it can ask GHC to load a script that resets all language extensions to their default state.

How? AFAIK that is not possible. (Please link to GHC documentation. or give an explicit example). Note that Cabal invokes ghci as a single command, and doesn't "execute" any command inside the repl.

bacchanalia commented 2 years ago

cabal already passes a script to ghci when invoking cabal repl outside of project context to set the working directory properly because of the fake-package machinery, so that capability definitely exists

kindaro commented 2 years ago

For example, it can ask GHC to load a script that resets all language extensions to their default state.

How? AFAIK that is not possible. (Please link to GHC documentation. or give an explicit example).

Here is an example where I reset UnicodeSyntax to default:

(Recall that I have UnicodeSyntax enabled in ~/.ghc/ghci.conf.)

% cat X.hs
main ∷ IO ( )
main = putStrLn "Hello world"
% cat reset.ghci
:set -XNoUnicodeSyntax
% ghci X.hs
GHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/kindaro/code/dotfiles/ghci.conf
[1 of 1] Compiling Main             ( X.hs, interpreted ) [flags changed]
Ok, one module loaded.
λ 
Leaving GHCi.
% ghci -ghci-script reset.ghci X.hs
GHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/kindaro/code/dotfiles/ghci.conf
Loaded GHCi configuration from reset.ghci
[1 of 1] Compiling Main             ( X.hs, interpreted ) [flags changed]

X.hs:1:1: error:
    Parse error: module header, import declaration
    or top-level declaration expected.
  |
1 | main ∷ IO ( )
  | ^^^^^^^^^^^^^
Failed, no modules loaded.
λ 
Leaving GHCi.

Now it is only a matter of preparing the scripts.

Note that Cabal invokes ghci as a single command, and doesn't "execute" any command inside the repl.

Is there something to stop me from making it do that? I can even do it from the command line:

% ghci <<EOF
heredoc> :set -XNoUnicodeSyntax
heredoc> :load X
heredoc> EOF
GHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/kindaro/code/dotfiles/ghci.conf
λ λ [1 of 1] Compiling Main             ( X.hs, interpreted ) [flags changed]

X.hs:1:1: error:
    Parse error: module header, import declaration
    or top-level declaration expected.
  |
1 | main ∷ IO ( )
  | ^^^^^^^^^^^^^
Failed, no modules loaded.
λ Leaving GHCi.

What is going on?

Oleg, I get that you have a lot of experience hacking on Cabal. But I do not understand what you are trying to say. It is hard for me to believe that you find it hard to implement a solution to this issue. Surely it is easy for you.

What is making you so grim?

phadej commented 2 years ago

cabal already passes a script to ghci when invoking cabal repl outside of project context to set the working directory properly because of the fake-package machinery, so that capability definitely exists

That script is (AFAIK) executed after ~/ghc/ghci.conf is loaded, and therefore if we e.g. do something like -XNoTypeApplications it:

It is hard for me to believe that you find it hard to implement a solution to this issue.

This is not an issue which we should hack around in Cabal. GHC should provide the means to do it, but I don't see how it can be done now.

phadej commented 2 years ago

If such a tiny problem cannot be solved easily, then maybe some code in the Cabal code base needs to be refactored?

I try to say it should be "fixed" in GHC, to allow module loading before .ghci.conf is applied. (And somehow that should make :reload work too). This is a feature request to GHC, not a bug in Cabal.

jneira commented 2 years ago

Agree with the analysis, i would try to not coupling even more cabal and ghc(i). How could we implement the solution without hardcoding ghci specific knowledge in cabal?

Imo the cabal repl script use of a ghci script was a hack on top of another hack (fake-package), and recognized as such. It was needed to implement a miss for too long feature with complicated workarounds.

phadej commented 2 years ago

Imo the cabal repl script use of a ghci script was a hack on top of another hack (fake-package), and recognized as such. It was needed to implement a miss for too long feature with complicated workarounds.

Fortunately these "hacks" would naturally decouple&vanish when fake-package hack is removed. If cabal-install would be able to create a package environment directly, then the invocation of ghci with that environment in correct working directory will be a lot easier.

Sometimes to make progress you need to take step back.

However, reimplementing of package environment creation is not related to this issue: in project context there is no need to fake package, as there is a project where everything is happening. (I don't know how ghci.conf could break out-of-package cabal repl, as there we don't ask ghci to interpret anything).

phadej commented 2 years ago

a side note: ghci will gain a multi-home-package functionality, but then :set won't even work initially. The problem is very similar to what's happening there, as far as i understand: different packages have different dynflags and it's all somewhat complicated. :seti however works already.

See https://gitlab.haskell.org/ghc/ghc/-/issues/20889

it summarizes this problem well:

The interface for GHCi heavily assumes that there is only one home unit in a session.

(and :set etc. stuff @kindaro wants to work should not apply that only home unit!)

jneira commented 2 years ago

Somewhat related; https://github.com/haskell/cabal/issues/4572

ulysses4ever commented 2 years ago

The root cause here is whether it's a good idea to load ~/.ghci by default, which is the subject of #1471. Also, #7789 is somewhat related. Perhaps, either Cabal or GHC in their output should be more explicit about the fact of loading the user config and possible consequences.

ulysses4ever commented 1 year ago

No activity here and there's some related work in other tickets linked above. I propose closing.