diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml index 9d18baaef..5abfdadef 100644 --- a/.github/workflows/haskell-ci.yml +++ b/.github/workflows/haskell-ci.yml @@ -3,7 +3,8 @@ ## When changing versions, do not forget to update .mergify.yaml # ## # ## WARNING: # -## Hand edited to add filter in on.push and on.pull_request. # +## Hand-edited to add filter in on.push and on.pull_request. # +## Also hand-edited to add 'weeder' step to GHC 9.6.5. # ## If possible do not manually edit beside the above. # ##################################################################### # @@ -220,6 +221,13 @@ jobs: - name: build run: | $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always + - name: weeder + if: matrix.compilerVersion == '9.6.5' + uses: freckle/weeder-action@v2 + with: + ghc-version: ${{ matrix.compilerVersion }} + weeder-arguments: --config $GITHUB_WORKSPACE/source/weeder.toml + working-directory: ${{ env.PKGDIR_swarm }} - name: tests run: | $CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct diff --git a/app/Main.hs b/app/game/Main.hs similarity index 100% rename from app/Main.hs rename to app/game/Main.hs diff --git a/app/Swarm/App.hs b/app/game/Swarm/App.hs similarity index 100% rename from app/Swarm/App.hs rename to app/game/Swarm/App.hs diff --git a/scripts/validate/weeder.sh b/scripts/validate/weeder.sh new file mode 100755 index 000000000..96974d4ea --- /dev/null +++ b/scripts/validate/weeder.sh @@ -0,0 +1,11 @@ +#!/bin/bash -ex + +cd $(git rev-parse --show-toplevel) + +# First, install Weeder: +# cabal install weeder + +cabal clean +cabal build -O0 -j all + +weeder -N diff --git a/src/swarm-engine/Swarm/Game/Scenario/Status.hs b/src/swarm-engine/Swarm/Game/Scenario/Status.hs index 563eea823..47d221dcd 100644 --- a/src/swarm-engine/Swarm/Game/Scenario/Status.hs +++ b/src/swarm-engine/Swarm/Game/Scenario/Status.hs @@ -67,9 +67,6 @@ instance ToJSON ScenarioStatus where toEncoding = genericToEncoding scenarioOptions toJSON = genericToJSON scenarioOptions -seedLaunchParams :: Applicative f => Maybe Seed -> ParameterizableLaunchParams a f -seedLaunchParams s = LaunchParams (pure s) (pure Nothing) - emptyLaunchParams :: Applicative f => ParameterizableLaunchParams a f emptyLaunchParams = LaunchParams (pure Nothing) (pure Nothing) diff --git a/src/swarm-scenario/Swarm/Game/Scenario/Objective/Graph.hs b/src/swarm-scenario/Swarm/Game/Scenario/Objective/Graph.hs index 6685a0e58..256ac6d8c 100644 --- a/src/swarm-scenario/Swarm/Game/Scenario/Objective/Graph.hs +++ b/src/swarm-scenario/Swarm/Game/Scenario/Objective/Graph.hs @@ -53,11 +53,6 @@ instance ToSample GraphInfo where deriving instance Generic (BE.Signed ObjectiveLabel) deriving instance ToJSON (BE.Signed ObjectiveLabel) -getConstFromSigned :: BE.Signed a -> a -getConstFromSigned = \case - BE.Positive x -> x - BE.Negative x -> x - getDistinctConstants :: (Ord a) => Prerequisite a -> Set (BE.Signed a) getDistinctConstants = Set.fromList . BE.constants . toBoolExpr diff --git a/src/swarm-topography/Swarm/Game/Location.hs b/src/swarm-topography/Swarm/Game/Location.hs index 0df09dc59..f1a80ee01 100644 --- a/src/swarm-topography/Swarm/Game/Location.hs +++ b/src/swarm-topography/Swarm/Game/Location.hs @@ -20,7 +20,6 @@ module Swarm.Game.Location ( toDirection, toAbsDirection, nearestDirection, - fromDirection, isCardinal, north, south, @@ -192,14 +191,6 @@ nearestDirection coord = index = round $ fromIntegral (length orderedDirs) * angle orderedDirs = Util.enumerateNonEmpty --- | Convert a 'Direction' into a corresponding 'Heading'. Note that --- this only does something reasonable for 'DNorth', 'DSouth', 'DEast', --- and 'DWest'---other 'Direction's return the zero vector. -fromDirection :: Direction -> Heading -fromDirection = \case - DAbsolute x -> toHeading x - _ -> zero - -- | Manhattan distance between world locations. manhattan :: Location -> Location -> Int32 manhattan (Location x1 y1) (Location x2 y2) = abs (x1 - x2) + abs (y1 - y2) diff --git a/src/swarm-tui/Swarm/TUI/Editor/Model.hs b/src/swarm-tui/Swarm/TUI/Editor/Model.hs index ede281fbd..3cf10a9a5 100644 --- a/src/swarm-tui/Swarm/TUI/Editor/Model.hs +++ b/src/swarm-tui/Swarm/TUI/Editor/Model.hs @@ -41,9 +41,6 @@ toFacade = \case Facade f -> f Ref e -> mkFacade e -getEntityName :: EntityFacade -> E.EntityName -getEntityName (EntityFacade name _) = name - data MapEditingBounds = MapEditingBounds { _boundsRect :: Maybe (Cosmic BoundsRectangle) -- ^ Upper-left and lower-right coordinates diff --git a/swarm.cabal b/swarm.cabal index 20e40b2a7..a2c57fda5 100644 --- a/swarm.cabal +++ b/swarm.cabal @@ -85,7 +85,6 @@ common common common stan-config ghc-options: -fwrite-ide-info - -hiedir=.hie -- Harmless extensions from GHC2021 common ghc2021-extensions @@ -199,6 +198,9 @@ library swarm-lang build-depends: swarm:swarm-util hs-source-dirs: src/swarm-lang + ghc-options: + -hiedir=.hie/src/swarm-lang + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -253,6 +255,9 @@ library swarm-topography swarm:swarm-util hs-source-dirs: src/swarm-topography + ghc-options: + -hiedir=.hie/src/swarm-topography + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -351,6 +356,9 @@ library swarm-scenario swarm:swarm-util, hs-source-dirs: src/swarm-scenario + ghc-options: + -hiedir=.hie/src/swarm-scenario + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -451,6 +459,9 @@ library swarm-engine swarm:swarm-util, hs-source-dirs: src/swarm-engine + ghc-options: + -hiedir=.hie/src/swarm-engine + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -497,6 +508,9 @@ library swarm-web swarm:swarm-util, hs-source-dirs: src/swarm-web + ghc-options: + -hiedir=.hie/src/swarm-web + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -555,6 +569,9 @@ library swarm-tournament swarm:swarm-util, hs-source-dirs: src/swarm-tournament + ghc-options: + -hiedir=.hie/src/swarm-tournament + default-language: Haskell2010 library swarm-util @@ -604,6 +621,9 @@ library swarm-util yaml >=0.11 && <0.11.12.0, hs-source-dirs: src/swarm-util + ghc-options: + -hiedir=.hie/src/swarm-util + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -655,6 +675,9 @@ library swarm-doc swarm:swarm-util, hs-source-dirs: src/swarm-doc + ghc-options: + -hiedir=.hie/src/swarm-doc + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -761,6 +784,9 @@ library swarm-tui swarm:swarm-util, hs-source-dirs: src/swarm-tui + ghc-options: + -hiedir=.hie/src/swarm-tui + default-language: Haskell2010 default-extensions: -- Avoid unexpected unevaluated thunk buildup @@ -768,7 +794,7 @@ library swarm-tui StrictData executable swarm - import: stan-config, common + import: stan-config, common, ghc2021-extensions main-is: Main.hs other-modules: Swarm.App build-depends: @@ -789,7 +815,10 @@ executable swarm vty, vty-crossplatform >=0.4 && <0.5, - hs-source-dirs: app + hs-source-dirs: app/game + ghc-options: + -hiedir=.hie/app/game + default-language: Haskell2010 ghc-options: -threaded default-extensions: ImportQualifiedPost @@ -806,6 +835,9 @@ executable swarm-scene swarm:swarm-topography, hs-source-dirs: app/scene + ghc-options: + -hiedir=.hie/app/scene + default-language: Haskell2010 ghc-options: -threaded default-extensions: ImportQualifiedPost @@ -822,6 +854,9 @@ executable swarm-docs text, hs-source-dirs: app/doc + ghc-options: + -hiedir=.hie/app/doc + default-language: Haskell2010 ghc-options: -threaded default-extensions: ImportQualifiedPost @@ -842,6 +877,9 @@ executable swarm-host-tournament swarm:swarm-tournament, hs-source-dirs: app/tournament + ghc-options: + -hiedir=.hie/app/tournament + default-language: Haskell2010 ghc-options: -threaded default-extensions: ImportQualifiedPost @@ -899,6 +937,9 @@ test-suite swarm-unit swarm:swarm-util, hs-source-dirs: test/unit + ghc-options: + -hiedir=.hie/test/unit + default-language: Haskell2010 ghc-options: -threaded @@ -931,6 +972,9 @@ test-suite swarm-integration swarm:swarm-util, hs-source-dirs: test/integration + ghc-options: + -hiedir=.hie/test/integration + default-language: Haskell2010 ghc-options: -threaded @@ -954,6 +998,9 @@ test-suite tournament-host swarm:swarm-tournament, hs-source-dirs: test/tournament-host + ghc-options: + -hiedir=.hie/test/tournament-host + default-language: Haskell2010 ghc-options: -threaded @@ -982,6 +1029,9 @@ test-suite standalone-topography swarm:swarm-util, hs-source-dirs: test/standalone-topography/src + ghc-options: + -hiedir=.hie/test/standalone-topography/src + default-language: Haskell2010 ghc-options: -threaded @@ -989,6 +1039,9 @@ benchmark benchmark import: stan-config, common, ghc2021-extensions main-is: Benchmark.hs hs-source-dirs: test/bench + ghc-options: + -hiedir=.hie/test/bench + type: exitcode-stdio-1.0 build-depends: base, diff --git a/weeder.toml b/weeder.toml new file mode 100644 index 000000000..df3626b43 --- /dev/null +++ b/weeder.toml @@ -0,0 +1,69 @@ +roots = [ + "^Main.main$", + "^Paths_.*", + + # Workarounds for TH parsing: + # ------------------------------- + "^Swarm.Language.Pipeline.QQ.tmQ$", + "^Swarm.Language.Parser.QQ.tyQ$", + "^Swarm.Util.Lens.makeLensesNoSigs$", + "^Swarm.Util.Lens.makeLensesExcluding$", + + # Workarounds for type families: + # ------------------------------- + "^Swarm.Game.World.Compile.NoFunParams$", + + # True positives: + # ===================================== + "^Main.prop_hittingSetMinimal$", + "^Main.printAllLogs$", + "^Control.Carrier.Accum.FixedStrict.execAccum$", + "^Swarm.App.demoWeb$", + "^Swarm.Effect.Unify.Common.dom$", + "^Swarm.Effect.Unify.Fast.@@$", + "^Swarm.Effect.Unify.Naive.runUnification$", + "^Swarm.Game.Entity.entityNameFor$", + "^Swarm.Game.Entity.singleton$", + "^Swarm.Game.Entity.Cosmetic.getBackground$", + "^Swarm.Game.Step.traceLogShow$", + "^Swarm.Game.World.Compile.compile$", + "^Swarm.Game.World.Compile.runCTerm$", + "^Swarm.Game.World.lookupTerrainM$", + "^Swarm.Language.Context.withBindings$", + "^Swarm.Language.Context.singleton$", + "^Swarm.Language.Parser.Util.showShortError$", + "^Swarm.Language.Pipeline.extractTCtx$", + "^Swarm.Language.Pretty.Prec$", + "^Swarm.Language.Pretty.appliedTermPrec$", + "^Swarm.Language.Requirements.Type.insert$", + "^Swarm.Language.Syntax.Pattern.UTerm$", + "^Swarm.Language.Syntax.Util.asTree$", + "^Swarm.Language.Syntax.Util.mapFreeS$", + "^Swarm.Util.replaceLast$", + "^Swarm.Util.reflow$", + "^Swarm.Util.isSuccessOr$", + "^Swarm.Util._NonEmpty$", + + # True positives (unused lenses): + # ------------------------------- + "^Swarm.Language.Typed.polytype$", + "^Swarm.Language.Typed.requires$", + "^Swarm.Language.Typed.value$", + "^Swarm.Language.Value.emptyEnv$", + "^Swarm.Game.Scenario.staticPlacements$", + "^Swarm.Game.Scenario.structureDefs$", + "^Swarm.Game.Scenario.Scoring.Best.scenarioBestByAstSize$", + "^Swarm.Game.Scenario.Scoring.Best.scenarioBestByCharCount$", + "^Swarm.Game.Scenario.Scoring.Best.scenarioBestByTicks$", + "^Swarm.Game.Scenario.Scoring.Best.scenarioBestByTime$", + "^Swarm.Game.ScenarioInfo._NotStarted$", + "^Swarm.Game.ScenarioInfo._Played$", + "^Swarm.Game.State.Robot._VCLocation$", + "^Swarm.Game.State.Robot._VCRobot$", + "^Swarm.Game.State.Substate._NoWinCondition$", + "^Swarm.Game.State.Substate._WinConditions$", + ] + +type-class-roots = true +unused-types = true +