[Git][ghc/ghc][wip/T22719] 11 commits: Bump hsc2hs submodule
Simon Peyton Jones (@simonpj)
gitlab at gitlab.haskell.org
Mon Jan 16 10:06:20 UTC 2023
Simon Peyton Jones pushed to branch wip/T22719 at Glasgow Haskell Compiler / GHC
Commits:
1142f858 by Cheng Shao at 2023-01-13T11:04:00+00:00
Bump hsc2hs submodule
- - - - -
d4686729 by Cheng Shao at 2023-01-13T11:04:00+00:00
Bump process submodule
- - - - -
84ae6573 by Cheng Shao at 2023-01-13T11:06:58+00:00
ci: Bump DOCKER_REV
- - - - -
d53598c5 by Cheng Shao at 2023-01-13T11:06:58+00:00
ci: enable xz parallel compression for x64 jobs
- - - - -
d31fcbca by Cheng Shao at 2023-01-13T11:06:58+00:00
ci: use in-image emsdk for js jobs
- - - - -
93b9bbc1 by Cheng Shao at 2023-01-13T11:47:17+00:00
ci: improve nix-shell for gen_ci.hs and fix some ghc/hlint warnings
- Add a ghc environment including prebuilt dependencies to the
nix-shell. Get rid of the ad hoc cabal cache and all dependencies
are now downloaded from the nixos binary cache.
- Make gen_ci.hs a cabal package with HLS integration, to make future
hacking of gen_ci.hs easier.
- Fix some ghc/hlint warnings after I got HLS to work.
- For the lint-ci-config job, do a shallow clone to save a few minutes
of unnecessary git checkout time.
- - - - -
8acc56c7 by Cheng Shao at 2023-01-13T11:47:17+00:00
ci: source the toolchain env file in wasm jobs
- - - - -
87194df0 by Cheng Shao at 2023-01-13T11:47:17+00:00
ci: add wasm ci jobs via gen_ci.hs
- There is one regular wasm job run in validate pipelines
- Additionally, int-native/unreg wasm jobs run in nightly/release pipelines
Also, remove the legacy handwritten wasm ci jobs in .gitlab-ci.yml.
- - - - -
b6eb9bcc by Matthew Pickering at 2023-01-13T11:52:16+00:00
wasm ci: Remove wasm release jobs
This removes the wasm release jobs, as we do not yet intend to
distribute these binaries.
- - - - -
496607fd by Simon Peyton Jones at 2023-01-13T16:52:07-05:00
Add a missing checkEscapingKind
Ticket #22743 pointed out that there is a missing check,
for type-inferred bindings, that the inferred type doesn't
have an escaping kind.
The fix is easy.
- - - - -
5fef5d40 by Simon Peyton Jones at 2023-01-16T10:06:34+00:00
Document the semantics of pattern bindings a bit better
This MR is in response to the discussion on #22719
- - - - -
23 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- + .gitlab/gen-ci.cabal
- .gitlab/gen_ci.hs
- .gitlab/generate_jobs
- + .gitlab/hie.yaml
- .gitlab/jobs.yaml
- compiler/GHC/Core/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Validity.hs
- docs/users_guide/exts/primitives.rst
- docs/users_guide/exts/strict.rst
- libraries/process
- + testsuite/tests/deSugar/should_compile/T22719.hs
- + testsuite/tests/deSugar/should_compile/T22719.stderr
- testsuite/tests/deSugar/should_compile/all.T
- + testsuite/tests/polykinds/T22743.hs
- + testsuite/tests/polykinds/T22743.stderr
- testsuite/tests/polykinds/all.T
- utils/hsc2hs
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -2,7 +2,7 @@ variables:
GIT_SSL_NO_VERIFY: "1"
# Commit of ghc/ci-images repository from which to pull Docker images
- DOCKER_REV: 0de79b7676de197f5d4b79f22a8220a7d563a427
+ DOCKER_REV: dd01591a50ea4e2aa3c106cf50ca54d38663f912
# Sequential version number of all cached things.
# Bump to invalidate GitLab CI cache.
@@ -262,26 +262,20 @@ lint-author:
- *drafts-can-fail-lint
lint-ci-config:
- image: "nixos/nix:2.8.0"
+ image: nixos/nix:2.12.0
extends: .lint
+ # We don't need history/submodules in this job
variables:
- BUILD_FLAVOUR: default
+ GIT_DEPTH: 1
+ GIT_SUBMODULE_STRATEGY: none
before_script:
- - mkdir -p ~/.cabal
- - cp -Rf cabal-cache/* ~/.cabal || true
+ - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf
+ - nix-channel --update
script:
- - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#cabal-install nixpkgs#ghc -c cabal update
- .gitlab/generate_jobs
- # 1 if .gitlab/generate_jobs changed the output of the generated config
- - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#git -c git diff --exit-code
- after_script:
- - rm -Rf cabal-cache
- - cp -Rf ~/.cabal cabal-cache
+ # 1 if .gitlab/generate_jobs changed the output of the generated config
+ - nix shell nixpkgs#git -c git diff --exit-code
dependencies: []
- cache:
- key: lint-ci-$CACHE_REV
- paths:
- - cabal-cache
lint-submods:
extends: .lint-submods
@@ -544,8 +538,6 @@ doc-tarball:
hackage-doc-tarball:
stage: packaging
needs:
- - job: x86_64-linux-fedora33-release-hackage
- optional: true
- job: nightly-x86_64-linux-fedora33-release-hackage
optional: true
- job: release-x86_64-linux-fedora33-release-hackage
@@ -948,64 +940,3 @@ pages:
artifacts:
paths:
- public
-
-.x86_64-linux-ubuntu20_04-cross_wasm32-wasi-release:
- stage: full-build
- rules:
- # See #22664 to see what needs to be done to bring this up to the validate pipeline standards.
- - if: $NIGHTLY
- tags:
- - x86_64-linux
- image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-ubuntu20_04:$DOCKER_REV
- before_script:
- - sudo chown ghc:ghc -R .
- variables:
- BIN_DIST_NAME: ghc-x86_64-linux-ubuntu20_04-cross_wasm32-wasi-int_$BIGNUM_BACKEND-release
- BUILD_FLAVOUR: perf
- CONFIGURE_ARGS: --with-intree-gmp --with-system-libffi
- XZ_OPT: "-9"
- CONF_CC_OPTS_STAGE2: -Wno-int-conversion -Wno-strict-prototypes -mnontrapping-fptoint -msign-ext -mbulk-memory -mmutable-globals -mreference-types
- CONF_CXX_OPTS_STAGE2: -fno-exceptions -Wno-int-conversion -Wno-strict-prototypes -mnontrapping-fptoint -msign-ext -mbulk-memory -mmutable-globals -mreference-types
- CONF_GCC_LINKER_OPTS_STAGE2: -Wl,--error-limit=0,--growable-table,--stack-first -Wno-unused-command-line-argument
- CROSS_EMULATOR: wasmtime
- CROSS_TARGET: wasm32-wasi
- HADRIAN_ARGS: --docs=none
- TEST_ENV: x86_64-linux-ubuntu20_04-cross_wasm32-wasi-int_$BIGNUM_BACKEND-release
- script:
- - |
- pushd libraries/process
- curl https://patch-diff.githubusercontent.com/raw/haskell/process/pull/240.diff | git apply
- popd
- pushd utils/hsc2hs
- curl https://patch-diff.githubusercontent.com/raw/haskell/hsc2hs/pull/68.diff | git apply
- popd
-
- pushd "$(mktemp -d)"
- curl -L https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/archive/master/ghc-wasm-meta-master.tar.gz | tar xz --strip-components=1
- PREFIX=/tmp/.ghc-wasm SKIP_GHC=1 ./setup.sh
- source /tmp/.ghc-wasm/env
- popd
-
- .gitlab/ci.sh setup
- .gitlab/ci.sh configure
- .gitlab/ci.sh build_hadrian
- .gitlab/ci.sh test_hadrian
-
- after_script:
- - cat ci-timings
-
- artifacts:
- expire_in: 8 weeks
- paths:
- - ghc-x86_64-linux-ubuntu20_04-cross_wasm32-wasi-int_$BIGNUM_BACKEND-release.tar.xz
- when: always
-
-x86_64-linux-ubuntu20_04-cross_wasm32-wasi-int_gmp-release:
- extends: .x86_64-linux-ubuntu20_04-cross_wasm32-wasi-release
- variables:
- BIGNUM_BACKEND: gmp
-
-x86_64-linux-ubuntu20_04-cross_wasm32-wasi-int_native-release:
- extends: .x86_64-linux-ubuntu20_04-cross_wasm32-wasi-release
- variables:
- BIGNUM_BACKEND: native
=====================================
.gitlab/ci.sh
=====================================
@@ -233,6 +233,10 @@ function set_toolchain_paths() {
export CABAL
export HAPPY
export ALEX
+
+ if [[ "${CROSS_TARGET:-}" == *"wasm"* ]]; then
+ source "/home/ghc/.ghc-wasm/env"
+ fi
}
function cabal_update() {
@@ -252,11 +256,6 @@ function setup() {
cp -Rf "$CABAL_CACHE"/* "$CABAL_DIR"
fi
- case "${CONFIGURE_WRAPPER:-}" in
- emconfigure) time_it "setup" setup_emscripten ;;
- *) ;;
- esac
-
case $toolchain_source in
extracted) time_it "setup" setup_toolchain ;;
*) ;;
@@ -372,14 +371,6 @@ function setup_toolchain() {
$cabal_install alex --constraint="alex>=$MIN_ALEX_VERSION"
}
-function setup_emscripten() {
- git clone https://github.com/emscripten-core/emsdk.git
- cd emsdk
- ./emsdk install latest
- ./emsdk activate latest
- cd ..
-}
-
function cleanup_submodules() {
start_section "clean submodules"
if [ -d .git ]; then
@@ -418,7 +409,7 @@ EOF
function configure() {
case "${CONFIGURE_WRAPPER:-}" in
- emconfigure) source emsdk/emsdk_env.sh ;;
+ emconfigure) source "$EMSDK/emsdk_env.sh" ;;
*) ;;
esac
@@ -516,6 +507,13 @@ function build_hadrian() {
check_release_build
+ # We can safely enable parallel compression for x64. By the time
+ # hadrian calls tar/xz to produce bindist, there's no other build
+ # work taking place.
+ if [[ "${CI_JOB_NAME:-}" != *"i386"* ]]; then
+ XZ_OPT="${XZ_OPT:-} -T$cores"
+ fi
+
if [[ -n "${REINSTALL_GHC:-}" ]]; then
run_hadrian build-cabal -V
else
@@ -549,7 +547,7 @@ function make_install_destdir() {
# install the binary distribution in directory $1 to $2.
function install_bindist() {
case "${CONFIGURE_WRAPPER:-}" in
- emconfigure) source emsdk/emsdk_env.sh ;;
+ emconfigure) source "$EMSDK/emsdk_env.sh" ;;
*) ;;
esac
=====================================
.gitlab/gen-ci.cabal
=====================================
@@ -0,0 +1,18 @@
+cabal-version: 3.0
+name: gen-ci
+version: 0.1.0.0
+build-type: Simple
+
+common warnings
+ ghc-options: -Wall
+
+executable gen_ci
+ import: warnings
+ main-is: gen_ci.hs
+ build-depends:
+ , aeson >=1.8.1
+ , base
+ , bytestring
+ , containers
+
+ default-language: Haskell2010
=====================================
.gitlab/gen_ci.hs
=====================================
@@ -7,12 +7,11 @@
build-depends: base, aeson >= 1.8.1, containers, bytestring
-}
-import Data.Coerce
-import Data.String (String)
import Data.Aeson as A
import qualified Data.Map as Map
import Data.Map (Map)
-import qualified Data.ByteString.Lazy as B hiding (putStrLn)
+import Data.Maybe
+import qualified Data.ByteString.Lazy as B
import qualified Data.ByteString.Lazy.Char8 as B
import Data.List (intercalate)
import Data.Set (Set)
@@ -135,10 +134,11 @@ data BuildConfig
-- Extra arguments to pass to ./configure due to the BuildConfig
configureArgsStr :: BuildConfig -> String
-configureArgsStr bc = intercalate " " $
+configureArgsStr bc = unwords $
["--enable-unregisterised"| unregisterised bc ]
++ ["--disable-tables-next-to-code" | not (tablesNextToCode bc) ]
++ ["--with-intree-gmp" | Just _ <- pure (crossTarget bc) ]
+ ++ ["--with-system-libffi" | crossTarget bc == Just "wasm32-wasi" ]
-- Compute the hadrian flavour from the BuildConfig
mkJobFlavour :: BuildConfig -> Flavour
@@ -232,7 +232,7 @@ noTntc = vanilla { tablesNextToCode = False }
-- | These tags have to match what we call the runners on gitlab
runnerTag :: Arch -> Opsys -> String
-runnerTag arch (Linux distro) =
+runnerTag arch (Linux _) =
case arch of
Amd64 -> "x86_64-linux"
AArch64 -> "aarch64-linux"
@@ -241,6 +241,7 @@ runnerTag AArch64 Darwin = "aarch64-darwin"
runnerTag Amd64 Darwin = "x86_64-darwin-m1"
runnerTag Amd64 Windows = "new-x86_64-windows"
runnerTag Amd64 FreeBSD13 = "x86_64-freebsd13"
+runnerTag _ _ = error "Invalid arch/opsys"
tags :: Arch -> Opsys -> BuildConfig -> [String]
tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use
@@ -324,14 +325,14 @@ dockerImage _ _ = Nothing
-- The "proper" solution would be to use a dependent monoidal map where each key specifies
-- the combination behaviour of it's values. Ie, whether setting it multiple times is an error
-- or they should be combined.
-newtype MonoidalMap k v = MonoidalMap (Map k v)
+newtype MonoidalMap k v = MonoidalMap { unMonoidalMap :: Map k v }
deriving (Eq, Show, Functor, ToJSON)
instance (Ord k, Semigroup v) => Semigroup (MonoidalMap k v) where
(MonoidalMap a) <> (MonoidalMap b) = MonoidalMap (Map.unionWith (<>) a b)
instance (Ord k, Semigroup v) => Monoid (MonoidalMap k v) where
- mempty = MonoidalMap (Map.empty)
+ mempty = MonoidalMap Map.empty
mminsertWith :: Ord k => (a -> a -> a) -> k -> a -> MonoidalMap k a -> MonoidalMap k a
mminsertWith f k v (MonoidalMap m) = MonoidalMap (Map.insertWith f k v m)
@@ -498,13 +499,13 @@ instance ToJSON ManualFlag where
toJSON OnSuccess = "on_success"
instance ToJSON OnOffRules where
- toJSON rules = toJSON [(object ([
+ toJSON rules = toJSON [object ([
"if" A..= and_all (map one_rule (enumRules rules))
, "when" A..= toJSON (when rules)]
-- Necessary to stop manual jobs stopping pipeline progress
-- https://docs.gitlab.com/ee/ci/yaml/#rulesallow_failure
++
- ["allow_failure" A..= True | when rules == Manual ]))]
+ ["allow_failure" A..= True | when rules == Manual ])]
where
one_rule (OnOffRule onoff r) = ruleString onoff r
@@ -580,7 +581,7 @@ instance ToJSON Job where
, "allow_failure" A..= jobAllowFailure
-- Joining up variables like this may well be the wrong thing to do but
-- at least it doesn't lose information silently by overriding.
- , "variables" A..= fmap (intercalate " ") jobVariables
+ , "variables" A..= fmap unwords jobVariables
, "artifacts" A..= jobArtifacts
, "cache" A..= jobCache
, "after_script" A..= jobAfterScript
@@ -608,6 +609,7 @@ job arch opsys buildConfig = (jobName, Job {..})
, "bash .gitlab/ci.sh test_hadrian" ]
| otherwise
= [ "find libraries -name config.sub -exec cp config.sub {} \\;" | Darwin == opsys ] ++
+ [ "sudo apk del --purge glibc*" | opsys == Linux Alpine, isNothing $ crossTarget buildConfig ] ++
[ "sudo chown ghc:ghc -R ." | Linux {} <- [opsys]] ++
[ ".gitlab/ci.sh setup"
, ".gitlab/ci.sh configure"
@@ -677,11 +679,11 @@ job arch opsys buildConfig = (jobName, Job {..})
-- | Modify all jobs in a 'JobGroup'
modifyJobs :: (a -> a) -> JobGroup a -> JobGroup a
-modifyJobs f = fmap f
+modifyJobs = fmap
-- | Modify just the validate jobs in a 'JobGroup'
modifyValidateJobs :: (a -> a) -> JobGroup a -> JobGroup a
-modifyValidateJobs f jg = jg { v = f <$> (v jg) }
+modifyValidateJobs f jg = jg { v = f <$> v jg }
-- Generic helpers
@@ -691,19 +693,26 @@ addJobRule r j = j { jobRules = enableRule r (jobRules j) }
addVariable :: String -> String -> Job -> Job
addVariable k v j = j { jobVariables = mminsertWith (++) k [v] (jobVariables j) }
+setVariable :: String -> String -> Job -> Job
+setVariable k v j = j { jobVariables = MonoidalMap $ Map.insert k [v] $ unMonoidalMap $ jobVariables j }
+
+delVariable :: String -> Job -> Job
+delVariable k j = j { jobVariables = MonoidalMap $ Map.delete k $ unMonoidalMap $ jobVariables j }
+
-- Building the standard jobs
--
-- | Make a normal validate CI job
validate :: Arch -> Opsys -> BuildConfig -> (String, Job)
-validate arch opsys bc =
- job arch opsys bc
+validate = job
-- | Make a normal nightly CI job
+nightly :: Arch -> Opsys -> BuildConfig -> ([Char], Job)
nightly arch opsys bc =
let (n, j) = job arch opsys bc
in ("nightly-" ++ n, addJobRule Nightly . keepArtifacts "8 weeks" . highCompression $ j)
-- | Make a normal release CI job
+release :: Arch -> Opsys -> BuildConfig -> ([Char], Job)
release arch opsys bc =
let (n, j) = job arch opsys (bc { buildFlavour = Release })
in ("release-" ++ n, addJobRule ReleaseOnly . keepArtifacts "1 year" . ignorePerfFailures . highCompression $ j)
@@ -786,10 +795,10 @@ flattenJobGroup (ValidateOnly a b) = [a, b]
-- | Specification for all the jobs we want to build.
jobs :: Map String Job
-jobs = Map.fromList $ concatMap flattenJobGroup $
+jobs = Map.fromList $ concatMap (filter is_enabled_job . flattenJobGroup)
[ disableValidate (standardBuilds Amd64 (Linux Debian10))
- , (standardBuildsWithConfig Amd64 (Linux Debian10) dwarf)
- , (validateBuilds Amd64 (Linux Debian10) nativeInt)
+ , standardBuildsWithConfig Amd64 (Linux Debian10) dwarf
+ , validateBuilds Amd64 (Linux Debian10) nativeInt
, fastCI (validateBuilds Amd64 (Linux Debian10) unreg)
, fastCI (validateBuilds Amd64 (Linux Debian10) debug)
, modifyValidateJobs manual tsan_jobs
@@ -804,7 +813,7 @@ jobs = Map.fromList $ concatMap flattenJobGroup $
, disableValidate (standardBuildsWithConfig Amd64 (Linux Centos7) (splitSectionsBroken vanilla))
-- Fedora33 job is always built with perf so there's one job in the normal
-- validate pipeline which is built with perf.
- , (standardBuildsWithConfig Amd64 (Linux Fedora33) releaseConfig)
+ , standardBuildsWithConfig Amd64 (Linux Fedora33) releaseConfig
-- This job is only for generating head.hackage docs
, hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora33) releaseConfig))
, disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora33) dwarf)
@@ -823,9 +832,14 @@ jobs = Map.fromList $ concatMap flattenJobGroup $
)
{ bignumBackend = Native
}
+ , make_wasm_jobs wasm_build_config
+ , disableValidate $ make_wasm_jobs wasm_build_config { bignumBackend = Native }
+ , disableValidate $ make_wasm_jobs wasm_build_config { unregisterised = True }
]
where
+ is_enabled_job (_, Job {jobRules = OnOffRules {..}}) = not $ Disable `S.member` rule_set
+
hackage_doc_job = rename (<> "-hackage") . modifyJobs (addVariable "HADRIAN_ARGS" "--haddock-base-url")
tsan_jobs =
@@ -836,6 +850,22 @@ jobs = Map.fromList $ concatMap flattenJobGroup $
. addVariable "HADRIAN_ARGS" "--docs=none") $
validateBuilds Amd64 (Linux Debian10) tsan
+ make_wasm_jobs cfg =
+ modifyJobs
+ ( delVariable "BROKEN_TESTS"
+ . setVariable "HADRIAN_ARGS" "--docs=none"
+ . delVariable "INSTALL_CONFIGURE_ARGS"
+ )
+ $ validateBuilds Amd64 (Linux Alpine) cfg
+
+ wasm_build_config =
+ (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing)
+ {
+ fullyStatic = True
+ , buildFlavour = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet
+ }
+
+main :: IO ()
main = do
as <- getArgs
(case as of
=====================================
.gitlab/generate_jobs
=====================================
@@ -1,9 +1,13 @@
-#! /usr/bin/env nix-shell
-#! nix-shell -i bash -p cabal-install ghc jq
+#!/usr/bin/env nix-shell
+#!nix-shell -i bash -p cabal-install "haskell.packages.ghc924.ghcWithPackages (pkgs: with pkgs; [aeson])" git jq
+
+# shellcheck shell=bash
+
+set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
tmp=$(mktemp)
-./gen_ci.hs $tmp
+cabal run gen_ci -- $tmp
rm -f jobs.yaml
echo "### THIS IS A GENERATED FILE, DO NOT MODIFY DIRECTLY" > jobs.yaml
cat $tmp | jq | tee -a jobs.yaml
=====================================
.gitlab/hie.yaml
=====================================
@@ -0,0 +1,2 @@
+cradle:
+ cabal:
=====================================
.gitlab/jobs.yaml
=====================================
@@ -120,64 +120,6 @@
"TEST_ENV": "aarch64-linux-deb10-validate"
}
},
- "aarch64-linux-deb10-validate+llvm": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-aarch64-linux-deb10-validate+llvm.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "aarch64-linux-deb10-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb10:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "aarch64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-aarch64-linux-deb10-validate+llvm",
- "BUILD_FLAVOUR": "validate+llvm",
- "CONFIGURE_ARGS": "",
- "TEST_ENV": "aarch64-linux-deb10-validate+llvm"
- }
- },
"i386-linux-deb9-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
@@ -602,6 +544,128 @@
"XZ_OPT": "-9"
}
},
+ "nightly-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "8 weeks",
+ "paths": [
+ "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static.tar.xz",
+ "junit.xml"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "x86_64-linux-alpine3_12-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static",
+ "BUILD_FLAVOUR": "release+fully_static",
+ "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi",
+ "CROSS_TARGET": "wasm32-wasi",
+ "HADRIAN_ARGS": "--docs=none",
+ "TEST_ENV": "x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static",
+ "XZ_OPT": "-9"
+ }
+ },
+ "nightly-x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "8 weeks",
+ "paths": [
+ "ghc-x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static.tar.xz",
+ "junit.xml"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "x86_64-linux-alpine3_12-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "native",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static",
+ "BUILD_FLAVOUR": "release+fully_static",
+ "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi",
+ "CROSS_TARGET": "wasm32-wasi",
+ "HADRIAN_ARGS": "--docs=none",
+ "TEST_ENV": "x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static",
+ "XZ_OPT": "-9"
+ }
+ },
"nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static": {
"after_script": [
".gitlab/ci.sh save_cache",
@@ -642,6 +706,7 @@
}
],
"script": [
+ "sudo apk del --purge glibc*",
"sudo chown ghc:ghc -R .",
".gitlab/ci.sh setup",
".gitlab/ci.sh configure",
@@ -664,6 +729,67 @@
"XZ_OPT": "-9"
}
},
+ "nightly-x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "8 weeks",
+ "paths": [
+ "ghc-x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static.tar.xz",
+ "junit.xml"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "x86_64-linux-alpine3_12-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static",
+ "BUILD_FLAVOUR": "release+fully_static",
+ "CONFIGURE_ARGS": "--disable-ld-override --enable-unregisterised --with-intree-gmp --with-system-libffi",
+ "CROSS_TARGET": "wasm32-wasi",
+ "HADRIAN_ARGS": "--docs=none",
+ "TEST_ENV": "x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static",
+ "XZ_OPT": "-9"
+ }
+ },
"nightly-x86_64-linux-alpine3_12-validate+fully_static": {
"after_script": [
".gitlab/ci.sh save_cache",
@@ -704,6 +830,7 @@
}
],
"script": [
+ "sudo apk del --purge glibc*",
"sudo chown ghc:ghc -R .",
".gitlab/ci.sh setup",
".gitlab/ci.sh configure",
@@ -2274,6 +2401,7 @@
}
],
"script": [
+ "sudo apk del --purge glibc*",
"sudo chown ghc:ghc -R .",
".gitlab/ci.sh setup",
".gitlab/ci.sh configure",
@@ -2337,6 +2465,7 @@
}
],
"script": [
+ "sudo apk del --purge glibc*",
"sudo chown ghc:ghc -R .",
".gitlab/ci.sh setup",
".gitlab/ci.sh configure",
@@ -3152,17 +3281,17 @@
"TEST_ENV": "x86_64-freebsd13-validate"
}
},
- "x86_64-linux-alpine3_12-int_native-validate+fully_static": {
+ "x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh clean",
"cat ci_timings"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-alpine3_12-int_native-validate+fully_static.tar.xz",
+ "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static.tar.xz",
"junit.xml"
],
"reports": {
@@ -3187,7 +3316,7 @@
],
"rules": [
{
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+ "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
"when": "on_success"
}
],
@@ -3203,14 +3332,13 @@
"x86_64-linux"
],
"variables": {
- "BIGNUM_BACKEND": "native",
- "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-int_native-validate+fully_static",
- "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native",
- "BUILD_FLAVOUR": "validate+fully_static",
- "CONFIGURE_ARGS": "--disable-ld-override ",
- "HADRIAN_ARGS": "--docs=no-sphinx",
- "INSTALL_CONFIGURE_ARGS": "--disable-ld-override",
- "TEST_ENV": "x86_64-linux-alpine3_12-int_native-validate+fully_static"
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static",
+ "BUILD_FLAVOUR": "release+fully_static",
+ "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi",
+ "CROSS_TARGET": "wasm32-wasi",
+ "HADRIAN_ARGS": "--docs=none",
+ "TEST_ENV": "x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static"
}
},
"x86_64-linux-alpine3_12-validate+fully_static": {
@@ -3253,6 +3381,7 @@
}
],
"script": [
+ "sudo apk del --purge glibc*",
"sudo chown ghc:ghc -R .",
".gitlab/ci.sh setup",
".gitlab/ci.sh configure",
@@ -3274,7 +3403,7 @@
"TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static"
}
},
- "x86_64-linux-centos7-validate": {
+ "x86_64-linux-deb10-int_native-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh clean",
@@ -3284,7 +3413,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-centos7-validate.tar.xz",
+ "ghc-x86_64-linux-deb10-int_native-validate.tar.xz",
"junit.xml"
],
"reports": {
@@ -3293,14 +3422,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-centos7-$CACHE_REV",
+ "key": "x86_64-linux-deb10-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-centos7:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -3309,7 +3438,7 @@
],
"rules": [
{
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+ "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
"when": "on_success"
}
],
@@ -3325,15 +3454,14 @@
"x86_64-linux"
],
"variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-centos7-validate",
+ "BIGNUM_BACKEND": "native",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-int_native-validate",
"BUILD_FLAVOUR": "validate",
"CONFIGURE_ARGS": "",
- "HADRIAN_ARGS": "--docs=no-sphinx",
- "TEST_ENV": "x86_64-linux-centos7-validate"
+ "TEST_ENV": "x86_64-linux-deb10-int_native-validate"
}
},
- "x86_64-linux-deb10-int_native-validate": {
+ "x86_64-linux-deb10-no_tntc-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh clean",
@@ -3343,7 +3471,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-deb10-int_native-validate.tar.xz",
+ "ghc-x86_64-linux-deb10-no_tntc-validate.tar.xz",
"junit.xml"
],
"reports": {
@@ -3368,67 +3496,9 @@
],
"rules": [
{
+ "allow_failure": true,
"if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "x86_64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "native",
- "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-int_native-validate",
- "BUILD_FLAVOUR": "validate",
- "CONFIGURE_ARGS": "",
- "TEST_ENV": "x86_64-linux-deb10-int_native-validate"
- }
- },
- "x86_64-linux-deb10-no_tntc-validate": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-linux-deb10-no_tntc-validate.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "x86_64-linux-deb10-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "allow_failure": true,
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
- "when": "manual"
+ "when": "manual"
}
],
"script": [
@@ -3567,64 +3637,6 @@
"TEST_ENV": "x86_64-linux-deb10-unreg-validate"
}
},
- "x86_64-linux-deb10-validate": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-linux-deb10-validate.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "x86_64-linux-deb10-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "x86_64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate",
- "BUILD_FLAVOUR": "validate",
- "CONFIGURE_ARGS": "",
- "TEST_ENV": "x86_64-linux-deb10-validate"
- }
- },
"x86_64-linux-deb10-validate+debug_info": {
"after_script": [
".gitlab/ci.sh save_cache",
@@ -3922,122 +3934,6 @@
"TEST_ENV": "x86_64-linux-deb11-int_native-cross_js-unknown-ghcjs-validate"
}
},
- "x86_64-linux-deb11-validate": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-linux-deb11-validate.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "x86_64-linux-deb11-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "x86_64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate",
- "BUILD_FLAVOUR": "validate",
- "CONFIGURE_ARGS": "",
- "TEST_ENV": "x86_64-linux-deb11-validate"
- }
- },
- "x86_64-linux-deb9-validate": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-linux-deb9-validate.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "x86_64-linux-deb9-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "x86_64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-deb9-validate",
- "BUILD_FLAVOUR": "validate",
- "CONFIGURE_ARGS": "",
- "TEST_ENV": "x86_64-linux-deb9-validate"
- }
- },
"x86_64-linux-fedora33-release": {
"after_script": [
".gitlab/ci.sh save_cache",
@@ -4098,243 +3994,6 @@
"TEST_ENV": "x86_64-linux-fedora33-release"
}
},
- "x86_64-linux-fedora33-release-hackage": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-linux-fedora33-release.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "x86_64-linux-fedora33-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "x86_64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release",
- "BUILD_FLAVOUR": "release",
- "CONFIGURE_ARGS": "",
- "HADRIAN_ARGS": "--haddock-base-url",
- "LLC": "/bin/false",
- "OPT": "/bin/false",
- "TEST_ENV": "x86_64-linux-fedora33-release"
- }
- },
- "x86_64-linux-fedora33-validate+debug_info": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-linux-fedora33-validate+debug_info.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "x86_64-linux-fedora33-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "x86_64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-validate+debug_info",
- "BUILD_FLAVOUR": "validate+debug_info",
- "CONFIGURE_ARGS": "",
- "LLC": "/bin/false",
- "OPT": "/bin/false",
- "TEST_ENV": "x86_64-linux-fedora33-validate+debug_info"
- }
- },
- "x86_64-linux-ubuntu20_04-validate": {
- "after_script": [
- ".gitlab/ci.sh save_cache",
- ".gitlab/ci.sh clean",
- "cat ci_timings"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-linux-ubuntu20_04-validate.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "x86_64-linux-ubuntu20_04-$CACHE_REV",
- "paths": [
- "cabal-cache",
- "toolchain"
- ]
- },
- "dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-ubuntu20_04:$DOCKER_REV",
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "sudo chown ghc:ghc -R .",
- ".gitlab/ci.sh setup",
- ".gitlab/ci.sh configure",
- ".gitlab/ci.sh build_hadrian",
- ".gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "x86_64-linux"
- ],
- "variables": {
- "BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-ubuntu20_04-validate",
- "BUILD_FLAVOUR": "validate",
- "CONFIGURE_ARGS": "",
- "TEST_ENV": "x86_64-linux-ubuntu20_04-validate"
- }
- },
- "x86_64-windows-int_native-validate": {
- "after_script": [
- "bash .gitlab/ci.sh save_cache",
- "bash .gitlab/ci.sh clean"
- ],
- "allow_failure": false,
- "artifacts": {
- "expire_in": "2 weeks",
- "paths": [
- "ghc-x86_64-windows-int_native-validate.tar.xz",
- "junit.xml"
- ],
- "reports": {
- "junit": "junit.xml"
- },
- "when": "always"
- },
- "cache": {
- "key": "no-caching",
- "paths": []
- },
- "dependencies": [],
- "image": null,
- "needs": [
- {
- "artifacts": false,
- "job": "hadrian-ghc-in-ghci"
- }
- ],
- "rules": [
- {
- "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
- "when": "on_success"
- }
- ],
- "script": [
- "bash .gitlab/ci.sh setup",
- "bash .gitlab/ci.sh configure",
- "bash .gitlab/ci.sh build_hadrian",
- "bash .gitlab/ci.sh test_hadrian"
- ],
- "stage": "full-build",
- "tags": [
- "new-x86_64-windows"
- ],
- "variables": {
- "BIGNUM_BACKEND": "native",
- "BIN_DIST_NAME": "ghc-x86_64-windows-int_native-validate",
- "BUILD_FLAVOUR": "validate",
- "CABAL_INSTALL_VERSION": "3.8.1.0",
- "CONFIGURE_ARGS": "",
- "GHC_VERSION": "9.4.3",
- "HADRIAN_ARGS": "--docs=no-sphinx",
- "LANG": "en_US.UTF-8",
- "MSYSTEM": "CLANG64",
- "TEST_ENV": "x86_64-windows-int_native-validate"
- }
- },
"x86_64-windows-validate": {
"after_script": [
"bash .gitlab/ci.sh save_cache",
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -50,7 +50,7 @@ module GHC.Core.Type (
mkSpecForAllTy, mkSpecForAllTys,
mkVisForAllTys, mkTyCoInvForAllTy,
mkInfForAllTy, mkInfForAllTys,
- splitForAllTyCoVars,
+ splitForAllTyCoVars, splitForAllTyVars,
splitForAllReqTyBinders, splitForAllInvisTyBinders,
splitForAllForAllTyBinders,
splitForAllTyCoVar_maybe, splitForAllTyCoVar,
=====================================
compiler/GHC/Hs/Utils.hs
=====================================
@@ -86,7 +86,7 @@ module GHC.Hs.Utils(
mkLetStmt,
-- * Collecting binders
- isUnliftedHsBind, isBangedHsBind,
+ isUnliftedHsBind, isUnliftedHsBinds, isBangedHsBind,
collectLocalBinders, collectHsValBinders, collectHsBindListBinders,
collectHsIdBinders,
@@ -905,55 +905,106 @@ to return a [Name] or [Id]. Before renaming the record punning
and wild-card mechanism makes it hard to know what is bound.
So these functions should not be applied to (HsSyn RdrName)
-Note [Unlifted id check in isUnliftedHsBind]
+Note [isUnliftedHsBind]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The function isUnliftedHsBind is used to complain if we make a top-level
-binding for a variable of unlifted type.
+The function isUnliftedHsBind tells if the binding binds a variable of
+unlifted type. e.g.
-Such a binding is illegal if the top-level binding would be unlifted;
-but also if the local letrec generated by desugaring AbsBinds would be.
-E.g.
- f :: Num a => (# a, a #)
- g :: Num a => a -> a
- f = ...g...
- g = ...g...
+ - I# x = blah
+ - Just (I# x) = blah
-The top-level bindings for f,g are not unlifted (because of the Num a =>),
-but the local, recursive, monomorphic bindings are:
+isUnliftedHsBind is used in two ways:
+* To complain if we make a top-level binding for a variable of unlifted
+ type. E.g. any of the above bindings are illegal at top level
+
+* To generate a case expression for a non-recursive local let. E.g.
+ let Just (I# x) = blah in body
+ ==>
+ case blah of Just (I# x) -> body
+ See GHC.HsToCore.Expr.dsUnliftedBind.
+
+Wrinkles:
+
+(W1) For AbsBinds we must check if the local letrec generated by desugaring
+ AbsBinds would be unlifted; so we just recurse into the abs_binds. E.g.
+ f :: Num a => (# a, a #)
+ g :: Num a => a -> a
+ f = ...g...
+ g = ...g...
+
+ The top-level bindings for f,g are not unlifted (because of the Num a =>),
+ but the local, recursive, monomorphic bindings are:
t = /\a \(d:Num a).
letrec fm :: (# a, a #) = ...g...
gm :: a -> a = ...f...
in (fm, gm)
-Here the binding for 'fm' is illegal. So generally we check the abe_mono types.
+ Here the binding for 'fm' is illegal. So we recurse into the abs_binds
+
+(W2) BUT we have a special case when abs_sig is true;
+ see Note [The abs_sig field of AbsBinds] in GHC.Hs.Binds
+
+(W3) isUnliftedHsBind returns False even if the binding itself is
+ unlifted, provided it binds only lifted variables. E.g.
+ - (# a,b #) = (# reverse xs, xs #)
+
+ - x = sqrt# y# :: Float#
+
+ - type Unl :: UnliftedType
+ data Unl = MkUnl Int
+ MkUnl z = blah
-BUT we have a special case when abs_sig is true;
- see Note [The abs_sig field of AbsBinds] in GHC.Hs.Binds
+ In each case the RHS of the "=" has unlifted type, but isUnliftedHsBind
+ returns False. Reason: see GHC Proposal #35
+ https://github.com/ghc-proposals/ghc-proposals/blob/master/
+ proposals/0035-unbanged-strict-patterns.rst
+
+(W4) In particular, (W3) applies to a pattern that binds no variables at all.
+ So { _ = sqrt# y :: Float# } returns False from isUnliftedHsBind, but
+ { x = sqrt# y :: Float# } returns True.
+ This is arguably a bit confusing (see #22719)
-}
----------------- Bindings --------------------------
-- | Should we treat this as an unlifted bind? This will be true for any
-- bind that binds an unlifted variable, but we must be careful around
--- AbsBinds. See Note [Unlifted id check in isUnliftedHsBind]. For usage
+-- AbsBinds. See Note [isUnliftedHsBind]. For usage
-- information, see Note [Strict binds checks] is GHC.HsToCore.Binds.
isUnliftedHsBind :: HsBind GhcTc -> Bool -- works only over typechecked binds
-isUnliftedHsBind bind
- | XHsBindsLR (AbsBinds { abs_exports = exports, abs_sig = has_sig }) <- bind
- = if has_sig
- then any (is_unlifted_id . abe_poly) exports
- else any (is_unlifted_id . abe_mono) exports
+isUnliftedHsBind (XHsBindsLR (AbsBinds { abs_exports = exports
+ , abs_sig = has_sig
+ , abs_binds = binds }))
+ | has_sig = any (is_unlifted_id . abe_poly) exports
+ | otherwise = isUnliftedHsBinds binds
+ -- See wrinkle (W1) and (W2) in Note [isUnliftedHsBind]
-- If has_sig is True we will never generate a binding for abe_mono,
-- so we don't need to worry about it being unlifted. The abe_poly
-- binding might not be: e.g. forall a. Num a => (# a, a #)
+ -- If has_sig is False, just recurse
- | otherwise
- = any is_unlifted_id (collectHsBindBinders CollNoDictBinders bind)
- where
- is_unlifted_id id = isUnliftedType (idType id)
- -- bindings always have a fixed RuntimeRep, so it's OK
- -- to call isUnliftedType here
+isUnliftedHsBind (FunBind { fun_id = L _ fun })
+ = is_unlifted_id fun
+
+isUnliftedHsBind (VarBind { var_id = var })
+ = is_unlifted_id var
+
+isUnliftedHsBind (PatBind { pat_lhs = pat })
+ = any is_unlifted_id (collectPatBinders CollNoDictBinders pat)
+ -- If we changed our view on (W3) you could add
+ -- || isUnliftedType pat_ty
+ -- to this check
+
+isUnliftedHsBind (PatSynBind {}) = panic "isUnliftedBind: PatSynBind"
+
+isUnliftedHsBinds :: LHsBinds GhcTc -> Bool
+isUnliftedHsBinds = anyBag (isUnliftedHsBind . unLoc)
+
+is_unlifted_id :: Id -> Bool
+is_unlifted_id id = isUnliftedType (idType id)
+ -- Bindings always have a fixed RuntimeRep, so it's OK
+ -- to call isUnliftedType here
-- | Is a binding a strict variable or pattern bind (e.g. @!x = ...@)?
isBangedHsBind :: HsBind GhcTc -> Bool
=====================================
compiler/GHC/HsToCore/Expr.hs
=====================================
@@ -197,7 +197,7 @@ dsUnliftedBind (FunBind { fun_id = L l fun
; let rhs' = core_wrap (mkOptTickBox tick rhs)
; return (bindNonRec fun rhs' body) }
-dsUnliftedBind (PatBind {pat_lhs = pat, pat_rhs = grhss
+dsUnliftedBind (PatBind { pat_lhs = pat, pat_rhs = grhss
, pat_ext = (ty, _) }) body
= -- let C x# y# = rhs in body
-- ==> case rhs of C x# y# -> body
=====================================
compiler/GHC/Tc/Gen/Bind.hs
=====================================
@@ -49,7 +49,7 @@ import GHC.Tc.Gen.Pat
import GHC.Tc.Utils.TcMType
import GHC.Tc.Instance.Family( tcGetFamInstEnvs )
import GHC.Tc.Utils.TcType
-import GHC.Tc.Validity (checkValidType)
+import GHC.Tc.Validity (checkValidType, checkEscapingKind)
import GHC.Core.Predicate
import GHC.Core.Reduction ( Reduction(..) )
@@ -906,7 +906,8 @@ mkInferredPolyId residual insoluble qtvs inferred_theta poly_name mb_sig_inst mo
, ppr inferred_poly_ty])
; unless insoluble $
addErrCtxtM (mk_inf_msg poly_name inferred_poly_ty) $
- checkValidType (InfSigCtxt poly_name) inferred_poly_ty
+ do { checkEscapingKind inferred_poly_ty
+ ; checkValidType (InfSigCtxt poly_name) inferred_poly_ty }
-- See Note [Validity of inferred types]
-- If we found an insoluble error in the function definition, don't
-- do this check; otherwise (#14000) we may report an ambiguity
=====================================
compiler/GHC/Tc/TyCl.hs
=====================================
@@ -4408,10 +4408,7 @@ checkValidDataCon dflags existential_ok tc con
-- e.g. reject this: MkT :: T (forall a. a->a)
-- Reason: it's really the argument of an equality constraint
; checkValidMonoType orig_res_ty
-
- -- Check for an escaping result kind
- -- See Note [Check for escaping result kind]
- ; checkEscapingKind con
+ ; checkEscapingKind (dataConWrapperType con)
-- For /data/ types check that each argument has a fixed runtime rep
-- If we are dealing with a /newtype/, we allow representation
@@ -4576,47 +4573,6 @@ checkNewDataCon con
ok_mult OneTy = True
ok_mult _ = False
-
--- | Reject nullary data constructors where a type variable
--- would escape through the result kind
--- See Note [Check for escaping result kind]
-checkEscapingKind :: DataCon -> TcM ()
-checkEscapingKind data_con
- | null eq_spec, null theta, null arg_tys
- , let tau_kind = typeKind res_ty
- , Nothing <- occCheckExpand (univ_tvs ++ ex_tvs) tau_kind
- -- Ensure that none of the tvs occur in the kind of the forall
- -- /after/ expanding type synonyms.
- -- See Note [Phantom type variables in kinds] in GHC.Core.Type
- = failWithTc $ TcRnForAllEscapeError (dataConWrapperType data_con) tau_kind
- | otherwise
- = return ()
- where
- (univ_tvs, ex_tvs, eq_spec, theta, arg_tys, res_ty)
- = dataConFullSig data_con
-
-{- Note [Check for escaping result kind]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider:
- type T :: TYPE (BoxedRep l)
- data T = MkT
-This is not OK: we get
- MkT :: forall l. T @l :: TYPE (BoxedRep l)
-which is ill-kinded.
-
-For ordinary type signatures f :: blah, we make this check as part of kind-checking
-the type signature; see Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType.
-But for data constructors we check the type piecemeal, and there is no very
-convenient place to do it. For example, note that it only applies for /nullary/
-constructors. If we had
- data T = MkT Int
-then the type of MkT would be MkT :: forall l. Int -> T @l, which is fine.
-
-So we make the check in checkValidDataCon.
-
-Historical note: we used to do the check in checkValidType (#20929 discusses).
--}
-
-------------------------------
checkValidClass :: Class -> TcM ()
checkValidClass cls
=====================================
compiler/GHC/Tc/Validity.hs
=====================================
@@ -12,7 +12,7 @@ module GHC.Tc.Validity (
Rank(..), UserTypeCtxt(..), checkValidType, checkValidMonoType,
checkValidTheta,
checkValidInstance, checkValidInstHead, validDerivPred,
- checkTySynRhs,
+ checkTySynRhs, checkEscapingKind,
checkValidCoAxiom, checkValidCoAxBranch,
checkValidTyFamEqn, checkValidAssocTyFamDeflt, checkConsistentFamInst,
arityErr,
@@ -466,6 +466,53 @@ checkTySynRhs ctxt ty
where
actual_kind = typeKind ty
+{- Note [Check for escaping result kind]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider:
+ type T :: TYPE (BoxedRep l)
+ data T = MkT
+This is not OK: we get
+ MkT :: forall l. T @l :: TYPE (BoxedRep l)
+which is ill-kinded.
+
+For ordinary /user-written type signatures f :: blah, we make this
+check as part of kind-checking the type signature in tcHsSigType; see
+Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType.
+
+But in two other places we need to check for an escaping result kind:
+
+* For data constructors we check the type piecemeal, and there is no
+ very convenient place to do it. For example, note that it only
+ applies for /nullary/ constructors. If we had
+ data T = MkT Int
+ then the type of MkT would be MkT :: forall l. Int -> T @l, which is fine.
+
+ So we make the check in checkValidDataCon.
+
+* When inferring the type of a function, there is no user-written type
+ that we are checking. Forgetting this led to #22743. Now we call
+ checkEscapingKind in GHC.Tc.Gen.Bind.mkInferredPolyId
+
+Historical note: we used to do the escaping-kind check in
+checkValidType (#20929 discusses), but that is now redundant.
+-}
+
+checkEscapingKind :: Type -> TcM ()
+-- Give a sigma-type (forall a1 .. an. ty), where (ty :: ki),
+-- check that `ki` does not mention any of the binders a1..an.
+-- Otherwise the type is ill-kinded
+-- See Note [Check for escaping result kind]
+checkEscapingKind poly_ty
+ | (tvs, tau) <- splitForAllTyVars poly_ty
+ , let tau_kind = typeKind tau
+ , Nothing <- occCheckExpand tvs tau_kind
+ -- Ensure that none of the tvs occur in the kind of the forall
+ -- /after/ expanding type synonyms.
+ -- See Note [Phantom type variables in kinds] in GHC.Core.Type
+ = failWithTc $ TcRnForAllEscapeError poly_ty tau_kind
+ | otherwise
+ = return ()
+
funArgResRank :: Rank -> (Rank, Rank) -- Function argument and result
funArgResRank (LimitedRank _ arg_rank) = (arg_rank, LimitedRank (forAllAllowed arg_rank) arg_rank)
funArgResRank other_rank = (other_rank, other_rank)
@@ -762,6 +809,9 @@ check_type ve@(ValidityEnv{ ve_tidy_env = env
; check_type (ve{ve_tidy_env = env'}) tau
-- Allow foralls to right of arrow
+ -- Note: skolem-escape in types (e.g. forall r (a::r). a) is handled
+ -- by tcHsSigType and the constraint solver, so no need to
+ -- check it here; c.f. #20929
}
where
(tvbs, phi) = tcSplitForAllTyVarBinders ty
=====================================
docs/users_guide/exts/primitives.rst
=====================================
@@ -136,7 +136,7 @@ There are some restrictions on the use of primitive types:
f x = let !(Foo a b, w) = ..rhs.. in ..body..
- since ``b`` has type ``Int#``.
+ since ``b`` has type ``Int#``. See :ref:`recursive-and-polymorphic-let-bindings`.
.. _unboxed-tuples:
@@ -198,7 +198,8 @@ example desugars like this:
q = snd t
in ..body..
-Indeed, the bindings can even be recursive.
+Indeed, the bindings can even be recursive. See :ref:`recursive-and-polymorphic-let-bindings`
+for a more precise account.
To refer to the unboxed tuple type constructors themselves, e.g. if you
want to attach instances to them, use ``(# #)``, ``(#,#)``, ``(#,,#)``, etc.
@@ -436,9 +437,13 @@ argument either way), GHC currently disallows the more general type
``PEither @l Int Bool -> Bool``. This is a consequence of the
`representation-polymorphic binder restriction <#representation-polymorphism-restrictions>`__,
-Due to :ghc-ticket:`19487`, it's
-currently not possible to declare levity-polymorphic data types with nullary
-data constructors. There's a workaround, though: ::
+Pattern matching against an unlifted data type work just like that for lifted
+types; but see :ref:`recursive-and-polymorphic-let-bindings` for the semantics of
+pattern bindings involving unlifted data types.
+
+Due to :ghc-ticket:`19487`, it is
+not currently possible to declare levity-polymorphic data types with nullary
+data constructors. There is a workaround, though: ::
type T :: TYPE (BoxedRep l)
data T where
=====================================
docs/users_guide/exts/strict.rst
=====================================
@@ -116,12 +116,10 @@ In both cases ``e`` is evaluated before starting to evaluate ``body``.
Note the following points:
-- This form is not the same as a bang pattern:
- The declarations ``f3 (x,y) = ...`` and ``f4 !(x,y) = ....``
- are equivalent (because the constructor pattern ``(x,y)`` forces the argument),
- but the expressions ``let (p,q) = e in body`` and ``let !(p,q) = e in body``
- are different. The former will not evaluate ``e`` unless
- ``p`` or ``q`` is forced in ``body``.
+- A strict binding (with a top level ``!``) should not be thought of as a regular
+ pattern binding that happens to have a bang pattern (:ref:`bang-patterns-informal`) on the LHS.
+ Rather, the top level ``!`` should be considered part of the let-binding, rather than
+ part of the pattern. This makes a difference when we come to the rules in :ref:`bang-patterns-sem`.
- Only a top-level bang (perhaps under parentheses) makes the binding strict; otherwise,
it is considered a normal bang pattern. For example, ::
@@ -377,20 +375,62 @@ Haskell Report.
Replace the "Translation" there with the following one. Given
``let { bind1 ... bindn } in body``:
-.. admonition:: FORCE
+.. admonition:: SPLIT-LAZY
- Replace any binding ``!p = e`` with ``v = case e of p -> (x1, ..., xn); (x1, ..., xn) = v`` and replace
- ``body`` with ``v seq body``, where ``v`` is fresh. This translation works fine if
- ``p`` is already a variable ``x``, but can obviously be optimised by not
- introducing a fresh variable ``v``.
+ Given a lazy pattern binding ``p = e``, where ``p`` is not a variable,
+ and ``x1...xn`` are the variables bound by ``p``,
+ and all these binders have lifted type,
+ replace the binding with this (where ``v`` is fresh)::
-.. admonition:: SPLIT
+ v = case e of { p -> (x1, ..., xn) }
+ x1 = case v of { (x1, ..., xn) -> x1 }
+ ...
+ xn = case v of { (x1, ..., xn) -> xn }``
- Replace any binding ``p = e``, where ``p`` is not a variable, with
- ``v = e; x1 = case v of p -> x1; ...; xn = case v of p -> xn``, where
- ``v`` is fresh and ``x1``.. ``xn`` are the bound variables of ``p``.
- Again if ``e`` is a variable, this can be optimised by not introducing a
- fresh variable.
+ If n=1 (i.e. exactly one variable is bound),
+ the desugaring uses the ``Solo`` type to make a 1-tuple.
+
+.. admonition:: SPLIT-STRICT
+
+ Given a strict pattern binding ``!p = e``, where
+ ``x1...xn`` are the variables bound by ``p``,
+ and all these binders have lifted type:
+
+ 1. Replace the binding with this (where ``v`` is fresh)::
+
+ v = case e of { !p -> (x1, ..., xn) }
+ (x1, ..., xn) = v
+
+ 2. Replace ``body`` with ``v `seq` body``.
+
+ As in SPLIT-LAZY, if n=1 the desugaring uses the ``Solo`` type to make a 1-tuple.
+
+ This transformation is illegal at the top
+ level of a module (since there is no ``body``), so strict bindings are illegal at top level.
+
+ The transformation is correct when ``p`` is a variable ``x``, but can be optimised to::
+
+ let !x = e in body ==> let x = e in x `seq` body
+
+.. admonition:: CASE
+
+ Given a non-recursive strict pattern binding ``!p = e``,
+ where ``x1...xn`` are the variables bound by ``p``,
+ and any of the binders has unlifted type:
+ replace the binding with nothing at all, and replace
+ ``body`` with ``case e of p -> body``.
+
+ This transformation is illegal at the top
+ level of a module, so such bindings are rejected.
+
+ The result of this transformation is ill-scoped if any of the binders
+ ``x1...xn`` appears in ``e``; hence the restriction to non-recursive pattern bindings.
+
+ Exactly the same transformation applies to a non-recursive lazy pattern binding
+ (i.e. one lacking a top-level ``!``) that binds any unlifted variables; but
+ such a binding emits a warning :ghc-flag:`-Wunbanged-strict-patterns`. The
+ warning encourages the programmer to make visible the fact that this binding
+ is necessarily strict.
The result will be a (possibly) recursive set of bindings, binding
only simple variables on the left hand side. (One could go one step
@@ -412,56 +452,106 @@ Here is a simple non-recursive case: ::
!x = factorial y
in body
- ===> (FORCE)
- let x = factorial y in x `seq` body
+ ===> (SPLIT-STRICT)
+ let x = factorial y in x `seq` body
===> (inline seq)
- let x = factorial y in case x of x -> body
+ let x = factorial y in case x of x -> body
===> (inline x)
- case factorial y of x -> body
+ case factorial y of x -> body
Same again, only with a pattern binding: ::
- let !(Just x, Left y) = e in body
+ let !(Just x) = e in body
- ===> (FORCE)
- let v = case e of (Just x, Left y) -> (x,y)
- (x,y) = v
- in v `seq` body
+ ===> (SPLIT-STRICT)
+ let v = case e of !(Just x) -> Solo x
+ Solo x = v
+ in v `seq` body
- ===> (SPLIT)
- let v = case e of (Just x, Left y) -> (x,y)
- x = case v of (x,y) -> x
- y = case v of (x,y) -> y
- in v `seq` body
+ ===> (SPLIT-LAZY, drop redundant bang)
+ let v = case e of Just x -> Solo x
+ x = case v of Solo x -> x
+ in v `seq` body
===> (inline seq, float x,y bindings inwards)
- let v = case e of (Just x, Left y) -> (x,y)
- in case v of v -> let x = case v of (x,y) -> x
- y = case v of (x,y) -> y
- in body
+ let v = case e of Just x -> Solo x
+ in case v of !v -> let x = case v of Solo x -> x
+ in body
===> (fluff up v's pattern; this is a standard Core optimisation)
- let v = case e of (Just x, Left y) -> (x,y)
- in case v of v@(p,q) -> let x = case v of (x,y) -> x
- y = case v of (x,y) -> y
- in body
+ let v = case e of Just x -> Solo x
+ in case v of v@(Solo p) -> let x = case v of Solo x -> x
+ in body
===> (case of known constructor)
- let v = case e of (Just x, Left y) -> (x,y)
- in case v of v@(p,q) -> let x = p
- y = q
- in body
+ let v = case e of Just x -> Solo x
+ in case v of v@(Solo p) -> let x = p
+ in body
- ===> (inline x,y, v)
- case (case e of (Just x, Left y) -> (x,y) of
- (p,q) -> body[p/x, q/y]
+ ===> (inline x, v)
+ case (case e of Just x -> Solo x) of
+ Solo p -> body[p/x, q/y]
===> (case of case)
- case e of (Just x, Left y) -> body[p/x, q/y]
+ case e of Just x -> body[p/x, q/y]
+
+The final form is just what we want: a simple case expression. Notice, crucially,
+that that *pattern* ``Just x`` is forced eagerly, but ``x`` itself is not evaluated
+unless and until ``body`` does so. Note also that this example uses a pattern
+that binds exactly one variable, and illustrates the use of the ``Solo`` 1-tuple.
-The final form is just what we want: a simple case expression.
+Rule (SPLIT-STRICT) applies even if the pattern binds no variables::
+
+ let !(True,False) = e in body
+
+ ===> (SPLIT-STRICT)
+ let v = case e of !(True,False) -> (); () = v in v `seq` body
+
+ ===> (inline, simplify, drop redundant bang)
+ case e of (True,False) -> body
+
+That is, we force ``e`` and check that it has the right form before proceeding with ``body``.
+This happens even if the pattern is itself vacuous::
+
+ let !_ = e in body
+
+ ===> (SPLIT-STRICT)
+ let v = case e of !_ -> (); () = v in v `seq` body
+
+ ===> (inline, simplify)
+ case e of !_ -> body
+
+Again, ``e`` is forced before evaluating ``body``. This (along with ``!x = e``) is the reason
+that (SPLIT-STRICT) uses a bang-pattern in the ``case`` in the desugared right-hand side.
+
+Note that rule (CASE) applies only when any of the *binders* is unlifted;
+it is irrelevant whether the binding *itself* is unlifted (see
+`GHC proposal #35 <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0035-unbanged-strict-patterns.rst>`__).
+For example (see :ref:`primitives`)::
+
+ let (# a::Int, b::Bool #) = e in body
+ ===> (SPLIT-LAZY)
+ let v = case e of (# a,b #) -> (a,b)
+ a = case v of (a,b) -> a
+ b = case v of (a,b) -> b
+ in body
+
+Even though the tuple pattern is unboxed, it is matched only when ``a`` or ``b`` are evaluated in ``body``.
+
+Here is an example with an unlifted data type::
+
+ type T :: UnliftedType
+ data T = MkT Int
+ f1 x = let MkT y = blah in body1
+ f2 x = let z :: T = blah in body2
+ f3 x = let _ :: T = blah in body3
+
+In ``f1``, even though ``T`` is an unlifted type, the pattern ``MkT y`` binds a lifted
+variable ``y``, so (SPLIT-LAZY) applies, and ``blah`` is not evaluated until ``body1`` evaluates ``y``.
+In contrast, in ``f2`` the pattern ``z :: T`` binds a variable ``z`` of unlifted type, so (CASE) applies
+and the let-binding is strict. In ``f3`` the pattern binds no variables, so again it is lazy like ``f1``.
Here is a recursive case ::
@@ -469,14 +559,14 @@ Here is a recursive case ::
!xs = factorial y : xs
in body
- ===> (FORCE)
- letrec xs = factorial y : xs in xs `seq` body
+ ===> (SPLIT-STRICT)
+ letrec xs = factorial y : xs in xs `seq` body
===> (inline seq)
- letrec xs = factorial y : xs in case xs of xs -> body
+ letrec xs = factorial y : xs in case xs of xs -> body
===> (eliminate case of value)
- letrec xs = factorial y : xs in body
+ letrec xs = factorial y : xs in body
and a polymorphic one: ::
@@ -484,10 +574,11 @@ and a polymorphic one: ::
!f = fst (reverse, True)
in body
- ===> (FORCE)
- let f = /\a. fst (reverse a, True) in f `seq` body
+ ===> (SPLIT-STRICT)
+ let f = /\a. fst (reverse a, True) in f `seq` body
+
===> (inline seq, inline f)
- case (/\a. fst (reverse a, True)) of f -> body
+ case (/\a. fst (reverse a, True)) of f -> body
Notice that the ``seq`` is added only in the translation to Core
If we did it in Haskell source, thus ::
@@ -507,10 +598,10 @@ intuitive: ::
!f = fst (member, True)
in body
- ===> (FORCE)
- let f = /\a \(d::Eq a). fst (member, True) in f `seq` body
+ ===> (SPLIT-STRICT)
+ let f = /\a \(d::Eq a). fst (member, True) in f `seq` body
===> (inline seq, case of value)
- let f = /\a \(d::Eq a). fst (member, True) in body
+ let f = /\a \(d::Eq a). fst (member, True) in body
Note that the bang has no effect at all in this case
=====================================
libraries/process
=====================================
@@ -1 +1 @@
-Subproject commit 7c6871d89bd87875b4e402de26d7267c11e617a9
+Subproject commit d295bcceb64e9f17f08999c6333aaabda4d5ee96
=====================================
testsuite/tests/deSugar/should_compile/T22719.hs
=====================================
@@ -0,0 +1,21 @@
+{-# LANGUAGE UnliftedDatatypes #-}
+{-# OPTIONS_GHC -Wall #-}
+
+module T22719 where
+
+import GHC.Exts
+
+type T :: UnliftedType
+data T = T
+
+f :: Int -> T
+f 0 = T
+f n = f (n-1)
+
+-- ex1 is lazy in (f 7)
+ex1 :: ()
+ex1 = let _ = f 7 in ()
+
+-- ex2 is strict in (f 10)
+ex2 :: ()
+ex2 = let _a = f 10 in ()
=====================================
testsuite/tests/deSugar/should_compile/T22719.stderr
=====================================
@@ -0,0 +1,30 @@
+
+==================== Tidy Core ====================
+Result size of Tidy Core
+ = {terms: 25, types: 10, coercions: 0, joins: 0/0}
+
+-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
+ex1 :: ()
+[GblId, Unf=OtherCon []]
+ex1 = GHC.Tuple.Prim.()
+
+Rec {
+-- RHS size: {terms: 15, types: 5, coercions: 0, joins: 0/0}
+f [Occ=LoopBreaker] :: Int -> T
+[GblId, Arity=1, Unf=OtherCon []]
+f = \ (ds :: Int) ->
+ case ds of wild { I# ds1 ->
+ case ds1 of {
+ __DEFAULT -> f (- @Int GHC.Num.$fNumInt wild (GHC.Types.I# 1#));
+ 0# -> T22719.T
+ }
+ }
+end Rec }
+
+-- RHS size: {terms: 6, types: 1, coercions: 0, joins: 0/0}
+ex2 :: ()
+[GblId]
+ex2 = case f (GHC.Types.I# 10#) of { T -> GHC.Tuple.Prim.() }
+
+
+
=====================================
testsuite/tests/deSugar/should_compile/all.T
=====================================
@@ -112,3 +112,4 @@ test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques'])
test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds'])
test('T19969', normal, compile, ['-ddump-simpl -dsuppress-uniques'])
test('T19883', normal, compile, [''])
+test('T22719', normal, compile, ['-ddump-simpl -dsuppress-uniques -dno-typeable-binds'])
=====================================
testsuite/tests/polykinds/T22743.hs
=====================================
@@ -0,0 +1,10 @@
+{-# LANGUAGE DataKinds #-}
+module M where
+
+import GHC.Exts
+import Data.Kind
+
+f :: forall f (g :: Type) (a :: TYPE (f g)). Int -> a
+f = f
+
+x = f 0
=====================================
testsuite/tests/polykinds/T22743.stderr
=====================================
@@ -0,0 +1,7 @@
+
+T22743.hs:10:1: error: [GHC-31147]
+ • Quantified type's kind mentions quantified type variable
+ type: ‘forall {f :: * -> RuntimeRep} {g} {a :: TYPE (f g)}. a’
+ where the body of the forall has this kind: ‘TYPE (f g)’
+ • When checking the inferred type
+ x :: forall {f :: * -> RuntimeRep} {g} {a :: TYPE (f g)}. a
=====================================
testsuite/tests/polykinds/all.T
=====================================
@@ -241,3 +241,4 @@ test('T19739c', normal, compile, [''])
test('T19739d', normal, compile, [''])
test('T22379a', normal, compile, [''])
test('T22379b', normal, compile, [''])
+test('T22743', normal, compile_fail, [''])
=====================================
utils/hsc2hs
=====================================
@@ -1 +1 @@
-Subproject commit 219bba062e804db0bea4bf3ffcaaba2df46334f8
+Subproject commit 0811ae8f29d0cc2591bbe89bc034ae14143d0443
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/973987d8c68c109b4113c4bbdf3866a4ba923172...5fef5d40a855e782242ef996f52fbb339133da6c
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/973987d8c68c109b4113c4bbdf3866a4ba923172...5fef5d40a855e782242ef996f52fbb339133da6c
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230116/a78707b5/attachment-0001.html>
More information about the ghc-commits
mailing list