-
-
Notifications
You must be signed in to change notification settings - Fork 370
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
don't crash when an unused operator import ends in .
#2123
don't crash when an unused operator import ends in .
#2123
Conversation
@jneira @jhrcek @pepeiborra this is an attempt of a fix for both #2025 and #2118. At the moment I'm just avoiding a crash, but it now occurs to me that a true solution would also have to exhibit the correct expected behavior. However, I'm not familiar with the code I'm changing, and I have no idea what the expected behavior is. |
The ghcide test suite enforces the expected behaviour for code actions. Ideally this PR would extend it with an example that displays the crash, and the expected behaviour should follow from other examples |
@pepeiborra Hm, I'm sorry, but I don't think so. Clearly there are no examples in the test suite that covered the issue with |
@pepeiborra Perhaps I misunderstood. Are you saying that adding an example with |
When I was looking at this issue I came up with this minimal reproducer consisting of two modules: module A where
(@.) = 0 -- Must have an operator whose name ends with '.'
a = 1 -- .. but also something else {-# OPTIONS_GHC -Wunused-imports #-}
module B where
import A (a,(@.)) -- Must use something from module A, but not (@.) <- generating the code action to remove this import triggers the head error
x = a A new test case consisting of these 2 modules should be added in this list of cases:
The current implementation of code "Remove redundant imports" code action is parsing stuff from GHC's warnings. I think you cannot actually have something qualified in import import Some.Module ( x, y, ... {- there can never be qualified thing like B.something in this list if I understand haskell syntax well enough.. -}) So the fix might be as simple as removing the "unqualify" call from "modifyBinding" which is called from the function linked above. |
Alright, I than gather that the following unit tests for
|
@jhrcek I added an integration test as you suggested. |
btw, here's how I run the tests:
|
.
First of all thank you for working on this! I'd approach the fix as follows:
module A (Prelude.head) where
-- ^... you can have qualified things in exports, so the unqualify makes sense here.
import B (Qualified.Think.here)
-- ^... there can never be qualified thing like this, so no point in calling unqualify
-- I checked haskell report which specifies the syntax: https://www.haskell.org/onlinereport/haskell2010/haskellch5.html#x11-1010005.3
|
I tried to write a test that triggers
|
Grepping GHC code base, I found this: https://gitlab.haskell.org/ghc/ghc/-/blob/master/testsuite/tests/parser/should_compile/T14189.hs Also see haddock: https://hackage.haskell.org/package/ghc-8.10.2/docs/GHC-Hs-ImpExp.html#v:IEThingWith |
Thanks! I also found the
|
Hm, I think we cannot have data constructors or classes ending in {-# LANGUAGE TypeOperators #-}
module B where
newtype (@.) = MkT {unT :: Int}
class (^.) a where and {-# LANGUAGE TypeOperators #-}
module A (type (B.@.) (MkT), type (B.^.)) where
import qualified B
a :: ()
a = () |
@@ -1150,6 +1150,33 @@ removeImportTests = testGroup "remove import actions" | |||
, "type T = K.Type" | |||
] | |||
liftIO $ expectedContentAfterAction @=? contentAfterAction | |||
, testSession "remove unused operators whose name ends with '.'" $ do | |||
let contentA = T.unlines | |||
[ "module ModuleA where" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional suggestion: I just realized there's (.|.) operator in Data.Bits in base, so we could potentially shrink the reproducer to just one module if you fancy minimalism 😉
{-# OPTIONS_GHC -Wunused-imports #-}
module ModuleA where
import Data.Bits ((.|.), xor)
x=xor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
really a great work, three issues closed at once, solid tests after a thoroughfull investigation, congrats!
closes #2118
closes #2025
.
Prelude.head: empty list
) in hls when an unused import ends in.
.