Skip to content

WIP: GHC-9.0 support for hls-tactics-plugin #2202

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

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ jobs:
name: Test hls-fourmolu-plugin
run: cabal test hls-fourmolu-plugin --test-options="-j1 --rerun-update" || cabal test hls-fourmolu-plugin --test-options="-j1 --rerun" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-fourmolu-plugin --test-options="-j1 --rerun"

- if: ${{ needs.pre_job.outputs.should_skip != 'true' && matrix.test && matrix.ghc != '9.0.1' }}
- if: ${{ needs.pre_job.outputs.should_skip != 'true' && matrix.test }}
name: Test hls-tactics-plugin test suite
run: cabal test hls-tactics-plugin --test-options="-j1 --rerun-update" || cabal test hls-tactics-plugin --test-options="-j1 --rerun" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-tactics-plugin --test-options="-j1 --rerun"

Expand Down
4 changes: 2 additions & 2 deletions cabal-ghc901.project
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ packages:
./ghcide
./hls-plugin-api
./hls-test-utils
-- ./plugins/hls-tactics-plugin
./plugins/hls-tactics-plugin
-- ./plugins/hls-brittany-plugin
-- ./plugins/hls-stylish-haskell-plugin
-- ./plugins/hls-fourmolu-plugin
Expand Down Expand Up @@ -65,7 +65,7 @@ index-state: 2021-09-16T07:00:23Z

constraints:
-- These plugins don't work on GHC9 yet
haskell-language-server -brittany -class -fourmolu -stylishhaskell -tactic
haskell-language-server -brittany -class -fourmolu -stylishhaskell

allow-newer:
floskell:base,
Expand Down
7 changes: 4 additions & 3 deletions configuration-ghc-901.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

let
disabledPlugins = [
"hls-tactics-plugin"
"hls-brittany-plugin"
"hls-stylish-haskell-plugin"
"hls-fourmolu-plugin"
Expand Down Expand Up @@ -54,7 +53,10 @@ let
dependent-sum-template = hself.callCabal2nix "dependent-sum-template"
"${dependent-sum-src}/dependent-sum-template" { };

hlint = hself.hlint_3_3_1;
hlint = hself.hlint_3_3_4;

generic-lens = hself.generic-lens_2_2_0_0;
generic-lens-core = hself.generic-lens-core_2_2_0_0;

ghc-lib-parser = hself.ghc-lib-parser_9_0_1_20210324;

Expand Down Expand Up @@ -85,7 +87,6 @@ let
"-f-class"
"-f-fourmolu"
"-f-stylishhaskell"
"-f-tactic"
]) { };

# YOLO
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 18 additions & 5 deletions ghcide/src/Development/IDE/GHC/Compat/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ module Development.IDE.GHC.Compat.Core (
-- slightly unsafe
setUnsafeGlobalDynFlags,
-- * Linear Haskell
#if !MIN_VERSION_ghc(9,0,0)
Scaled,
unrestricted,
#endif
scaledThing,
-- * Interface Files
IfaceExport,
Expand Down Expand Up @@ -121,9 +124,12 @@ module Development.IDE.GHC.Compat.Core (
TyCoRep.CoercionTy
),
pattern FunTy,
pattern ConPatIn,
Development.IDE.GHC.Compat.Core.splitForAllTyCoVars,
#if !MIN_VERSION_ghc(9,0,0)
Development.IDE.GHC.Compat.Core.mkVisFunTys,
Development.IDE.GHC.Compat.Core.mkInfForAllTys,
#endif
Comment on lines +129 to +132
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this cause any issues or something? I would prefer to have as few CPP statements as possible, as you lose very quickly the big picture about what happens in Core.hs

Copy link
Contributor Author

@anka-213 anka-213 Sep 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see. Yeah, that should be fairly easy to workaround. I was trying to avoid having redundant

foo = Module.foo

definitions and just reexporting the existing things. I think removing these pragmas would just cause a few "duplicate exports" warnings, so another option could be to just disable that warning in this file.

Edit: The primary reason why is that I wanted to re-export the whole module, which is what caused the "duplicate exports" warnings. Getting rid of duplicate definitions was just a bonus.

-- * Specs
ImpDeclSpec(..),
ImportSpec(..),
Expand Down Expand Up @@ -336,6 +342,7 @@ module Development.IDE.GHC.Compat.Core (
module GHC.Types.Var,
module GHC.Unit.Module,
module GHC.Utils.Error,
module TcType,
#else
module BasicTypes,
module Class,
Expand Down Expand Up @@ -769,7 +776,9 @@ dataConExTyCoVars = DataCon.dataConExTyVars
type Scaled a = a
scaledThing :: Scaled a -> a
scaledThing = id
#endif

unrestricted :: a -> Scaled a
unrestricted = id

mkVisFunTys :: [Scaled Type] -> Type -> Type
mkVisFunTys =
Expand All @@ -781,10 +790,7 @@ mkVisFunTys =

mkInfForAllTys :: [TyVar] -> Type -> Type
mkInfForAllTys =
#if MIN_VERSION_ghc(9,0,0)
TcType.mkInfForAllTys
#else
mkInvForAllTys
mkInfForAllTys
#endif

splitForAllTyCoVars :: Type -> ([TyCoVar], Type)
Expand Down Expand Up @@ -846,3 +852,10 @@ type PlainGhcException = Plain.PlainGhcException
#else
type PlainGhcException = Plain.GhcException
#endif

#if MIN_VERSION_ghc(9,0,0)
-- This is from the old api, but it still simplifies
pattern ConPatIn :: SrcLoc.Located (ConLikeP GhcPs) -> HsConPatDetails GhcPs -> Pat GhcPs
pattern ConPatIn con args = ConPat NoExtField con args
#endif

10 changes: 8 additions & 2 deletions plugins/hls-tactics-plugin/src/Wingman/CodeGen.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
Expand Down Expand Up @@ -57,7 +58,7 @@ destructMatches use_field_puns f scrut t jdg = do
Just (dcs, apps) ->
fmap unzipTrace $ for dcs $ \dc -> do
let con = RealDataCon dc
ev = concatMap mkEvidence $ dataConInstArgTys dc apps
ev = concatMap (mkEvidence . scaledThing) $ dataConInstArgTys dc apps
-- We explicitly do not need to add the method hypothesis to
-- #syn_scoped
method_hy = foldMap evidenceToHypothesis ev
Expand Down Expand Up @@ -140,6 +141,7 @@ mkDestructPat already_in_scope con names

in (names', )
$ ConPatIn (noLoc $ Unqual $ occName $ conLikeName con)
-- $ ConPat NoExtField (noLoc $ Unqual $ occName $ conLikeName con)
$ RecCon
$ HsRecFields rec_fields
$ Nothing
Expand Down Expand Up @@ -186,7 +188,7 @@ conLikeInstOrigArgTys'
-- ^ Types of arguments to the ConLike with returned type is instantiated with the second argument.
conLikeInstOrigArgTys' con uniTys =
let exvars = conLikeExTys con
in conLikeInstOrigArgTys con $
in map scaledThing $ conLikeInstOrigArgTys con $
uniTys ++ fmap mkTyVarTy exvars
-- Rationale: At least in GHC <= 8.10, 'dataConInstOrigArgTys'
-- unifies the second argument with DataCon's universals followed by existentials.
Expand Down Expand Up @@ -230,7 +232,11 @@ destructLambdaCase' use_field_puns f jdg = do
when (isDestructBlacklisted jdg) $ cut -- throwError NoApplicableTactic
let g = jGoal jdg
case splitFunTy_maybe (unCType g) of
#if __GLASGOW_HASKELL__ >= 900
Just (_multiplicity, arg, _) | isAlgType arg ->
#else
Just (arg, _) | isAlgType arg ->
#endif
fmap (fmap noLoc lambdaCase) <$>
destructMatches use_field_puns f Nothing (CType arg) jdg
_ -> cut -- throwError $ GoalMismatch "destructLambdaCase'" g
Expand Down
1 change: 1 addition & 0 deletions plugins/hls-tactics-plugin/src/Wingman/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Development.IDE.GHC.Compat.Util
import Wingman.GHC (normalizeType)
import Wingman.Judgements.Theta
import Wingman.Types
-- import GHC.Tc.Utils.TcType (tcSplitPhiTy, tcSplitTyConApp)


mkContext
Expand Down
2 changes: 1 addition & 1 deletion plugins/hls-tactics-plugin/src/Wingman/EmptyCase.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ scrutinzedType :: EmptyCaseSort Type -> Maybe Type
scrutinzedType (EmptyCase ty) = pure ty
scrutinzedType (EmptyLamCase ty) =
case tacticsSplitFunTy ty of
(_, _, tys, _) -> listToMaybe tys
(_, _, tys, _) -> listToMaybe $ map scaledThing tys


------------------------------------------------------------------------------
Expand Down
13 changes: 11 additions & 2 deletions plugins/hls-tactics-plugin/src/Wingman/GHC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Data.Traversable
import Development.IDE.GHC.Compat
import Development.IDE.GHC.Compat.Util
import GHC.SourceGen (lambda)
-- import GHC.Tc.Utils.TcType (tcSplitSigmaTy, tcSplitNestedSigmaTys, tcSplitFunTys, tyCoVarsOfTypeList)
import Generics.SYB (Data, everything, everywhere, listify, mkQ, mkT)
import Wingman.StaticPlugin (pattern MetaprogramSyntax)
import Wingman.Types
Expand Down Expand Up @@ -57,7 +58,7 @@ isFunction _ = True
------------------------------------------------------------------------------
-- | Split a function, also splitting out its quantified variables and theta
-- context.
tacticsSplitFunTy :: Type -> ([TyVar], ThetaType, [Type], Type)
tacticsSplitFunTy :: Type -> ([TyVar], ThetaType, [Scaled Type], Type)
tacticsSplitFunTy t
= let (vars, theta, t') = tcSplitNestedSigmaTys t
(args, res) = tcSplitFunTys t'
Expand Down Expand Up @@ -182,7 +183,11 @@ allOccNames = everything (<>) $ mkQ mempty $ \case

------------------------------------------------------------------------------
-- | Unpack the relevant parts of a 'Match'
#if __GLASGOW_HASKELL__ >= 900
pattern AMatch :: HsMatchContext (NoGhcTc GhcPs) -> [Pat GhcPs] -> HsExpr GhcPs -> Match GhcPs (LHsExpr GhcPs)
#else
pattern AMatch :: HsMatchContext (NameOrRdrName (IdP GhcPs)) -> [Pat GhcPs] -> HsExpr GhcPs -> Match GhcPs (LHsExpr GhcPs)
#endif
pattern AMatch ctx pats body <-
Match { m_ctxt = ctx
, m_pats = fmap fromPatCompat -> pats
Expand All @@ -195,7 +200,7 @@ pattern SingleLet bind pats val expr <-
HsLet _
(L _ (HsValBinds _
(ValBinds _ (bagToList ->
[(L _ (FunBind _ (L _ bind) (MG _ (L _ [L _ (AMatch _ pats val)]) _) _ _))]) _)))
[L _ (FunBind {fun_id = (L _ bind), fun_matches = (MG _ (L _ [L _ (AMatch _ pats val)]) _)})]) _)))
(L _ expr)


Expand Down Expand Up @@ -258,7 +263,11 @@ pattern LamCase matches <-
-- @Just False@ if it can't be homomorphic
-- @Just True@ if it can
lambdaCaseable :: Type -> Maybe Bool
#if __GLASGOW_HASKELL__ >= 900
lambdaCaseable (splitFunTy_maybe -> Just (_multiplicity, arg, res))
#else
lambdaCaseable (splitFunTy_maybe -> Just (arg, res))
#endif
| isJust (algebraicTyCon arg)
= Just $ isJust $ algebraicTyCon res
lambdaCaseable _ = Nothing
Expand Down
8 changes: 8 additions & 0 deletions plugins/hls-tactics-plugin/src/Wingman/Judgements/Theta.hs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,11 @@ absBinds _ _ = []
------------------------------------------------------------------------------
-- | Extract evidence from 'HsWrapper's in scope
wrapperBinds :: SrcSpan -> LHsExpr GhcTc -> [PredType]
#if __GLASGOW_HASKELL__ >= 900
wrapperBinds dst (L src (XExpr (WrapExpr (HsWrap h _))))
#else
wrapperBinds dst (L src (HsWrap _ h _))
#endif
| dst `isSubspanOf` src = wrapper h
wrapperBinds _ _ = []

Expand All @@ -196,7 +200,11 @@ matchBinds _ _ = []
------------------------------------------------------------------------------
-- | Extract evidence from a 'ConPatOut'.
patBinds :: Pat GhcTc -> [PredType]
#if __GLASGOW_HASKELL__ >= 900
patBinds (ConPat{ pat_con_ext = ConPatTc { cpt_dicts = dicts }})
#else
patBinds (ConPatOut { pat_dicts = dicts })
#endif
= fmap idType dicts
patBinds _ = []

Expand Down
14 changes: 11 additions & 3 deletions plugins/hls-tactics-plugin/src/Wingman/LanguageServer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ getAlreadyDestructed (unTrack -> span) (unTrack -> binds) =

getSpanAndTypeAtHole
:: Tracked age Range
-> Tracked age (HieASTs b)
-> Maybe (Tracked age RealSrcSpan, b)
-> Tracked age (HieASTs Type)
-> Maybe (Tracked age RealSrcSpan, Type)
getSpanAndTypeAtHole r@(unTrack -> range) (unTrack -> hf) = do
join $ listToMaybe $ M.elems $ flip M.mapWithKey (getAsts hf) $ \fs ast ->
case selectSmallestContaining (rangeToRealSrcSpan (FastString.unpackFS fs) range) ast of
Expand Down Expand Up @@ -386,7 +386,11 @@ buildPatHy prov (fromPatCompat -> p0) =
(RealDataCon $ tupleDataCon boxity $ length pats)
tys
$ zip [0.. ] pats
ConPatOut (L _ con) args _ _ _ f _ ->
#if __GLASGOW_HASKELL__ >= 900
ConPat {pat_con = (L _ con), pat_con_ext = ConPatTc {cpt_arg_tys = args}, pat_args = f} ->
#else
ConPatOut {pat_con = (L _ con), pat_arg_tys = args, pat_args = f} ->
#endif
case f of
PrefixCon l_pgt ->
mkDerivedConHypothesis prov con args $ zip [0..] l_pgt
Expand Down Expand Up @@ -540,7 +544,11 @@ wingmanRules plId = do
L span (HsVar _ (L _ name))
| isHole (occName name) ->
maybeToList $ srcSpanToRange span
#if __GLASGOW_HASKELL__ >= 900
L span (HsUnboundVar _ occ)
#else
L span (HsUnboundVar _ (TrueExprHole occ))
#endif
| isHole occ ->
maybeToList $ srcSpanToRange span
#if __GLASGOW_HASKELL__ <= 808
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ homoFilter codomain domain =
liftLambdaCase :: r -> (Type -> Type -> r) -> Type -> r
liftLambdaCase nil f t =
case tacticsSplitFunTy t of
(_, _, arg : _, res) -> f res arg
(_, _, arg : _, res) -> f res $ scaledThing arg
_ -> nil


Expand Down
5 changes: 3 additions & 2 deletions plugins/hls-tactics-plugin/src/Wingman/Naming.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Data.Traversable
import Development.IDE.GHC.Compat.Core hiding (IsFunction)
import Text.Hyphenation (hyphenate, english_US)
import Wingman.GHC (tcTyVar_maybe)
-- import GHC.Tc.Utils.TcType (tcSplitFunTys, isBoolTy, isIntegerTy, isIntTy, isFloatingTy, isStringTy, tcSplitAppTys)


------------------------------------------------------------------------------
Expand All @@ -38,11 +39,11 @@ data Purpose

pattern IsPredicate :: Type
pattern IsPredicate <-
(tcSplitFunTys -> ([isFunTy -> False], isBoolTy -> True))
(tcSplitFunTys -> ([isFunTy . scaledThing -> False], isBoolTy -> True))

pattern IsFunction :: [Type] -> Type -> Type
pattern IsFunction args res <-
(tcSplitFunTys -> (args@(_:_), res))
(first (map scaledThing) . tcSplitFunTys -> (args@(_:_), res))

pattern IsString :: Type
pattern IsString <-
Expand Down
Loading