Skip to content

Commit f60b4fb

Browse files
committed
Warn if TH and Mac and static binary
1 parent 57cf81e commit f60b4fb

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

docs/troubleshooting.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ An usual symptom is the presence of errors containing `unknown symbol` and it is
3636

3737
The workaround is to use a version of haskell-language-server compiled from source with the ghc option `-dynamic` enabled. See more details [here](https://github.com/haskell/haskell-language-server/issues/1160#issuecomment-756566273).
3838

39-
### Problems with Template Haskell
39+
### Support for Template Haskell
4040

41-
Due to how Template Haskell code is evaluated at compile time and some limitations in the interaction between HLS and GHC, the loading of modules using TH can be problematic.
41+
Template Haskell should work fine in Linux with the distributed binaries
4242

43-
The errors thrown are usually related to linking and usually make HLS crash: `Segmentation fault`, `GHC runtime linker: fatal error`, etc
43+
Usage of Template Haskell in Mac Os requires a dynamically linked binary of HLS or risk encountering linker errors and/or segmentation faults.
4444

45-
A workaround which has helped in some cases is to compile HLS from source with the ghc option `-dynamic` enabled, as in the previous issue.
45+
The best and currently only way to obtain a dynamically linked HLS binary is to build it locally. With cabal install this can be done as follows:
4646

47-
We have a [dedicated label](https://github.com/haskell/haskell-language-server/issues?q=is%3Aissue+is%3Aopen+label%3A%22type%3A+template+haskell+related%22) in the issue tracker and an [general issue](https://github.com/haskell/haskell-language-server/issues/1431) tracking support for TH.
47+
cabal install haskell-language-server --enable-executable-dynamic
4848

4949
## Troubleshooting the server
5050

ghcide/src/Development/IDE/Core/Rules.hs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ import qualified GHC.LanguageExtensions as LangExt
136136
import qualified HieDb
137137
import Ide.Plugin.Config
138138
import qualified Language.LSP.Server as LSP
139-
import Language.LSP.Types (SMethod (SCustomMethod))
139+
import Language.LSP.Types (SMethod (SCustomMethod, SWindowShowMessage), ShowMessageParams (ShowMessageParams), MessageType (MtInfo))
140140
import Language.LSP.VFS
141141
import System.Directory (makeAbsolute)
142142
import Data.Default (def, Default)
@@ -149,6 +149,14 @@ import Ide.PluginUtils (configForPlugin)
149149
import Ide.Types (DynFlagsModifications (dynFlagsModifyGlobal, dynFlagsModifyParser),
150150
PluginId)
151151
import Control.Concurrent.STM.Stats (atomically)
152+
import Language.LSP.Server (LspT)
153+
import System.Environment (getExecutablePath)
154+
import System.Process.Extra (readProcessWithExitCode)
155+
import Text.Read (readMaybe)
156+
import System.Info.Extra (isMac)
157+
158+
templateHaskellInstructions :: T.Text
159+
templateHaskellInstructions = "https://haskell-language-server.readthedocs.io/en/latest/troubleshooting.html#support-for-template-haskell"
152160

153161
-- | This is useful for rules to convert rules that can only produce errors or
154162
-- a result into the more general IdeResult type that supports producing
@@ -820,8 +828,34 @@ isHiFileStableRule = defineEarlyCutoff $ RuleNoDiagnostics $ \IsHiFileStable f -
820828
summarize SourceUnmodified = BS.singleton 2
821829
summarize SourceUnmodifiedAndStable = BS.singleton 3
822830

831+
displayTHWarning :: LspT c IO ()
832+
displayTHWarning
833+
| isMac = do
834+
isDynamicBinary <- lift $ do
835+
exe <- getExecutablePath
836+
(_, out, _) <- readProcessWithExitCode exe ["+RTS", "--info"] ""
837+
return $ fromMaybe False $ do
838+
fields <- readMaybe out
839+
rtsWay <- lookup ("RTS way" :: String) fields
840+
return $ "dyn" `isInfixOf` rtsWay
841+
unless isDynamicBinary $
842+
LSP.sendNotification SWindowShowMessage $
843+
ShowMessageParams MtInfo $ T.unwords
844+
[ "This HLS binary does not support Template Haskell."
845+
, "Follow the [instructions](" <> templateHaskellInstructions <> ")"
846+
, "to build an HLS binary with support for Template Haskell."
847+
]
848+
| otherwise = return ()
849+
850+
newtype DisplayTHWarning = DisplayTHWarning (IO ())
851+
instance IsIdeGlobal DisplayTHWarning
852+
823853
getModSummaryRule :: Rules ()
824854
getModSummaryRule = do
855+
env <- lspEnv <$> getShakeExtrasRules
856+
displayItOnce <- liftIO $ once $ LSP.runLspT (fromJust env) displayTHWarning
857+
addIdeGlobal (DisplayTHWarning displayItOnce)
858+
825859
defineEarlyCutoff $ Rule $ \GetModSummary f -> do
826860
session' <- hscEnv <$> use_ GhcSession f
827861
modify_dflags <- getModifyDynFlags dynFlagsModifyGlobal
@@ -832,6 +866,10 @@ getModSummaryRule = do
832866
getModSummaryFromImports session fp modTime (textToStringBuffer <$> mFileContent)
833867
case modS of
834868
Right res -> do
869+
-- Check for Template Haskell
870+
when (uses_th_qq $ msrModSummary res) $ do
871+
DisplayTHWarning act <- getIdeGlobalAction
872+
liftIO act
835873
bufFingerPrint <- liftIO $
836874
fingerprintFromStringBuffer $ fromJust $ ms_hspp_buf $ msrModSummary res
837875
let fingerPrint = Util.fingerprintFingerprints
@@ -1027,9 +1065,6 @@ needsCompilationRule file = do
10271065

10281066
pure (Just $ encodeLinkableType res, Just res)
10291067
where
1030-
uses_th_qq (ms_hspp_opts -> dflags) =
1031-
xopt LangExt.TemplateHaskell dflags || xopt LangExt.QuasiQuotes dflags
1032-
10331068
computeLinkableType :: ModSummary -> [Maybe ModSummary] -> [Maybe LinkableType] -> Maybe LinkableType
10341069
computeLinkableType this deps xs
10351070
| Just ObjectLinkable `elem` xs = Just ObjectLinkable -- If any dependent needs object code, so do we
@@ -1039,6 +1074,10 @@ needsCompilationRule file = do
10391074
where
10401075
this_type = computeLinkableTypeForDynFlags (ms_hspp_opts this)
10411076

1077+
uses_th_qq :: ModSummary -> Bool
1078+
uses_th_qq (ms_hspp_opts -> dflags) =
1079+
xopt LangExt.TemplateHaskell dflags || xopt LangExt.QuasiQuotes dflags
1080+
10421081
-- | How should we compile this module?
10431082
-- (assuming we do in fact need to compile it).
10441083
-- Depends on whether it uses unboxed tuples or sums

0 commit comments

Comments
 (0)