summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShayan Najd <sh.najd@gmail.com>2017-08-13 18:37:54 +0000
committerShayan Najd <sh.najd@gmail.com>2017-08-13 18:37:54 +0000
commit6752680ee9253aec991cfde4dc447479564e06e7 (patch)
treeb4802e0583eeb0288123bfc53926ef68b124eabe
parent1c771765295bf789d4cda228a1f87c5a2e8e42b5 (diff)
parentc6462ab02882779d7e33f2cac00cd89a9ac192f1 (diff)
downloadhaskell-6752680ee9253aec991cfde4dc447479564e06e7.tar.gz
Merge branch 'master' of git://git.haskell.org/ghc into GrowableAST
# Conflicts: # compiler/deSugar/DsArrows.hs # compiler/deSugar/DsBinds.hs # compiler/hsSyn/HsBinds.hs # compiler/hsSyn/HsDecls.hs # compiler/hsSyn/HsExpr.hs # compiler/hsSyn/HsLit.hs # compiler/hsSyn/HsPat.hs # compiler/typecheck/TcBinds.hs # compiler/typecheck/TcClassDcl.hs # compiler/typecheck/TcHsSyn.hs
-rw-r--r--.gitignore2
-rw-r--r--.gitmodules16
-rw-r--r--Makefile8
-rw-r--r--aclocal.m43
-rw-r--r--compiler/backpack/RnModIface.hs1
-rw-r--r--compiler/basicTypes/DataCon.hs4
-rw-r--r--compiler/basicTypes/Id.hs4
-rw-r--r--compiler/basicTypes/PatSyn.hs54
-rw-r--r--compiler/basicTypes/SrcLoc.hs4
-rw-r--r--compiler/basicTypes/Var.hs13
-rw-r--r--compiler/cmm/CmmMonad.hs5
-rw-r--r--compiler/cmm/CmmOpt.hs2
-rw-r--r--compiler/coreSyn/CoreLint.hs14
-rw-r--r--compiler/coreSyn/PprCore.hs2
-rw-r--r--compiler/coreSyn/TrieMap.hs3
-rw-r--r--compiler/deSugar/Check.hs178
-rw-r--r--compiler/deSugar/Coverage.hs41
-rw-r--r--compiler/deSugar/DsArrows.hs10
-rw-r--r--compiler/deSugar/DsBinds.hs244
-rw-r--r--compiler/deSugar/DsExpr.hs11
-rw-r--r--compiler/deSugar/DsMeta.hs195
-rw-r--r--compiler/deSugar/Match.hs9
-rw-r--r--compiler/ghc.cabal.in7
-rw-r--r--compiler/ghci/ByteCodeGen.hs471
-rw-r--r--compiler/ghci/ByteCodeInstr.hs4
-rw-r--r--compiler/ghci/ByteCodeTypes.hs6
-rw-r--r--compiler/ghci/GHCi.hs (renamed from compiler/ghci/GHCi.hsc)26
-rw-r--r--compiler/ghci/Linker.hs9
-rw-r--r--compiler/ghci/RtClosureInspect.hs4
-rw-r--r--compiler/hsSyn/HsBinds.hs121
-rw-r--r--compiler/hsSyn/HsDecls.hs19
-rw-r--r--compiler/hsSyn/HsExpr.hs2
-rw-r--r--compiler/hsSyn/HsLit.hs2
-rw-r--r--compiler/hsSyn/HsPat.hs7
-rw-r--r--compiler/hsSyn/HsUtils.hs107
-rw-r--r--compiler/iface/BuildTyCl.hs70
-rw-r--r--compiler/iface/IfaceSyn.hs1
-rw-r--r--compiler/iface/IfaceType.hs12
-rw-r--r--compiler/iface/TcIface.hs12
-rw-r--r--compiler/iface/ToIface.hs12
-rw-r--r--compiler/iface/ToIface.hs-boot2
-rw-r--r--compiler/llvmGen/Llvm/AbsSyn.hs4
-rw-r--r--compiler/llvmGen/Llvm/PpLlvm.hs2
-rw-r--r--compiler/llvmGen/LlvmCodeGen/CodeGen.hs4
-rw-r--r--compiler/main/DriverPipeline.hs1
-rw-r--r--compiler/main/DynFlags.hs8
-rw-r--r--compiler/main/InteractiveEvalTypes.hs6
-rw-r--r--compiler/main/Packages.hs5
-rw-r--r--compiler/main/SysTools.hs14
-rw-r--r--compiler/nativeGen/RegAlloc/Graph/Coalesce.hs2
-rw-r--r--compiler/nativeGen/RegAlloc/Graph/Spill.hs2
-rw-r--r--compiler/nativeGen/X86/CodeGen.hs2
-rw-r--r--compiler/parser/Lexer.x4
-rw-r--r--compiler/parser/RdrHsSyn.hs28
-rw-r--r--compiler/prelude/KnownUniques.hs9
-rw-r--r--compiler/prelude/PrelRules.hs2
-rw-r--r--compiler/prelude/THNames.hs124
-rw-r--r--compiler/prelude/TysWiredIn.hs23
-rw-r--r--compiler/prelude/primops.txt.pp2
-rw-r--r--compiler/rename/RnBinds.hs26
-rw-r--r--compiler/rename/RnEnv.hs18
-rw-r--r--compiler/rename/RnExpr.hs5
-rw-r--r--compiler/rename/RnPat.hs9
-rw-r--r--compiler/rename/RnSource.hs21
-rw-r--r--compiler/rename/RnTypes.hs34
-rw-r--r--compiler/rename/RnUtils.hs7
-rw-r--r--compiler/simplCore/CSE.hs2
-rw-r--r--compiler/simplCore/CallArity.hs2
-rw-r--r--compiler/simplCore/OccurAnal.hs9
-rw-r--r--compiler/simplCore/SimplUtils.hs2
-rw-r--r--compiler/simplCore/Simplify.hs3
-rw-r--r--compiler/simplStg/StgCse.hs12
-rw-r--r--compiler/specialise/Specialise.hs6
-rw-r--r--compiler/typecheck/Inst.hs11
-rw-r--r--compiler/typecheck/TcArrows.hs7
-rw-r--r--compiler/typecheck/TcBinds.hs57
-rw-r--r--compiler/typecheck/TcCanonical.hs323
-rw-r--r--compiler/typecheck/TcClassDcl.hs40
-rw-r--r--compiler/typecheck/TcDeriv.hs22
-rw-r--r--compiler/typecheck/TcDerivInfer.hs64
-rw-r--r--compiler/typecheck/TcDerivUtils.hs1
-rw-r--r--compiler/typecheck/TcErrors.hs113
-rw-r--r--compiler/typecheck/TcEvidence.hs8
-rw-r--r--compiler/typecheck/TcExpr.hs52
-rw-r--r--compiler/typecheck/TcFlatten.hs31
-rw-r--r--compiler/typecheck/TcGenDeriv.hs3
-rw-r--r--compiler/typecheck/TcHsSyn.hs83
-rw-r--r--compiler/typecheck/TcHsType.hs387
-rw-r--r--compiler/typecheck/TcInstDcls.hs57
-rw-r--r--compiler/typecheck/TcInteract.hs11
-rw-r--r--compiler/typecheck/TcMType.hs30
-rw-r--r--compiler/typecheck/TcMatches.hs13
-rw-r--r--compiler/typecheck/TcPat.hs6
-rw-r--r--compiler/typecheck/TcPatSyn.hs7
-rw-r--r--compiler/typecheck/TcRnDriver.hs6
-rw-r--r--compiler/typecheck/TcRnTypes.hs93
-rw-r--r--compiler/typecheck/TcSMonad.hs6
-rw-r--r--compiler/typecheck/TcSigs.hs4
-rw-r--r--compiler/typecheck/TcSimplify.hs171
-rw-r--r--compiler/typecheck/TcSplice.hs20
-rw-r--r--compiler/typecheck/TcSplice.hs-boot6
-rw-r--r--compiler/typecheck/TcTyClsDecls.hs285
-rw-r--r--compiler/typecheck/TcTyDecls.hs16
-rw-r--r--compiler/typecheck/TcType.hs62
-rw-r--r--compiler/typecheck/TcUnify.hs165
-rw-r--r--compiler/typecheck/TcUnify.hs-boot7
-rw-r--r--compiler/typecheck/TcValidity.hs63
-rw-r--r--compiler/types/Class.hs4
-rw-r--r--compiler/types/Coercion.hs109
-rw-r--r--compiler/types/Coercion.hs-boot3
-rw-r--r--compiler/types/FamInstEnv.hs162
-rw-r--r--compiler/types/OptCoercion.hs2
-rw-r--r--compiler/types/TyCoRep.hs110
-rw-r--r--compiler/types/TyCon.hs88
-rw-r--r--compiler/types/Type.hs43
-rw-r--r--compiler/types/Type.hs-boot9
-rw-r--r--compiler/types/Unify.hs4
-rw-r--r--compiler/utils/IOEnv.hs7
-rw-r--r--compiler/utils/Json.hs2
-rw-r--r--compiler/utils/ListSetOps.hs26
-rw-r--r--compiler/utils/MonadUtils.hs5
-rw-r--r--compiler/utils/OrdList.hs5
-rw-r--r--compiler/utils/Outputable.hs5
-rw-r--r--compiler/utils/UniqFM.hs4
-rw-r--r--compiler/utils/UniqSet.hs5
-rw-r--r--compiler/utils/Util.hs33
-rw-r--r--configure.ac4
-rw-r--r--docs/core-spec/CoreSyn.ott2
-rw-r--r--docs/users_guide/8.4.1-notes.rst12
-rw-r--r--docs/users_guide/ffi-chap.rst6
-rw-r--r--docs/users_guide/glasgow_exts.rst30
-rw-r--r--docs/users_guide/phases.rst9
-rw-r--r--docs/users_guide/runtime_control.rst4
-rw-r--r--ghc.mk11
-rw-r--r--ghc/hschooks.c2
-rw-r--r--includes/Rts.h6
-rw-r--r--includes/RtsAPI.h2
-rw-r--r--libraries/base/Control/Applicative.hs2
-rw-r--r--libraries/base/Data/Bits.hs8
-rw-r--r--libraries/base/Data/Functor.hs26
-rw-r--r--libraries/base/Data/OldList.hs192
-rw-r--r--libraries/base/Data/Typeable.hs18
-rw-r--r--libraries/base/GHC/Environment.hs45
-rw-r--r--libraries/base/GHC/IO/Encoding.hs12
-rw-r--r--libraries/base/GHC/Natural.hs18
-rw-r--r--libraries/base/GHC/Real.hs2
-rw-r--r--libraries/base/GHC/Stack.hs5
-rw-r--r--libraries/base/System/Environment.hs102
-rw-r--r--libraries/base/System/Environment/Blank.hsc196
-rw-r--r--libraries/base/base.cabal1
-rw-r--r--libraries/base/changelog.md4
-rw-r--r--libraries/base/tests/T12494.hs36
-rw-r--r--libraries/base/tests/T12494.stdout8
-rw-r--r--libraries/base/tests/all.T2
-rw-r--r--libraries/base/tests/functorOperators.hs38
-rw-r--r--libraries/base/tests/functorOperators.stdout16
-rw-r--r--libraries/ghci/GHCi/Message.hs16
-rw-r--r--libraries/ghci/GHCi/TH.hs5
m---------libraries/mtl0
m---------libraries/parsec0
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib.hs836
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs936
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Ppr.hs4
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Syntax.hs26
-rw-r--r--libraries/template-haskell/changelog.md13
-rw-r--r--libraries/template-haskell/template-haskell.cabal2
m---------libraries/text0
m---------libraries/unix0
-rw-r--r--mk/warnings.mk5
-rw-r--r--packages3
-rw-r--r--rts/ProfHeap.c2
-rw-r--r--rts/RaiseAsync.c2
-rw-r--r--rts/RetainerProfile.c4
-rw-r--r--rts/RetainerSet.h2
-rw-r--r--rts/RtsFlags.c189
-rw-r--r--rts/RtsFlags.h5
-rw-r--r--rts/RtsMain.c11
-rw-r--r--rts/RtsStartup.c26
-rw-r--r--rts/RtsSymbols.c2
-rw-r--r--rules/sdist-ghc-file.mk31
-rw-r--r--testsuite/driver/junit.py38
-rw-r--r--testsuite/driver/runtests.py138
-rw-r--r--testsuite/driver/testglobals.py1
-rw-r--r--testsuite/driver/testlib.py1
-rw-r--r--testsuite/mk/test.mk10
-rw-r--r--testsuite/tests/dependent/should_compile/T12176.hs18
-rw-r--r--testsuite/tests/dependent/should_compile/all.T1
-rw-r--r--testsuite/tests/dependent/should_fail/T11471.hs2
-rw-r--r--testsuite/tests/dependent/should_fail/T11471.stderr11
-rw-r--r--testsuite/tests/dependent/should_fail/T13135.hs2
-rw-r--r--testsuite/tests/dependent/should_fail/T13601.hs47
-rw-r--r--testsuite/tests/dependent/should_fail/T13601.stderr6
-rw-r--r--testsuite/tests/dependent/should_fail/T13780a.hs9
-rw-r--r--testsuite/tests/dependent/should_fail/T13780a.stderr6
-rw-r--r--testsuite/tests/dependent/should_fail/T13780b.hs10
-rw-r--r--testsuite/tests/dependent/should_fail/T13780c.hs12
-rw-r--r--testsuite/tests/dependent/should_fail/T13780c.stderr12
-rw-r--r--testsuite/tests/dependent/should_fail/all.T6
-rw-r--r--testsuite/tests/deriving/should_compile/T13998.hs43
-rw-r--r--testsuite/tests/deriving/should_compile/T14045b.hs13
-rw-r--r--testsuite/tests/deriving/should_compile/T14094.hs13
-rw-r--r--testsuite/tests/deriving/should_compile/T14094.stderr26
-rw-r--r--testsuite/tests/deriving/should_compile/all.T3
-rw-r--r--testsuite/tests/deriving/should_fail/T10598_fail3.stderr7
-rw-r--r--testsuite/tests/deriving/should_fail/T8165_fail2.stderr7
-rw-r--r--testsuite/tests/deriving/should_run/T3087.hs2
-rw-r--r--testsuite/tests/driver/T13710/A.hs5
-rw-r--r--testsuite/tests/driver/T13710/A.hs-boot2
-rw-r--r--testsuite/tests/driver/T13710/B.hs3
-rw-r--r--testsuite/tests/driver/T13710/Makefile6
-rw-r--r--testsuite/tests/driver/T13710/T13710.stdout3
-rw-r--r--testsuite/tests/driver/T13710/all.T4
-rw-r--r--testsuite/tests/gadt/gadt7.stderr6
-rw-r--r--testsuite/tests/ghc-api/T6145.hs2
-rw-r--r--testsuite/tests/ghci.debugger/scripts/all.T3
-rw-r--r--testsuite/tests/ghci.debugger/scripts/break012.stdout14
-rw-r--r--testsuite/tests/indexed-types/should_compile/T12369.hs35
-rw-r--r--testsuite/tests/indexed-types/should_compile/T14045.hs10
-rw-r--r--testsuite/tests/indexed-types/should_compile/all.T2
-rw-r--r--testsuite/tests/indexed-types/should_fail/Overlap4.stderr8
-rw-r--r--testsuite/tests/indexed-types/should_fail/SimpleFail1a.stderr3
-rw-r--r--testsuite/tests/indexed-types/should_fail/SimpleFail1b.stderr8
-rw-r--r--testsuite/tests/indexed-types/should_fail/SimpleFail2a.stderr2
-rw-r--r--testsuite/tests/indexed-types/should_fail/T12867.stderr3
-rw-r--r--testsuite/tests/indexed-types/should_fail/T13877.hs74
-rw-r--r--testsuite/tests/indexed-types/should_fail/T13877.stderr31
-rw-r--r--testsuite/tests/indexed-types/should_fail/T14033.hs10
-rw-r--r--testsuite/tests/indexed-types/should_fail/T14033.stderr6
-rw-r--r--testsuite/tests/indexed-types/should_fail/T14045a.hs13
-rw-r--r--testsuite/tests/indexed-types/should_fail/T14045a.stderr7
-rw-r--r--testsuite/tests/indexed-types/should_fail/T5934.stderr13
-rw-r--r--testsuite/tests/indexed-types/should_fail/TyFamArity1.stderr8
-rw-r--r--testsuite/tests/indexed-types/should_fail/TyFamArity2.stderr9
-rw-r--r--testsuite/tests/indexed-types/should_fail/all.T3
-rw-r--r--testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr3
-rw-r--r--testsuite/tests/parser/should_fail/T7848.hs2
-rw-r--r--testsuite/tests/parser/should_fail/T7848.stderr13
-rw-r--r--testsuite/tests/patsyn/should_compile/T13768.hs33
-rw-r--r--testsuite/tests/patsyn/should_compile/T14058.hs7
-rw-r--r--testsuite/tests/patsyn/should_compile/T14058a.hs19
-rw-r--r--testsuite/tests/patsyn/should_compile/all.T3
-rw-r--r--testsuite/tests/perf/compiler/all.T4
-rw-r--r--testsuite/tests/pmcheck/should_compile/T14086.hs6
-rw-r--r--testsuite/tests/pmcheck/should_compile/all.T2
-rw-r--r--testsuite/tests/polykinds/KindVType.stderr2
-rw-r--r--testsuite/tests/polykinds/T12593.stderr63
-rw-r--r--testsuite/tests/polykinds/T13555.stderr21
-rw-r--r--testsuite/tests/polykinds/T6039.stderr3
-rw-r--r--testsuite/tests/polykinds/T7278.stderr3
-rw-r--r--testsuite/tests/polykinds/T7438.stderr6
-rw-r--r--testsuite/tests/polykinds/T8566.stderr2
-rw-r--r--testsuite/tests/polykinds/T8616.stderr2
-rw-r--r--testsuite/tests/polykinds/T9017.stderr10
-rw-r--r--testsuite/tests/polykinds/T9200b.stderr6
-rw-r--r--testsuite/tests/programs/galois_raytrace/Eval.hs2
-rw-r--r--testsuite/tests/quasiquotation/Makefile4
-rw-r--r--testsuite/tests/quasiquotation/T14028.hs8
-rw-r--r--testsuite/tests/quasiquotation/T14028C.c5
-rw-r--r--testsuite/tests/quasiquotation/T14028Quote.hs6
-rw-r--r--testsuite/tests/quasiquotation/all.T4
-rw-r--r--testsuite/tests/quotes/TH_localname.stderr2
-rw-r--r--testsuite/tests/rename/should_fail/rnfail026.stderr3
-rw-r--r--testsuite/tests/roles/should_compile/Roles13.stderr2
-rw-r--r--testsuite/tests/roles/should_compile/T14101.hs10
-rw-r--r--testsuite/tests/roles/should_compile/all.T1
-rw-r--r--testsuite/tests/rts/T6006.stdout-mingw322
-rw-r--r--testsuite/tests/rts/flags/Makefile6
-rw-r--r--testsuite/tests/rts/flags/T12870.hs6
-rw-r--r--testsuite/tests/rts/flags/T12870_.stdout1
-rw-r--r--testsuite/tests/rts/flags/T12870a.stdout1
-rw-r--r--testsuite/tests/rts/flags/T12870c.stderr1
-rw-r--r--testsuite/tests/rts/flags/T12870d.stdout1
-rw-r--r--testsuite/tests/rts/flags/T12870e.stdout1
-rw-r--r--testsuite/tests/rts/flags/T12870f.stdout1
-rw-r--r--testsuite/tests/rts/flags/T12870g.hs8
-rw-r--r--testsuite/tests/rts/flags/T12870g.stdout1
-rw-r--r--testsuite/tests/rts/flags/T12870h.stdout1
-rw-r--r--testsuite/tests/rts/flags/all.T44
-rw-r--r--testsuite/tests/stranal/should_compile/T9208.hs4
-rw-r--r--testsuite/tests/th/T13642.hs4
-rw-r--r--testsuite/tests/th/T13642.stderr4
-rw-r--r--testsuite/tests/th/T13837.hs10
-rw-r--r--testsuite/tests/th/T13837.stderr10
-rw-r--r--testsuite/tests/th/T13887.hs13
-rw-r--r--testsuite/tests/th/T13887.stdout3
-rw-r--r--testsuite/tests/th/T13968.hs6
-rw-r--r--testsuite/tests/th/T13968.stderr3
-rw-r--r--testsuite/tests/th/T3177a.stderr6
-rw-r--r--testsuite/tests/th/T5358.stderr20
-rw-r--r--testsuite/tests/th/T7276.stderr4
-rw-r--r--testsuite/tests/th/TH_PromotedList.stderr4
-rw-r--r--testsuite/tests/th/TH_RichKinds2.stderr5
-rw-r--r--testsuite/tests/th/all.T5
-rw-r--r--testsuite/tests/typecheck/should_compile/T13594.stderr3
-rw-r--r--testsuite/tests/typecheck/should_compile/all.T2
-rw-r--r--testsuite/tests/typecheck/should_fail/T11356.stderr3
-rw-r--r--testsuite/tests/typecheck/should_fail/T11672.hs9
-rw-r--r--testsuite/tests/typecheck/should_fail/T11672.stderr12
-rw-r--r--testsuite/tests/typecheck/should_fail/T11963.hs29
-rw-r--r--testsuite/tests/typecheck/should_fail/T11963.stderr20
-rw-r--r--testsuite/tests/typecheck/should_fail/T12373.hs10
-rw-r--r--testsuite/tests/typecheck/should_fail/T12373.stderr11
-rw-r--r--testsuite/tests/typecheck/should_fail/T12785b.stderr6
-rw-r--r--testsuite/tests/typecheck/should_fail/T13530.hs11
-rw-r--r--testsuite/tests/typecheck/should_fail/T13530.stderr10
-rw-r--r--testsuite/tests/typecheck/should_fail/T13610.hs11
-rw-r--r--testsuite/tests/typecheck/should_fail/T13610.stderr14
-rw-r--r--testsuite/tests/typecheck/should_fail/T13819.hs14
-rw-r--r--testsuite/tests/typecheck/should_fail/T13819.stderr18
-rw-r--r--testsuite/tests/typecheck/should_fail/T14000.hs8
-rw-r--r--testsuite/tests/typecheck/should_fail/T14000.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T14055.hs6
-rw-r--r--testsuite/tests/typecheck/should_fail/T14055.stderr6
-rw-r--r--testsuite/tests/typecheck/should_fail/T2994.stderr3
-rw-r--r--testsuite/tests/typecheck/should_fail/T3540.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T4875.stderr6
-rw-r--r--testsuite/tests/typecheck/should_fail/T5691.stderr10
-rw-r--r--testsuite/tests/typecheck/should_fail/T7368.stderr6
-rw-r--r--testsuite/tests/typecheck/should_fail/T7368a.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T7453.stderr48
-rw-r--r--testsuite/tests/typecheck/should_fail/T7609.stderr11
-rw-r--r--testsuite/tests/typecheck/should_fail/T7696.stderr4
-rw-r--r--testsuite/tests/typecheck/should_fail/T7778.stderr10
-rw-r--r--testsuite/tests/typecheck/should_fail/T8142.stderr26
-rw-r--r--testsuite/tests/typecheck/should_fail/T8262.stderr6
-rw-r--r--testsuite/tests/typecheck/should_fail/T8603.hs6
-rw-r--r--testsuite/tests/typecheck/should_fail/T8603.stderr18
-rw-r--r--testsuite/tests/typecheck/should_fail/all.T8
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail070.stderr3
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail078.stderr6
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail090.stderr4
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail113.stderr12
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail122.stderr8
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail123.stderr4
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail132.stderr3
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail200.stderr6
-rw-r--r--testsuite/tests/typecheck/should_run/IPLocation.hs6
-rw-r--r--testsuite/tests/unboxedsums/T14051.hs10
-rw-r--r--testsuite/tests/unboxedsums/T14051a.hs6
-rw-r--r--testsuite/tests/unboxedsums/all.T1
-rw-r--r--utils/ghc-cabal/ghc.mk25
-rw-r--r--utils/ghctags/Main.hs1
-rwxr-xr-xvalidate2
343 files changed, 5780 insertions, 3767 deletions
diff --git a/.gitignore b/.gitignore
index 16071f62a6..f2d4be531e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -92,6 +92,7 @@ _darcs/
/bindistprep/
/bindisttest/HelloWorld
/bindisttest/
+/bootstrapping/
/ch01.html
/ch02.html
/compiler/dist/
@@ -171,6 +172,7 @@ _darcs/
/rts/package.conf.install.raw
/stage3.package.conf
/testsuite_summary*.txt
+/testsuite*.xml
/testlog*
/utils/mkUserGuidePart/mkUserGuidePart.cabal
/utils/runghc/runghc.cabal
diff --git a/.gitmodules b/.gitmodules
index 55d360ae10..9e0e8058be 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -70,14 +70,22 @@
path = libraries/filepath
url = ../packages/filepath.git
ignore = none
-[submodule "libraries/hoopl"]
- path = libraries/hoopl
- url = ../packages/hoopl.git
- ignore = none
[submodule "libraries/hpc"]
path = libraries/hpc
url = ../packages/hpc.git
ignore = none
+[submodule "libraries/parsec"]
+ path = libraries/parsec
+ url = ../packages/parsec.git
+ ignore = none
+[submodule "libraries/text"]
+ path = libraries/text
+ url = ../packages/text.git
+ ignore = none
+[submodule "libraries/mtl"]
+ path = libraries/mtl
+ url = ../packages/mtl.git
+ ignore = none
[submodule "libraries/process"]
path = libraries/process
url = ../packages/process.git
diff --git a/Makefile b/Makefile
index 9b888e7cca..8046e36e14 100644
--- a/Makefile
+++ b/Makefile
@@ -129,9 +129,15 @@ endif
@echo "===--- building final phase"
$(MAKE) --no-print-directory -f ghc.mk phase=final $@
+# if BINARY_DIST_DIR is not set, assume we want the old
+# behaviour of placing the binary dist into the current
+# directory. Provide BINARY_DIST_DIR to put the final
+# binary distribution elsewhere.
+BINARY_DIST_DIR ?= .
+
.PHONY: binary-dist
binary-dist: binary-dist-prep
- mv bindistprep/*.tar.$(TAR_COMP_EXT) .
+ mv bindistprep/*.tar.$(TAR_COMP_EXT) "$(BINARY_DIST_DIR)"
.PHONY: binary-dist-prep
binary-dist-prep:
diff --git a/aclocal.m4 b/aclocal.m4
index a9788bf5fb..11606c7842 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -2283,7 +2283,8 @@ AC_DEFUN([FIND_LD],[
[enable_ld_override=yes])
if test "x$enable_ld_override" = "xyes"; then
- AC_CHECK_TARGET_TOOLS([TmpLd], [ld.gold ld.lld ld])
+ TmpLd="$LD" # In case the user set LD
+ AC_CHECK_TARGET_TOOLS([TmpLd], [ld.lld ld.gold ld])
out=`$TmpLd --version`
case $out in
diff --git a/compiler/backpack/RnModIface.hs b/compiler/backpack/RnModIface.hs
index 2e738c1ec6..e3da067ea4 100644
--- a/compiler/backpack/RnModIface.hs
+++ b/compiler/backpack/RnModIface.hs
@@ -646,6 +646,7 @@ rnIfaceCo (IfaceAppCo co1 co2)
= IfaceAppCo <$> rnIfaceCo co1 <*> rnIfaceCo co2
rnIfaceCo (IfaceForAllCo bndr co1 co2)
= IfaceForAllCo <$> rnIfaceTvBndr bndr <*> rnIfaceCo co1 <*> rnIfaceCo co2
+rnIfaceCo (IfaceFreeCoVar c) = pure (IfaceFreeCoVar c)
rnIfaceCo (IfaceCoVarCo lcl) = IfaceCoVarCo <$> pure lcl
rnIfaceCo (IfaceAxiomInstCo n i cs)
= IfaceAxiomInstCo <$> rnIfaceGlobal n <*> pure i <*> mapM rnIfaceCo cs
diff --git a/compiler/basicTypes/DataCon.hs b/compiler/basicTypes/DataCon.hs
index 73bbf2cf57..fa8e0a846f 100644
--- a/compiler/basicTypes/DataCon.hs
+++ b/compiler/basicTypes/DataCon.hs
@@ -778,7 +778,7 @@ mkDataCon name declared_infix prom_info
-- data T a where { MkT :: S }
-- then it's possible that the univ_tvs may hit an assertion failure
-- if you pull on univ_tvs. This case is checked by checkValidDataCon,
--- so the error is detected properly... it's just that asaertions here
+-- so the error is detected properly... it's just that assertions here
-- are a little dodgy.
= con
@@ -902,7 +902,7 @@ dataConExTyVars (MkData { dcExTyVars = tvbs }) = binderVars tvbs
dataConExTyVarBinders :: DataCon -> [TyVarBinder]
dataConExTyVarBinders = dcExTyVars
--- | Both the universal and existentiatial type variables of the constructor
+-- | Both the universal and existential type variables of the constructor
dataConAllTyVars :: DataCon -> [TyVar]
dataConAllTyVars (MkData { dcUnivTyVars = univ_tvs, dcExTyVars = ex_tvs })
= binderVars (univ_tvs ++ ex_tvs)
diff --git a/compiler/basicTypes/Id.hs b/compiler/basicTypes/Id.hs
index 290e26291d..05290776d0 100644
--- a/compiler/basicTypes/Id.hs
+++ b/compiler/basicTypes/Id.hs
@@ -5,7 +5,7 @@
\section[Id]{@Ids@: Value and constructor identifiers}
-}
-{-# LANGUAGE ImplicitParams, CPP #-}
+{-# LANGUAGE CPP #-}
-- |
-- #name_types#
@@ -715,7 +715,7 @@ setIdCafInfo :: Id -> CafInfo -> Id
setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
---------------------------------
- -- Occcurrence INFO
+ -- Occurrence INFO
idOccInfo :: Id -> OccInfo
idOccInfo id = occInfo (idInfo id)
diff --git a/compiler/basicTypes/PatSyn.hs b/compiler/basicTypes/PatSyn.hs
index 0e218a39c1..d59810b5e1 100644
--- a/compiler/basicTypes/PatSyn.hs
+++ b/compiler/basicTypes/PatSyn.hs
@@ -63,7 +63,7 @@ data PatSyn
-- record pat syn or same length as
-- psArgs
- -- Universially-quantified type variables
+ -- Universally-quantified type variables
psUnivTyVars :: [TyVarBinder],
-- Required dictionaries (may mention psUnivTyVars)
@@ -76,7 +76,8 @@ data PatSyn
psProvTheta :: ThetaType,
-- Result type
- psOrigResTy :: Type, -- Mentions only psUnivTyVars
+ psResultTy :: Type, -- Mentions only psUnivTyVars
+ -- See Note [Pattern synonym result type]
-- See Note [Matchers and builders for pattern synonyms]
psMatcher :: (Id, Bool),
@@ -145,6 +146,43 @@ Example 3:
You can see it's existential because it doesn't appear in the
result type (T3 b).
+Note [Pattern synonym result type]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+ data T a b = MkT b a
+
+ pattern P :: a -> T [a] Bool
+ pattern P x = MkT True [x]
+
+P's psResultTy is (T a Bool), and it really only matches values of
+type (T [a] Bool). For example, this is ill-typed
+
+ f :: T p q -> String
+ f (P x) = "urk"
+
+This is differnet to the situation with GADTs:
+
+ data S a where
+ MkS :: Int -> S Bool
+
+Now MkS (and pattern synonyms coming from MkS) can match a
+value of type (S a), not just (S Bool); we get type refinement.
+
+That in turn means that if you have a pattern
+
+ P x :: T [ty] Bool
+
+it's not entirely straightforward to work out the instantiation of
+P's universal tyvars. You have to /match/
+ the type of the pattern, (T [ty] Bool)
+against
+ the psResultTy for the pattern synonym, T [a] Bool
+to get the instantiation a := ty.
+
+This is very unlike DataCons, where univ tyvars match 1-1 the
+arguments of the TyCon.
+
+
Note [Pattern synonym representation]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider the following pattern synonym declaration
@@ -174,7 +212,7 @@ In this case, the fields of MkPatSyn will be set as follows:
psExTyVars = [b]
psProvTheta = (Show (Maybe t), Ord b)
psReqTheta = (Eq t, Num t)
- psOrigResTy = T (Maybe t)
+ psResultTy = T (Maybe t)
Note [Matchers and builders for pattern synonyms]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -325,7 +363,7 @@ mkPatSyn name declared_infix
psInfix = declared_infix,
psArgs = orig_args,
psArity = length orig_args,
- psOrigResTy = orig_res_ty,
+ psResultTy = orig_res_ty,
psMatcher = matcher,
psBuilder = builder,
psFieldLabels = field_labels
@@ -368,7 +406,7 @@ patSynExTyVarBinders = psExTyVars
patSynSig :: PatSyn -> ([TyVar], ThetaType, [TyVar], ThetaType, [Type], Type)
patSynSig (MkPatSyn { psUnivTyVars = univ_tvs, psExTyVars = ex_tvs
, psProvTheta = prov, psReqTheta = req
- , psArgs = arg_tys, psOrigResTy = res_ty })
+ , psArgs = arg_tys, psResultTy = res_ty })
= (binderVars univ_tvs, req, binderVars ex_tvs, prov, arg_tys, res_ty)
patSynMatcher :: PatSyn -> (Id,Bool)
@@ -405,9 +443,9 @@ patSynInstResTy :: PatSyn -> [Type] -> Type
-- E.g. pattern P x y = Just (x,x,y)
-- P :: a -> b -> Just (a,a,b)
-- (patSynInstResTy P [Int,Bool] = Maybe (Int,Int,Bool)
--- NB: unlikepatSynInstArgTys, the inst_tys should be just the *universal* tyvars
+-- NB: unlike patSynInstArgTys, the inst_tys should be just the *universal* tyvars
patSynInstResTy (MkPatSyn { psName = name, psUnivTyVars = univ_tvs
- , psOrigResTy = res_ty })
+ , psResultTy = res_ty })
inst_tys
= ASSERT2( univ_tvs `equalLength` inst_tys
, text "patSynInstResTy" <+> ppr name $$ ppr univ_tvs $$ ppr inst_tys )
@@ -417,7 +455,7 @@ patSynInstResTy (MkPatSyn { psName = name, psUnivTyVars = univ_tvs
pprPatSynType :: PatSyn -> SDoc
pprPatSynType (MkPatSyn { psUnivTyVars = univ_tvs, psReqTheta = req_theta
, psExTyVars = ex_tvs, psProvTheta = prov_theta
- , psArgs = orig_args, psOrigResTy = orig_res_ty })
+ , psArgs = orig_args, psResultTy = orig_res_ty })
= sep [ pprForAll univ_tvs
, pprThetaArrowTy req_theta
, ppWhen insert_empty_ctxt $ parens empty <+> darrow
diff --git a/compiler/basicTypes/SrcLoc.hs b/compiler/basicTypes/SrcLoc.hs
index f71dac6273..1e6e7d2535 100644
--- a/compiler/basicTypes/SrcLoc.hs
+++ b/compiler/basicTypes/SrcLoc.hs
@@ -7,10 +7,6 @@
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RecordWildCards #-}
-{-# OPTIONS_GHC -fno-omit-interface-pragmas #-}
- -- Workaround for Trac #5252 crashes the bootstrap compiler without -O
- -- When the earliest compiler we want to boostrap with is
- -- GHC 7.2, we can make RealSrcLoc properly abstract
-- | This module contains types that relate to the positions of things
-- in source files, and allow tagging of those things with locations
diff --git a/compiler/basicTypes/Var.hs b/compiler/basicTypes/Var.hs
index 87c4fe2240..9a39e2939b 100644
--- a/compiler/basicTypes/Var.hs
+++ b/compiler/basicTypes/Var.hs
@@ -64,6 +64,7 @@ module Var (
TyVarBndr(..), ArgFlag(..), TyVarBinder,
binderVar, binderVars, binderArgFlag, binderKind,
isVisibleArgFlag, isInvisibleArgFlag, sameVis,
+ mkTyVarBinder, mkTyVarBinders,
-- ** Constructing TyVar's
mkTyVar, mkTcTyVar,
@@ -158,7 +159,7 @@ type TyCoVar = Id -- Type, *or* coercion variable
{- Many passes apply a substitution, and it's very handy to have type
- synonyms to remind us whether or not the subsitution has been applied -}
+ synonyms to remind us whether or not the substitution has been applied -}
type InVar = Var
type InTyVar = TyVar
@@ -374,7 +375,7 @@ updateVarTypeM f id = do { ty' <- f (varType id)
-- Is something required to appear in source Haskell ('Required'),
-- permitted by request ('Specified') (visible type application), or
-- prohibited entirely from appearing in source Haskell ('Inferred')?
--- See Note [TyBinders and ArgFlags] in TyCoRep
+-- See Note [TyVarBndrs, TyVarBinders, TyConBinders, and visibility] in TyCoRep
data ArgFlag = Required | Specified | Inferred
deriving (Eq, Data)
@@ -429,6 +430,14 @@ binderArgFlag (TvBndr _ argf) = argf
binderKind :: TyVarBndr TyVar argf -> Kind
binderKind (TvBndr tv _) = tyVarKind tv
+-- | Make a named binder
+mkTyVarBinder :: ArgFlag -> Var -> TyVarBinder
+mkTyVarBinder vis var = TvBndr var vis
+
+-- | Make many named binders
+mkTyVarBinders :: ArgFlag -> [TyVar] -> [TyVarBinder]
+mkTyVarBinders vis = map (mkTyVarBinder vis)
+
{-
************************************************************************
* *
diff --git a/compiler/cmm/CmmMonad.hs b/compiler/cmm/CmmMonad.hs
index fc66bf5928..c035577473 100644
--- a/compiler/cmm/CmmMonad.hs
+++ b/compiler/cmm/CmmMonad.hs
@@ -7,16 +7,13 @@
-- The parser for C-- requires access to a lot more of the 'DynFlags',
-- so 'PD' provides access to 'DynFlags' via a 'HasDynFlags' instance.
-----------------------------------------------------------------------------
-{-# LANGUAGE CPP #-}
module CmmMonad (
PD(..)
, liftP
) where
import Control.Monad
-#if __GLASGOW_HASKELL__ > 710
import qualified Control.Monad.Fail as MonadFail
-#endif
import DynFlags
import Lexer
@@ -34,10 +31,8 @@ instance Monad PD where
(>>=) = thenPD
fail = failPD
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail.MonadFail PD where
fail = failPD
-#endif
liftP :: P a -> PD a
liftP (P f) = PD $ \_ s -> f s
diff --git a/compiler/cmm/CmmOpt.hs b/compiler/cmm/CmmOpt.hs
index 3cb28217f2..78a186721b 100644
--- a/compiler/cmm/CmmOpt.hs
+++ b/compiler/cmm/CmmOpt.hs
@@ -2,9 +2,7 @@
-- The default iteration limit is a bit too low for the definitions
-- in this module.
-#if __GLASGOW_HASKELL__ >= 800
{-# OPTIONS_GHC -fmax-pmcheck-iterations=10000000 #-}
-#endif
-----------------------------------------------------------------------------
--
diff --git a/compiler/coreSyn/CoreLint.hs b/compiler/coreSyn/CoreLint.hs
index 2be1020674..390a3173d7 100644
--- a/compiler/coreSyn/CoreLint.hs
+++ b/compiler/coreSyn/CoreLint.hs
@@ -64,10 +64,10 @@ import Demand ( splitStrictSig, isBotRes )
import HscTypes
import DynFlags
import Control.Monad
-#if __GLASGOW_HASKELL__ > 710
import qualified Control.Monad.Fail as MonadFail
-#endif
import MonadUtils
+import Data.Foldable ( toList )
+import Data.List.NonEmpty ( NonEmpty )
import Data.Maybe
import Pair
import qualified GHC.LanguageExtensions as LangExt
@@ -1949,10 +1949,8 @@ instance Monad LintM where
Just r -> unLintM (k r) env errs'
Nothing -> (Nothing, errs'))
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail.MonadFail LintM where
fail err = failWithL (text err)
-#endif
instance HasDynFlags LintM where
getDynFlags = LintM (\ e errs -> (Just (le_dynflags e), errs))
@@ -2431,15 +2429,15 @@ pprLeftOrRight :: LeftOrRight -> MsgDoc
pprLeftOrRight CLeft = text "left"
pprLeftOrRight CRight = text "right"
-dupVars :: [[Var]] -> MsgDoc
+dupVars :: [NonEmpty Var] -> MsgDoc
dupVars vars
= hang (text "Duplicate variables brought into scope")
- 2 (ppr vars)
+ 2 (ppr (map toList vars))
-dupExtVars :: [[Name]] -> MsgDoc
+dupExtVars :: [NonEmpty Name] -> MsgDoc
dupExtVars vars
= hang (text "Duplicate top-level variables with the same qualified name")
- 2 (ppr vars)
+ 2 (ppr (map toList vars))
{-
************************************************************************
diff --git a/compiler/coreSyn/PprCore.hs b/compiler/coreSyn/PprCore.hs
index 28d35528fe..1ac3084e39 100644
--- a/compiler/coreSyn/PprCore.hs
+++ b/compiler/coreSyn/PprCore.hs
@@ -374,7 +374,7 @@ pprTypedLamBinder bind_site debug_on var
= sdocWithDynFlags $ \dflags ->
case () of
_
- | not debug_on -- Show case-bound wild bilders only if debug is on
+ | not debug_on -- Show case-bound wild binders only if debug is on
, CaseBind <- bind_site
, isDeadBinder var -> empty
diff --git a/compiler/coreSyn/TrieMap.hs b/compiler/coreSyn/TrieMap.hs
index a6b9db46cb..fcff256123 100644
--- a/compiler/coreSyn/TrieMap.hs
+++ b/compiler/coreSyn/TrieMap.hs
@@ -278,6 +278,9 @@ instance TrieMap m => TrieMap (ListMap m) where
foldTM = fdList
mapTM = mapList
+instance (TrieMap m, Outputable a) => Outputable (ListMap m a) where
+ ppr m = text "List elts" <+> ppr (foldTM (:) m [])
+
mapList :: TrieMap m => (a->b) -> ListMap m a -> ListMap m b
mapList f (LM { lm_nil = mnil, lm_cons = mcons })
= LM { lm_nil = fmap f mnil, lm_cons = mapTM (mapTM f) mcons }
diff --git a/compiler/deSugar/Check.hs b/compiler/deSugar/Check.hs
index cb9837ed0c..ab2047fcf3 100644
--- a/compiler/deSugar/Check.hs
+++ b/compiler/deSugar/Check.hs
@@ -12,13 +12,16 @@ module Check (
checkSingle, checkMatches, isAnyPmCheckEnabled,
-- See Note [Type and Term Equality Propagation]
- genCaseTmCs1, genCaseTmCs2
+ genCaseTmCs1, genCaseTmCs2,
+
+ -- Pattern-match-specific type operations
+ pmIsClosedType, pmTopNormaliseType_maybe
) where
#include "HsVersions.h"
import TmOracle
-
+import Unify( tcMatchTy )
import BasicTypes
import DynFlags
import HsSyn
@@ -27,6 +30,7 @@ import Id
import ConLike
import Name
import FamInstEnv
+import TysPrim (tYPETyCon)
import TysWiredIn
import TyCon
import SrcLoc
@@ -42,9 +46,11 @@ import TcType (toTcType, isStringTy, isIntTy, isWordTy)
import Bag
import ErrUtils
import Var (EvVar)
+import TyCoRep
import Type
import UniqSupply
import DsGRHSs (isTrueLHsExpr)
+import Maybes ( expectJust )
import Data.List (find)
import Data.Maybe (isJust, fromMaybe)
@@ -372,7 +378,7 @@ checkMatches' vars matches
(NotCovered, Diverged ) -> (final_prov, rs, final_u, m:is)
hsLMatchToLPats :: LMatch id body -> Located [LPat id]
- hsLMatchToLPats (L l (Match _ pats _ _)) = L l pats
+ hsLMatchToLPats (L l (Match { m_pats = pats })) = L l pats
-- | Check an empty case expression. Since there are no clauses to process, we
-- only compute the uncovered set. See Note [Checking EmptyCase Expressions]
@@ -406,6 +412,147 @@ checkEmptyCase' var = do
else PmResult FromBuiltin [] uncovered []
Nothing -> return emptyPmResult
+-- | Returns 'True' if the argument 'Type' is a fully saturated application of
+-- a closed type constructor.
+--
+-- Closed type constructors are those with a fixed right hand side, as
+-- opposed to e.g. associated types. These are of particular interest for
+-- pattern-match coverage checking, because GHC can exhaustively consider all
+-- possible forms that values of a closed type can take on.
+--
+-- Note that this function is intended to be used to check types of value-level
+-- patterns, so as a consequence, the 'Type' supplied as an argument to this
+-- function should be of kind @Type@.
+pmIsClosedType :: Type -> Bool
+pmIsClosedType ty
+ = case splitTyConApp_maybe ty of
+ Just (tc, ty_args)
+ | is_algebraic_like tc && not (isFamilyTyCon tc)
+ -> ASSERT2( ty_args `lengthIs` tyConArity tc, ppr ty ) True
+ _other -> False
+ where
+ -- This returns True for TyCons which /act like/ algebraic types.
+ -- (See "Type#type_classification" for what an algebraic type is.)
+ --
+ -- This is qualified with \"like\" because of a particular special
+ -- case: TYPE (the underlyind kind behind Type, among others). TYPE
+ -- is conceptually a datatype (and thus algebraic), but in practice it is
+ -- a primitive builtin type, so we must check for it specially.
+ --
+ -- NB: it makes sense to think of TYPE as a closed type in a value-level,
+ -- pattern-matching context. However, at the kind level, TYPE is certainly
+ -- not closed! Since this function is specifically tailored towards pattern
+ -- matching, however, it's OK to label TYPE as closed.
+ is_algebraic_like :: TyCon -> Bool
+ is_algebraic_like tc = isAlgTyCon tc || tc == tYPETyCon
+
+pmTopNormaliseType_maybe :: FamInstEnvs -> Type -> Maybe (Type, [DataCon], Type)
+-- ^ Get rid of *outermost* (or toplevel)
+-- * type function redex
+-- * data family redex
+-- * newtypes
+--
+-- Behaves exactly like `topNormaliseType_maybe`, but instead of returning a
+-- coercion, it returns useful information for issuing pattern matching
+-- warnings. See Note [Type normalisation for EmptyCase] for details.
+pmTopNormaliseType_maybe env typ
+ = do ((ty_f,tm_f), ty) <- topNormaliseTypeX stepper comb typ
+ return (eq_src_ty ty (typ : ty_f [ty]), tm_f [], ty)
+ where
+ -- Find the first type in the sequence of rewrites that is a data type,
+ -- newtype, or a data family application (not the representation tycon!).
+ -- This is the one that is equal (in source Haskell) to the initial type.
+ -- If none is found in the list, then all of them are type family
+ -- applications, so we simply return the last one, which is the *simplest*.
+ eq_src_ty :: Type -> [Type] -> Type
+ eq_src_ty ty tys = maybe ty id (find is_closed_or_data_family tys)
+
+ is_closed_or_data_family :: Type -> Bool
+ is_closed_or_data_family ty = pmIsClosedType ty || isDataFamilyAppType ty
+
+ -- For efficiency, represent both lists as difference lists.
+ -- comb performs the concatenation, for both lists.
+ comb (tyf1, tmf1) (tyf2, tmf2) = (tyf1 . tyf2, tmf1 . tmf2)
+
+ stepper = newTypeStepper `composeSteppers` tyFamStepper
+
+ -- A 'NormaliseStepper' that unwraps newtypes, careful not to fall into
+ -- a loop. If it would fall into a loop, it produces 'NS_Abort'.
+ newTypeStepper :: NormaliseStepper ([Type] -> [Type],[DataCon] -> [DataCon])
+ newTypeStepper rec_nts tc tys
+ | Just (ty', _co) <- instNewTyCon_maybe tc tys
+ = case checkRecTc rec_nts tc of
+ Just rec_nts' -> let tyf = ((TyConApp tc tys):)
+ tmf = ((tyConSingleDataCon tc):)
+ in NS_Step rec_nts' ty' (tyf, tmf)
+ Nothing -> NS_Abort
+ | otherwise
+ = NS_Done
+
+ tyFamStepper :: NormaliseStepper ([Type] -> [Type], [DataCon] -> [DataCon])
+ tyFamStepper rec_nts tc tys -- Try to step a type/data family
+ = let (_args_co, ntys) = normaliseTcArgs env Representational tc tys in
+ -- NB: It's OK to use normaliseTcArgs here instead of
+ -- normalise_tc_args (which takes the LiftingContext described
+ -- in Note [Normalising types]) because the reduceTyFamApp below
+ -- works only at top level. We'll never recur in this function
+ -- after reducing the kind of a bound tyvar.
+
+ case reduceTyFamApp_maybe env Representational tc ntys of
+ Just (_co, rhs) -> NS_Step rec_nts rhs ((rhs:), id)
+ _ -> NS_Done
+
+{- Note [Type normalisation for EmptyCase]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+EmptyCase is an exception for pattern matching, since it is strict. This means
+that it boils down to checking whether the type of the scrutinee is inhabited.
+Function pmTopNormaliseType_maybe gets rid of the outermost type function/data
+family redex and newtypes, in search of an algebraic type constructor, which is
+easier to check for inhabitation.
+
+It returns 3 results instead of one, because there are 2 subtle points:
+1. Newtypes are isomorphic to the underlying type in core but not in the source
+ language,
+2. The representational data family tycon is used internally but should not be
+ shown to the user
+
+Hence, if pmTopNormaliseType_maybe env ty = Just (src_ty, dcs, core_ty), then
+ (a) src_ty is the rewritten type which we can show to the user. That is, the
+ type we get if we rewrite type families but not data families or
+ newtypes.
+ (b) dcs is the list of data constructors "skipped", every time we normalise a
+ newtype to it's core representation, we keep track of the source data
+ constructor.
+ (c) core_ty is the rewritten type. That is,
+ pmTopNormaliseType_maybe env ty = Just (src_ty, dcs, core_ty)
+ implies
+ topNormaliseType_maybe env ty = Just (co, core_ty)
+ for some coercion co.
+
+To see how all cases come into play, consider the following example:
+
+ data family T a :: *
+ data instance T Int = T1 | T2 Bool
+ -- Which gives rise to FC:
+ -- data T a
+ -- data R:TInt = T1 | T2 Bool
+ -- axiom ax_ti : T Int ~R R:TInt
+
+ newtype G1 = MkG1 (T Int)
+ newtype G2 = MkG2 G1
+
+ type instance F Int = F Char
+ type instance F Char = G2
+
+In this case pmTopNormaliseType_maybe env (F Int) results in
+
+ Just (G2, [MkG2,MkG1], R:TInt)
+
+Which means that in source Haskell:
+ - G2 is equivalent to F Int (in contrast, G1 isn't).
+ - if (x : R:TInt) then (MkG2 (MkG1 x) : F Int).
+-}
+
-- | Generate all inhabitation candidates for a given type. The result is
-- either (Left ty), if the type cannot be reduced to a closed algebraic type
-- (or if it's one trivially inhabited, like Int), or (Right candidates), if it
@@ -439,7 +586,8 @@ inhabitationCandidates fam_insts ty
(_:_) -> do var <- liftD $ mkPmId (toTcType core_ty)
let va = build_tm (PmVar var) dcs
return $ Right [(va, mkIdEq var, emptyBag)]
- | isClosedAlgType core_ty -> liftD $ do
+
+ | pmIsClosedType core_ty -> liftD $ do
var <- mkPmId (toTcType core_ty) -- it would be wrong to unify x
alts <- mapM (mkOneConFull var . RealDataCon) (tyConDataCons tc)
return $ Right [(build_tm va dcs, eq, cs) | (va, eq, cs) <- alts]
@@ -747,7 +895,7 @@ translateConPatVec fam_insts univ_tys ex_tvs c (RecCon (HsRecFields fs _))
-- Translate a single match
translateMatch :: FamInstEnvs -> LMatch GhcTc (LHsExpr GhcTc)
-> DsM (PatVec,[PatVec])
-translateMatch fam_insts (L _ (Match _ lpats _ grhss)) = do
+translateMatch fam_insts (L _ (Match { m_pats = lpats, m_grhss = grhss })) = do
pats' <- concat <$> translatePatVec fam_insts pats
guards' <- mapM (translateGuards fam_insts) guards
return (pats', guards')
@@ -971,14 +1119,14 @@ mkOneConFull :: Id -> ConLike -> DsM (ValAbs, ComplexEq, Bag EvVar)
-- ComplexEq: x ~ K y1..yn
-- [EvVar]: Q
mkOneConFull x con = do
- let -- res_ty == TyConApp (ConLikeTyCon cabs_con) cabs_arg_tys
- res_ty = idType x
- (univ_tvs, ex_tvs, eq_spec, thetas, _req_theta , arg_tys, _)
+ let res_ty = idType x
+ (univ_tvs, ex_tvs, eq_spec, thetas, _req_theta , arg_tys, con_res_ty)
= conLikeFullSig con
- tc_args = case splitTyConApp_maybe res_ty of
- Just (_, tys) -> tys
- Nothing -> pprPanic "mkOneConFull: Not TyConApp:" (ppr res_ty)
- subst1 = zipTvSubst univ_tvs tc_args
+ tc_args = tyConAppArgs res_ty
+ subst1 = case con of
+ RealDataCon {} -> zipTvSubst univ_tvs tc_args
+ PatSynCon {} -> expectJust "mkOneConFull" (tcMatchTy con_res_ty res_ty)
+ -- See Note [Pattern synonym result type] in PatSyn
(subst, ex_tvs') <- cloneTyVarBndrs subst1 ex_tvs <$> getUniqueSupplyM
@@ -1740,9 +1888,9 @@ pp_context singular (DsMatchContext kind _loc) msg rest_of_msg_fun
(ppr_match, pref)
= case kind of
- FunRhs (L _ fun) _ _ -> (pprMatchContext kind,
- \ pp -> ppr fun <+> pp)
- _ -> (pprMatchContext kind, \ pp -> pp)
+ FunRhs { mc_fun = L _ fun }
+ -> (pprMatchContext kind, \ pp -> ppr fun <+> pp)
+ _ -> (pprMatchContext kind, \ pp -> pp)
ppr_pats :: HsMatchContext Name -> [Pat GhcTc] -> SDoc
ppr_pats kind pats
diff --git a/compiler/deSugar/Coverage.hs b/compiler/deSugar/Coverage.hs
index 16537bd7a5..a9d953dc0e 100644
--- a/compiler/deSugar/Coverage.hs
+++ b/compiler/deSugar/Coverage.hs
@@ -3,7 +3,7 @@
(c) University of Glasgow, 2007
-}
-{-# LANGUAGE CPP, NondecreasingIndentation, RecordWildCards #-}
+{-# LANGUAGE NondecreasingIndentation, RecordWildCards #-}
module Coverage (addTicksToBinds, hpcInitCode) where
@@ -11,11 +11,7 @@ import qualified GHCi
import GHCi.RemoteTypes
import Data.Array
import ByteCodeTypes
-#if MIN_VERSION_base(4,9,0)
import GHC.Stack.CCS
-#else
-import GHC.Stack as GHC.Stack.CCS
-#endif
import Type
import HsSyn
import Module
@@ -281,31 +277,6 @@ addTickLHsBind (L pos bind@(AbsBinds { abs_binds = binds,
| ABE{ abe_poly = pid, abe_mono = mid } <- abs_exports
, isInlinePragma (idInlinePragma pid) ] }
-addTickLHsBind (L pos bind@(AbsBindsSig { abs_sig_bind = val_bind
- , abs_sig_export = poly_id }))
- | L _ FunBind { fun_id = L _ mono_id } <- val_bind
- = do withEnv (add_export mono_id) $ do
- withEnv (add_inlines mono_id) $ do
- val_bind' <- addTickLHsBind val_bind
- return $ L pos $ bind { abs_sig_bind = val_bind' }
-
- | otherwise
- = pprPanic "addTickLHsBind" (ppr bind)
- where
- -- see AbsBinds comments
- add_export mono_id env
- | idName poly_id `elemNameSet` exports env
- = env { exports = exports env `extendNameSet` idName mono_id }
- | otherwise
- = env
-
- -- See Note [inline sccs]
- add_inlines mono_id env
- | isInlinePragma (idInlinePragma poly_id)
- = env { inlines = inlines env `extendVarSet` mono_id }
- | otherwise
- = env
-
addTickLHsBind (L pos (funBind@(FunBind { fun_id = (L _ id) }))) = do
let name = getOccString id
decl_path <- getPathEntry
@@ -682,10 +653,10 @@ addTickMatchGroup is_lam mg@(MG { mg_alts = L l matches }) = do
addTickMatch :: Bool -> Bool -> Match GhcTc (LHsExpr GhcTc)
-> TM (Match GhcTc (LHsExpr GhcTc))
-addTickMatch isOneOfMany isLambda (Match mf pats opSig gRHSs) =
+addTickMatch isOneOfMany isLambda match@(Match { m_pats = pats, m_grhss = gRHSs }) =
bindLocals (collectPatsBinders pats) $ do
gRHSs' <- addTickGRHSs isOneOfMany isLambda gRHSs
- return $ Match mf pats opSig gRHSs'
+ return $ match { m_grhss = gRHSs' }
addTickGRHSs :: Bool -> Bool -> GRHSs GhcTc (LHsExpr GhcTc)
-> TM (GRHSs GhcTc (LHsExpr GhcTc))
@@ -923,10 +894,10 @@ addTickCmdMatchGroup mg@(MG { mg_alts = L l matches }) = do
return $ mg { mg_alts = L l matches' }
addTickCmdMatch :: Match GhcTc (LHsCmd GhcTc) -> TM (Match GhcTc (LHsCmd GhcTc))
-addTickCmdMatch (Match mf pats opSig gRHSs) =
+addTickCmdMatch match@(Match { m_pats = pats, m_grhss = gRHSs }) =
bindLocals (collectPatsBinders pats) $ do
gRHSs' <- addTickCmdGRHSs gRHSs
- return $ Match mf pats opSig gRHSs'
+ return $ match { m_grhss = gRHSs' }
addTickCmdGRHSs :: GRHSs GhcTc (LHsCmd GhcTc) -> TM (GRHSs GhcTc (LHsCmd GhcTc))
addTickCmdGRHSs (GRHSs guarded (L l local_binds)) = do
@@ -1304,7 +1275,7 @@ hpcSrcSpan = mkGeneralSrcSpan (fsLit "Haskell Program Coverage internals")
matchesOneOfMany :: [LMatch GhcTc body] -> Bool
matchesOneOfMany lmatches = sum (map matchCount lmatches) > 1
where
- matchCount (L _ (Match _ _pats _ty (GRHSs grhss _binds))) = length grhss
+ matchCount (L _ (Match { m_grhss = GRHSs grhss _binds })) = length grhss
type MixEntry_ = (SrcSpan, [String], [OccName], BoxLabel)
diff --git a/compiler/deSugar/DsArrows.hs b/compiler/deSugar/DsArrows.hs
index 97ec32de5c..c1633ee582 100644
--- a/compiler/deSugar/DsArrows.hs
+++ b/compiler/deSugar/DsArrows.hs
@@ -447,8 +447,8 @@ dsCmd ids local_vars stack_ty res_ty (HsCmdApp cmd arg) env_ids = do
-- ---> premap (\ ((xs), (p1, ... (pk,stk)...)) -> ((ys),stk)) cmd
dsCmd ids local_vars stack_ty res_ty
- (HsCmdLam (MG { mg_alts = L _ [L _ (Match _ pats _
- (GRHSs [L _ (GRHS [] body)] _ ))] }))
+ (HsCmdLam (MG { mg_alts = L _ [L _ (Match { m_pats = pats
+ , m_grhss = GRHSs [L _ (GRHS [] body)] _ })] }))
env_ids = do
let pat_vars = mkVarSet (collectPatsBinders pats)
let
@@ -1106,7 +1106,7 @@ matchSimplys _ _ _ _ _ = panic "matchSimplys"
leavesMatch :: LMatch GhcTc (Located (body (GHC GhcTc)))
-> [(Located (body (GHC GhcTc)), IdSet)]
-leavesMatch (L _ (Match _ pats _ (GRHSs grhss (L _ binds))))
+leavesMatch (L _ (Match { m_pats = pats, m_grhss = GRHSs grhss (L _ binds) }))
= let
defined_vars = mkVarSet (collectPatsBinders pats)
`unionVarSet`
@@ -1125,11 +1125,11 @@ replaceLeavesMatch
-> LMatch GhcTc (Located (body (GHC GhcTc))) -- the matches of a case command
-> ([Located (body' (GHC GhcTc))], -- remaining leaf expressions
LMatch GhcTc (Located (body' (GHC GhcTc)))) -- updated match
-replaceLeavesMatch _res_ty leaves (L loc (Match mf pat mt (GRHSs grhss binds)))
+replaceLeavesMatch _res_ty leaves (L loc match@(Match { m_grhss = GRHSs grhss binds }))
= let
(leaves', grhss') = mapAccumL replaceLeavesGRHS leaves grhss
in
- (leaves', L loc (Match mf pat mt (GRHSs grhss' binds)))
+ (leaves', L loc (match { m_grhss = GRHSs grhss' binds }))
replaceLeavesGRHS
:: [Located (body' (GHC GhcTc))] -- replacement leaf expressions of that type
diff --git a/compiler/deSugar/DsBinds.hs b/compiler/deSugar/DsBinds.hs
index 56ec6ec6be..c6d8bed746 100644
--- a/compiler/deSugar/DsBinds.hs
+++ b/compiler/deSugar/DsBinds.hs
@@ -52,6 +52,7 @@ import Name
import VarSet
import Rules
import VarEnv
+import Var( EvVar )
import Outputable
import Module
import SrcLoc
@@ -79,7 +80,7 @@ dsTopLHsBinds binds
-- see Note [Strict binds checks]
| not (isEmptyBag unlifted_binds) || not (isEmptyBag bang_binds)
= do { mapBagM_ (top_level_err "bindings for unlifted types") unlifted_binds
- ; mapBagM_ (top_level_err "strict pattern bindings") bang_binds
+ ; mapBagM_ (top_level_err "strict bindings") bang_binds
; return nilOL }
| otherwise
@@ -93,7 +94,7 @@ dsTopLHsBinds binds
where
unlifted_binds = filterBag (isUnliftedHsBind . unLoc) binds
- bang_binds = filterBag (isBangedPatBind . unLoc) binds
+ bang_binds = filterBag (isBangedHsBind . unLoc) binds
top_level_err desc (L loc bind)
= putSrcSpanDs loc $
@@ -105,8 +106,7 @@ dsTopLHsBinds binds
-- later be forced in the binding group body, see Note [Desugar Strict binds]
dsLHsBinds :: LHsBinds GhcTc -> DsM ([Id], [(Id,CoreExpr)])
dsLHsBinds binds
- = do { MASSERT( allBag (not . isUnliftedHsBind . unLoc) binds )
- ; ds_bs <- mapBagM dsLHsBind binds
+ = do { ds_bs <- mapBagM dsLHsBind binds
; return (foldBag (\(a, a') (b, b') -> (a ++ b, a' ++ b'))
id ([], []) ds_bs) }
@@ -124,10 +124,9 @@ dsHsBind :: DynFlags
-- binding group see Note [Desugar Strict binds] and all
-- bindings and their desugared right hand sides.
-dsHsBind dflags
- (VarBind { var_id = var
- , var_rhs = expr
- , var_inline = inline_regardless })
+dsHsBind dflags (VarBind { var_id = var
+ , var_rhs = expr
+ , var_inline = inline_regardless })
= do { core_expr <- dsLExpr expr
-- Dictionary bindings are always VarBinds,
-- so we only need do this here
@@ -139,9 +138,8 @@ dsHsBind dflags
else []
; return (force_var, [core_bind]) }
-dsHsBind dflags
- b@(FunBind { fun_id = L _ fun, fun_matches = matches
- , fun_co_fn = co_fn, fun_tick = tick })
+dsHsBind dflags b@(FunBind { fun_id = L _ fun, fun_matches = matches
+ , fun_co_fn = co_fn, fun_tick = tick })
= do { (args, body) <- matchWrapper
(mkPrefixFunRhs (noLoc $ idName fun))
Nothing matches
@@ -154,16 +152,18 @@ dsHsBind dflags
| xopt LangExt.Strict dflags
, matchGroupArity matches == 0 -- no need to force lambdas
= [id]
- | isBangedBind b
+ | isBangedHsBind b
= [id]
| otherwise
= []
- ; --pprTrace "dsHsBind" (ppr fun <+> ppr (idInlinePragma fun) $$ ppr (mg_alts matches) $$ ppr args $$ ppr core_binds) $
- return (force_var, [core_binds]) }
-
-dsHsBind dflags
- (PatBind { pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty
- , pat_ticks = (rhs_tick, var_ticks) })
+ ; --pprTrace "dsHsBind" (vcat [ ppr fun <+> ppr (idInlinePragma fun)
+ -- , ppr (mg_alts matches)
+ -- , ppr args, ppr core_binds]) $
+ return (force_var, [core_binds]) }
+
+dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss
+ , pat_rhs_ty = ty
+ , pat_ticks = (rhs_tick, var_ticks) })
= do { body_expr <- dsGuarded grhss ty
; let body' = mkOptTickBox rhs_tick body_expr
pat' = decideBangHood dflags pat
@@ -175,47 +175,73 @@ dsHsBind dflags
else []
; return (force_var', sel_binds) }
- -- A common case: one exported variable, only non-strict binds
- -- Non-recursive bindings come through this way
- -- So do self-recursive bindings
- -- Bindings with complete signatures are AbsBindsSigs, below
-dsHsBind dflags
- (AbsBinds { abs_tvsa = tyvars, abs_ev_varsa = dicts
- , abs_exports = [export]
- , abs_ev_binds = ev_binds, abs_binds = binds })
- | ABE { abe_wrap = wrap, abe_poly = global
- , abe_mono = local, abe_prags = prags } <- export
- , not (xopt LangExt.Strict dflags) -- Handle strict binds
- , not (anyBag (isBangedBind . unLoc) binds) -- in the next case
- = -- See Note [AbsBinds wrappers] in HsBinds
- addDictsDs (toTcTypeBag (listToBag dicts)) $
- -- addDictsDs: push type constraints deeper for pattern match check
- do { (force_vars, bind_prs) <- dsLHsBinds binds
- ; ds_binds <- dsTcEvBinds_s ev_binds
- ; core_wrap <- dsHsWrapper wrap -- Usually the identity
+dsHsBind dflags (AbsBinds { abs_tvsa = tyvars, abs_ev_varsa = dicts
+ , abs_exports = exports
+ , abs_ev_binds = ev_binds
+ , abs_binds = binds, abs_sig = has_sig })
+ = do { ds_binds <- addDictsDs (toTcTypeBag (listToBag dicts)) $
+ dsLHsBinds binds
+ -- addDictsDs: push type constraints deeper
+ -- for inner pattern match check
+
+ ; ds_ev_binds <- dsTcEvBinds_s ev_binds
+
+ -- dsAbsBinds does the hard work
+ ; dsAbsBinds dflags tyvars dicts exports ds_ev_binds ds_binds has_sig }
+
+dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind"
+
+
+-----------------------
+dsAbsBinds :: DynFlags
+ -> [TyVar] -> [EvVar] -> [ABExport GhcTc]
+ -> [CoreBind] -- Desugared evidence bindings
+ -> ([Id], [(Id,CoreExpr)]) -- Desugared value bindings
+ -> Bool -- Single binding with signature
+ -> DsM ([Id], [(Id,CoreExpr)])
+
+dsAbsBinds dflags tyvars dicts exports
+ ds_ev_binds (force_vars, bind_prs) has_sig
+
+ -- A very important common case: one exported variable
+ -- Non-recursive bindings come through this way
+ -- So do self-recursive bindings
+ | [export] <- exports
+ , ABE { abe_poly = global_id, abe_mono = local_id
+ , abe_wrap = wrap, abe_prags = prags } <- export
+ , Just force_vars' <- case force_vars of
+ [] -> Just []
+ [v] | v == local_id -> Just [global_id]
+ _ -> Nothing
+ -- If there is a variable to force, it's just the
+ -- single variable we are binding here
+ = do { core_wrap <- dsHsWrapper wrap -- Usually the identity
; let rhs = core_wrap $
mkLams tyvars $ mkLams dicts $
- mkCoreLets ds_binds $
- mkLetRec bind_prs $
- Var local
+ mkCoreLets ds_ev_binds $
+ body
+
+ body | has_sig
+ , [(_, lrhs)] <- bind_prs
+ = lrhs
+ | otherwise
+ = mkLetRec bind_prs (Var local_id)
+
; (spec_binds, rules) <- dsSpecs rhs prags
- ; let global' = addIdSpecialisations global rules
- main_bind = makeCorePair dflags global' (isDefaultMethod prags)
- (dictArity dicts) rhs
+ ; let global_id' = addIdSpecialisations global_id rules
+ main_bind = makeCorePair dflags global_id'
+ (isDefaultMethod prags)
+ (dictArity dicts) rhs
- ; ASSERT(null force_vars)
- return ([], main_bind : fromOL spec_binds) }
+ ; return (force_vars', main_bind : fromOL spec_binds) }
- -- Another common case: no tyvars, no dicts
- -- In this case we can have a much simpler desugaring
-dsHsBind dflags
- (AbsBinds { abs_tvsa = [], abs_ev_varsa = []
- , abs_exports = exports
- , abs_ev_binds = ev_binds, abs_binds = binds })
- = do { (force_vars, bind_prs) <- dsLHsBinds binds
- ; let mk_bind (ABE { abe_wrap = wrap
+ -- Another common case: no tyvars, no dicts
+ -- In this case we can have a much simpler desugaring
+ | null tyvars, null dicts
+
+ = do { let mk_bind (ABE { abe_wrap = wrap
, abe_poly = global
, abe_mono = local
, abe_prags = prags })
@@ -225,42 +251,35 @@ dsHsBind dflags
0 (core_wrap (Var local))) }
; main_binds <- mapM mk_bind exports
- ; ds_binds <- dsTcEvBinds_s ev_binds
- ; return (force_vars, flattenBinds ds_binds ++ bind_prs ++ main_binds) }
-
-dsHsBind dflags
- (AbsBinds { abs_tvsa = tyvars, abs_ev_varsa = dicts
- , abs_exports = exports, abs_ev_binds = ev_binds
- , abs_binds = binds })
- -- See Note [Desugaring AbsBinds]
- = addDictsDs (toTcTypeBag (listToBag dicts)) $
- -- addDictsDs: push type constraints deeper for pattern match check
- do { (local_force_vars, bind_prs) <- dsLHsBinds binds
- ; let core_bind = Rec [ makeCorePair dflags (add_inline lcl_id) False 0 rhs
+ ; return (force_vars, flattenBinds ds_ev_binds ++ bind_prs ++ main_binds) }
+
+ -- The general case
+ -- See Note [Desugaring AbsBinds]
+ | otherwise
+ = do { let core_bind = Rec [ makeCorePair dflags (add_inline lcl_id) False 0 rhs
| (lcl_id, rhs) <- bind_prs ]
-- Monomorphic recursion possible, hence Rec
- new_force_vars = get_new_force_vars local_force_vars
- locals = map abe_mono exports
- all_locals = locals ++ new_force_vars
- tup_expr = mkBigCoreVarTup all_locals
- tup_ty = exprType tup_expr
- ; ds_binds <- dsTcEvBinds_s ev_binds
- ; let poly_tup_rhs = mkLams tyvars $ mkLams dicts $
- mkCoreLets ds_binds $
- mkLet core_bind $
- tup_expr
-
- ; poly_tup_id <- newSysLocalDs (exprType poly_tup_rhs)
+ new_force_vars = get_new_force_vars force_vars
+ locals = map abe_mono exports
+ all_locals = locals ++ new_force_vars
+ tup_expr = mkBigCoreVarTup all_locals
+ tup_ty = exprType tup_expr
+ ; let poly_tup_rhs = mkLams tyvars $ mkLams dicts $
+ mkCoreLets ds_ev_binds $
+ mkLet core_bind $
+ tup_expr
+
+ ; poly_tup_id <- newSysLocalDs (exprType poly_tup_rhs)
-- Find corresponding global or make up a new one: sometimes
-- we need to make new export to desugar strict binds, see
-- Note [Desugar Strict binds]
- ; (exported_force_vars, extra_exports) <- get_exports local_force_vars
+ ; (exported_force_vars, extra_exports) <- get_exports force_vars
- ; let mk_bind (ABE { abe_wrap = wrap
- , abe_poly = global
- , abe_mono = local, abe_prags = spec_prags })
- -- See Note [AbsBinds wrappers] in HsBinds
+ ; let mk_bind (ABE { abe_wrap = wrap
+ , abe_poly = global
+ , abe_mono = local, abe_prags = spec_prags })
+ -- See Note [AbsBinds wrappers] in HsBinds
= do { tup_id <- newSysLocalDs tup_ty
; core_wrap <- dsHsWrapper wrap
; let rhs = core_wrap $ mkLams tyvars $ mkLams dicts $
@@ -275,10 +294,10 @@ dsHsBind dflags
-- Id is just the selector. Hmm.
; return ((global', rhs) : fromOL spec_binds) }
- ; export_binds_s <- mapM mk_bind (exports ++ extra_exports)
+ ; export_binds_s <- mapM mk_bind (exports ++ extra_exports)
- ; return (exported_force_vars
- ,(poly_tup_id, poly_tup_rhs) :
+ ; return ( exported_force_vars
+ , (poly_tup_id, poly_tup_rhs) :
concat export_binds_s) }
where
inline_env :: IdEnv Id -- Maps a monomorphic local Id to one with
@@ -321,57 +340,10 @@ dsHsBind dflags
mk_export local =
do global <- newSysLocalDs
(exprType (mkLams tyvars (mkLams dicts (Var local))))
- return (ABE {abe_poly = global
- ,abe_mono = local
- ,abe_wrap = WpHole
- ,abe_prags = SpecPrags []})
-
--- AbsBindsSig is a combination of AbsBinds and FunBind
-dsHsBind dflags (AbsBindsSig { abs_tvs = tyvars, abs_ev_vars = dicts
- , abs_sig_export = global
- , abs_sig_prags = prags
- , abs_sig_ev_bind = ev_bind
- , abs_sig_bind = bind })
- | L bind_loc FunBind { fun_matches = matches
- , fun_co_fn = co_fn
- , fun_tick = tick } <- bind
- = putSrcSpanDs bind_loc $
- addDictsDs (toTcTypeBag (listToBag dicts)) $
- -- addDictsDs: push type constraints deeper for pattern match check
- do { (args, body) <- matchWrapper
- (mkPrefixFunRhs (noLoc $ idName global))
- Nothing matches
- ; core_wrap <- dsHsWrapper co_fn
- ; let body' = mkOptTickBox tick body
- fun_rhs = core_wrap (mkLams args body')
- force_vars
- | xopt LangExt.Strict dflags
- , matchGroupArity matches == 0 -- no need to force lambdas
- = [global]
- | isBangedBind (unLoc bind)
- = [global]
- | otherwise
- = []
-
- ; ds_binds <- dsTcEvBinds ev_bind
- ; let rhs = mkLams tyvars $
- mkLams dicts $
- mkCoreLets ds_binds $
- fun_rhs
-
- ; (spec_binds, rules) <- dsSpecs rhs prags
- ; let global' = addIdSpecialisations global rules
- main_bind = makeCorePair dflags global' (isDefaultMethod prags)
- (dictArity dicts) rhs
-
- ; return (force_vars, main_bind : fromOL spec_binds) }
-
- | otherwise
- = pprPanic "dsHsBind: AbsBindsSig" (ppr bind)
-
-dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind"
-
-
+ return (ABE { abe_poly = global
+ , abe_mono = local
+ , abe_wrap = WpHole
+ , abe_prags = SpecPrags [] })
-- | This is where we apply INLINE and INLINABLE pragmas. All we need to
-- do is to attach the unfolding information to the Id.
@@ -631,7 +603,7 @@ We define an "unlifted bind" to be any bind that binds an unlifted id. Note that
is *not* an unlifted bind. Unlifted binds are detected by HsUtils.isUnliftedHsBind.
-Define a "banged bind" to have a top-level bang. Detected by HsPat.isBangedPatBind.
+Define a "banged bind" to have a top-level bang. Detected by HsPat.isBangedHsBind.
Define a "strict bind" to be either an unlifted bind or a banged bind.
The restrictions are:
diff --git a/compiler/deSugar/DsExpr.hs b/compiler/deSugar/DsExpr.hs
index d2f35fc57e..21e7872358 100644
--- a/compiler/deSugar/DsExpr.hs
+++ b/compiler/deSugar/DsExpr.hs
@@ -130,8 +130,6 @@ ds_val_bind (NonRecursive, hsbinds) body
where
is_polymorphic (AbsBinds { abs_tvsa = tvs, abs_ev_varsa = evs })
= not (null tvs && null evs)
- is_polymorphic (AbsBindsSig { abs_tvs = tvs, abs_ev_vars = evs })
- = not (null tvs && null evs)
is_polymorphic _ = False
unlifted_must_be_bang bind
@@ -186,15 +184,6 @@ dsUnliftedBind (AbsBinds { abs_tvsa = [], abs_ev_varsa = []
; ds_binds <- dsTcEvBinds_s ev_binds
; return (mkCoreLets ds_binds body2) }
-dsUnliftedBind (AbsBindsSig { abs_tvs = []
- , abs_ev_vars = []
- , abs_sig_export = poly
- , abs_sig_ev_bind = ev_bind
- , abs_sig_bind = L _ bind }) body
- = do { ds_binds <- dsTcEvBinds ev_bind
- ; body' <- dsUnliftedBind (bind { fun_id = noLoc poly }) body
- ; return (mkCoreLets ds_binds body') }
-
dsUnliftedBind (FunBind { fun_id = L l fun
, fun_matches = matches
, fun_co_fn = co_fn
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
index 56bde9254c..17d0731f8d 100644
--- a/compiler/deSugar/DsMeta.hs
+++ b/compiler/deSugar/DsMeta.hs
@@ -307,7 +307,7 @@ repRoleD (L loc (RoleAnnotDecl tycon roles))
; return (loc, dec) }
-------------------------
-repDataDefn :: Core TH.Name -> Core [TH.TyVarBndr]
+repDataDefn :: Core TH.Name -> Core [TH.TyVarBndrQ]
-> Maybe (Core [TH.TypeQ])
-> HsDataDefn GhcRn
-> DsM (Core TH.DecQ)
@@ -318,20 +318,20 @@ repDataDefn tc bndrs opt_tys
; derivs1 <- repDerivs mb_derivs
; case (new_or_data, cons) of
(NewType, [con]) -> do { con' <- repC con
- ; ksig' <- repMaybeLKind ksig
+ ; ksig' <- repMaybeLTy ksig
; repNewtype cxt1 tc bndrs opt_tys ksig' con'
derivs1 }
(NewType, _) -> failWithDs (text "Multiple constructors for newtype:"
<+> pprQuotedList
(getConNames $ unLoc $ head cons))
- (DataType, _) -> do { ksig' <- repMaybeLKind ksig
+ (DataType, _) -> do { ksig' <- repMaybeLTy ksig
; consL <- mapM repC cons
; cons1 <- coreList conQTyConName consL
; repData cxt1 tc bndrs opt_tys ksig' cons1
derivs1 }
}
-repSynDecl :: Core TH.Name -> Core [TH.TyVarBndr]
+repSynDecl :: Core TH.Name -> Core [TH.TyVarBndrQ]
-> LHsType GhcRn
-> DsM (Core TH.DecQ)
repSynDecl tc bndrs ty
@@ -373,9 +373,9 @@ repFamilyDecl decl@(L loc (FamilyDecl { fdInfo = info,
}
-- | Represent result signature of a type family
-repFamilyResultSig :: FamilyResultSig GhcRn -> DsM (Core TH.FamilyResultSig)
+repFamilyResultSig :: FamilyResultSig GhcRn -> DsM (Core TH.FamilyResultSigQ)
repFamilyResultSig NoSig = repNoSig
-repFamilyResultSig (KindSig ki) = do { ki' <- repLKind ki
+repFamilyResultSig (KindSig ki) = do { ki' <- repLTy ki
; repKindSig ki' }
repFamilyResultSig (TyVarSig bndr) = do { bndr' <- repTyVarBndr bndr
; repTyVarSig bndr' }
@@ -384,12 +384,12 @@ repFamilyResultSig (TyVarSig bndr) = do { bndr' <- repTyVarBndr bndr
-- where the result signature can be either missing or a kind but never a named
-- result variable.
repFamilyResultSigToMaybeKind :: FamilyResultSig GhcRn
- -> DsM (Core (Maybe TH.Kind))
+ -> DsM (Core (Maybe TH.KindQ))
repFamilyResultSigToMaybeKind NoSig =
- do { coreNothing kindTyConName }
+ do { coreNothing kindQTyConName }
repFamilyResultSigToMaybeKind (KindSig ki) =
- do { ki' <- repLKind ki
- ; coreJust kindTyConName ki' }
+ do { ki' <- repLTy ki
+ ; coreJust kindQTyConName ki' }
repFamilyResultSigToMaybeKind _ = panic "repFamilyResultSigToMaybeKind"
-- | Represent injectivity annotation of a type family
@@ -769,7 +769,7 @@ rep_wc_ty_sig mk_sig loc sig_ty nm
= do { nm1 <- lookupLOcc nm
; let rep_in_scope_tv tv = do { name <- lookupBinder (hsLTyVarName tv)
; repTyVarBndrWithKind tv name }
- ; th_explicit_tvs <- repList tyVarBndrTyConName rep_in_scope_tv
+ ; th_explicit_tvs <- repList tyVarBndrQTyConName rep_in_scope_tv
explicit_tvs
-- NB: Don't pass any implicit type variables to repList above
-- See Note [Don't quantify implicit type variables in quotes]
@@ -865,7 +865,7 @@ addSimpleTyVarBinds names thing_inside
; wrapGenSyms fresh_names term }
addTyVarBinds :: LHsQTyVars GhcRn -- the binders to be added
- -> (Core [TH.TyVarBndr] -> DsM (Core (TH.Q a))) -- action in the ext env
+ -> (Core [TH.TyVarBndrQ] -> DsM (Core (TH.Q a))) -- action in the ext env
-> DsM (Core (TH.Q a))
-- gensym a list of type variables and enter them into the meta environment;
-- the computations passed as the second argument is executed in that extended
@@ -876,7 +876,7 @@ addTyVarBinds (HsQTvs { hsq_implicit = imp_tvs, hsq_explicit = exp_tvs }) m
; fresh_exp_names <- mkGenSyms (map hsLTyVarName exp_tvs)
; let fresh_names = fresh_imp_names ++ fresh_exp_names
; term <- addBinds fresh_names $
- do { kbs <- repList tyVarBndrTyConName mk_tv_bndr
+ do { kbs <- repList tyVarBndrQTyConName mk_tv_bndr
(exp_tvs `zip` fresh_exp_names)
; m kbs }
; wrapGenSyms fresh_names term }
@@ -884,7 +884,7 @@ addTyVarBinds (HsQTvs { hsq_implicit = imp_tvs, hsq_explicit = exp_tvs }) m
mk_tv_bndr (tv, (_,v)) = repTyVarBndrWithKind tv (coreVar v)
addTyClTyVarBinds :: LHsQTyVars GhcRn
- -> (Core [TH.TyVarBndr] -> DsM (Core (TH.Q a)))
+ -> (Core [TH.TyVarBndrQ] -> DsM (Core (TH.Q a)))
-> DsM (Core (TH.Q a))
-- Used for data/newtype declarations, and family instances,
@@ -900,29 +900,31 @@ addTyClTyVarBinds tvs m
-- This makes things work for family declarations
; term <- addBinds freshNames $
- do { kbs <- repList tyVarBndrTyConName mk_tv_bndr (hsQTvExplicit tvs)
+ do { kbs <- repList tyVarBndrQTyConName mk_tv_bndr
+ (hsQTvExplicit tvs)
; m kbs }
; wrapGenSyms freshNames term }
where
+ mk_tv_bndr :: LHsTyVarBndr GhcRn -> DsM (Core TH.TyVarBndrQ)
mk_tv_bndr tv = do { v <- lookupBinder (hsLTyVarName tv)
; repTyVarBndrWithKind tv v }
-- Produce kinded binder constructors from the Haskell tyvar binders
--
repTyVarBndrWithKind :: LHsTyVarBndr GhcRn
- -> Core TH.Name -> DsM (Core TH.TyVarBndr)
+ -> Core TH.Name -> DsM (Core TH.TyVarBndrQ)
repTyVarBndrWithKind (L _ (UserTyVar _)) nm
= repPlainTV nm
repTyVarBndrWithKind (L _ (KindedTyVar _ ki)) nm
- = repLKind ki >>= repKindedTV nm
+ = repLTy ki >>= repKindedTV nm
-- | Represent a type variable binder
-repTyVarBndr :: LHsTyVarBndr GhcRn -> DsM (Core TH.TyVarBndr)
+repTyVarBndr :: LHsTyVarBndr GhcRn -> DsM (Core TH.TyVarBndrQ)
repTyVarBndr (L _ (UserTyVar (L _ nm)) )= do { nm' <- lookupBinder nm
; repPlainTV nm' }
repTyVarBndr (L _ (KindedTyVar (L _ nm) ki)) = do { nm' <- lookupBinder nm
- ; ki' <- repLKind ki
+ ; ki' <- repLTy ki
; repKindedTV nm' ki' }
-- represent a type context
@@ -996,6 +998,8 @@ repTy ty@(HsForAllTy {}) = repForall ty
repTy ty@(HsQualTy {}) = repForall ty
repTy (HsTyVar _ (L _ n))
+ | isLiftedTypeKindTyConName n = repTStar
+ | n `hasKey` constraintKindTyConKey = repTConstraint
| isTvOcc occ = do tv1 <- lookupOcc n
repTvar tv1
| isDataOcc occ = do tc1 <- lookupOcc n
@@ -1044,7 +1048,7 @@ repTy (HsEqTy t1 t2) = do
repTapps eq [t1', t2']
repTy (HsKindSig t k) = do
t1 <- repLTy t
- k1 <- repLKind k
+ k1 <- repLTy k
repTSig t1 k1
repTy (HsSpliceTy splice _) = repSplice splice
repTy (HsExplicitListTy _ _ tys) = do
@@ -1068,59 +1072,14 @@ repTyLit (HsStrTy _ s) = do { s' <- mkStringExprFS s
; rep2 strTyLitName [s']
}
--- represent a kind
---
--- It would be great to scrap this function in favor of repLTy, since Types
--- and Kinds are the same things. We have not done so yet for engineering
--- reasons, as repLTy returns a monadic TypeQ, whereas repLKind returns a pure
--- Kind, so in order to replace repLKind with repLTy, we'd need to go through
--- and purify repLTy and every monadic function it calls. This is the subject
--- GHC Trac #11785.
-repLKind :: LHsKind GhcRn -> DsM (Core TH.Kind)
-repLKind ki
- = do { let (kis, ki') = splitHsFunType ki
- ; kis_rep <- mapM repLKind kis
- ; ki'_rep <- repNonArrowLKind ki'
- ; kcon <- repKArrow
- ; let f k1 k2 = repKApp kcon k1 >>= flip repKApp k2
- ; foldrM f ki'_rep kis_rep
- }
-
--- | Represent a kind wrapped in a Maybe
-repMaybeLKind :: Maybe (LHsKind GhcRn)
- -> DsM (Core (Maybe TH.Kind))
-repMaybeLKind Nothing =
- do { coreNothing kindTyConName }
-repMaybeLKind (Just ki) =
- do { ki' <- repLKind ki
- ; coreJust kindTyConName ki' }
-
-repNonArrowLKind :: LHsKind GhcRn -> DsM (Core TH.Kind)
-repNonArrowLKind (L _ ki) = repNonArrowKind ki
-
-repNonArrowKind :: HsKind GhcRn -> DsM (Core TH.Kind)
-repNonArrowKind (HsTyVar _ (L _ name))
- | isLiftedTypeKindTyConName name = repKStar
- | name `hasKey` constraintKindTyConKey = repKConstraint
- | isTvOcc (nameOccName name) = lookupOcc name >>= repKVar
- | otherwise = lookupOcc name >>= repKCon
-repNonArrowKind (HsAppTy f a) = do { f' <- repLKind f
- ; a' <- repLKind a
- ; repKApp f' a'
- }
-repNonArrowKind (HsListTy k) = do { k' <- repLKind k
- ; kcon <- repKList
- ; repKApp kcon k'
- }
-repNonArrowKind (HsTupleTy _ ks) = do { ks' <- mapM repLKind ks
- ; kcon <- repKTuple (length ks)
- ; repKApps kcon ks'
- }
-repNonArrowKind (HsKindSig k sort) = do { k' <- repLKind k
- ; sort' <- repLKind sort
- ; repKSig k' sort'
- }
-repNonArrowKind k = notHandled "Exotic form of kind" (ppr k)
+-- | Represent a type wrapped in a Maybe
+repMaybeLTy :: Maybe (LHsKind GhcRn)
+ -> DsM (Core (Maybe TH.TypeQ))
+repMaybeLTy Nothing =
+ do { coreNothing kindQTyConName }
+repMaybeLTy (Just ki) =
+ do { ki' <- repLTy ki
+ ; coreJust kindQTyConName ki' }
repRole :: Located (Maybe Role) -> DsM (Core TH.Role)
repRole (L _ (Just Nominal)) = rep2 nominalRName []
@@ -1299,7 +1258,7 @@ repE e = notHandled "Expression form" (ppr e)
-- Building representations of auxillary structures like Match, Clause, Stmt,
repMatchTup :: LMatch GhcRn (LHsExpr GhcRn) -> DsM (Core TH.MatchQ)
-repMatchTup (L _ (Match _ [p] _ (GRHSs guards (L _ wheres)))) =
+repMatchTup (L _ (Match { m_pats = [p], m_grhss = GRHSs guards (L _ wheres) })) =
do { ss1 <- mkGenSyms (collectPatBinders p)
; addBinds ss1 $ do {
; p1 <- repLP p
@@ -1311,7 +1270,7 @@ repMatchTup (L _ (Match _ [p] _ (GRHSs guards (L _ wheres)))) =
repMatchTup _ = panic "repMatchTup: case alt with more than one arg"
repClauseTup :: LMatch GhcRn (LHsExpr GhcRn) -> DsM (Core TH.ClauseQ)
-repClauseTup (L _ (Match _ ps _ (GRHSs guards (L _ wheres)))) =
+repClauseTup (L _ (Match { m_pats = ps, m_grhss = GRHSs guards (L _ wheres) })) =
do { ss1 <- mkGenSyms (collectPatsBinders ps)
; addBinds ss1 $ do {
ps1 <- repLPs ps
@@ -1481,8 +1440,8 @@ rep_bind :: LHsBind GhcRn -> DsM (SrcSpan, Core TH.DecQ)
rep_bind (L loc (FunBind
{ fun_id = fn,
fun_matches = MG { mg_alts
- = L _ [L _ (Match _ [] _
- (GRHSs guards (L _ wheres)))] } }))
+ = L _ [L _ (Match { m_pats = []
+ , m_grhss = GRHSs guards (L _ wheres) })] } }))
= do { (ss,wherecore) <- repBinds wheres
; guardcore <- addBinds ss (repGuards guards)
; fn' <- lookupLBinder fn
@@ -1517,7 +1476,6 @@ rep_bind (L _ (VarBind { var_id = v, var_rhs = e}))
; return (srcLocSpan (getSrcLoc v), ans) }
rep_bind (L _ (AbsBinds {})) = panic "rep_bind: AbsBinds"
-rep_bind (L _ (AbsBindsSig {})) = panic "rep_bind: AbsBindsSig"
rep_bind (L loc (PatSynBind (PSB { psb_id = syn
, psb_fvs = _fvs
, psb_args = args
@@ -1624,7 +1582,8 @@ repExplBidirPatSynDir (MkC cls) = rep2 explBidirPatSynName [cls]
-- (\ p1 .. pn -> exp) by causing an error.
repLambda :: LMatch GhcRn (LHsExpr GhcRn) -> DsM (Core TH.ExpQ)
-repLambda (L _ (Match _ ps _ (GRHSs [L _ (GRHS [] e)] (L _ EmptyLocalBinds))))
+repLambda (L _ (Match { m_pats = ps
+ , m_grhss = GRHSs [L _ (GRHS [] e)] (L _ EmptyLocalBinds) } ))
= do { let bndrs = collectPatsBinders ps ;
; ss <- mkGenSyms bndrs
; lam <- addBinds ss (
@@ -2046,8 +2005,8 @@ repVal (MkC p) (MkC b) (MkC ds) = rep2 valDName [p, b, ds]
repFun :: Core TH.Name -> Core [TH.ClauseQ] -> DsM (Core TH.DecQ)
repFun (MkC nm) (MkC b) = rep2 funDName [nm, b]
-repData :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndr]
- -> Maybe (Core [TH.TypeQ]) -> Core (Maybe TH.Kind)
+repData :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndrQ]
+ -> Maybe (Core [TH.TypeQ]) -> Core (Maybe TH.KindQ)
-> Core [TH.ConQ] -> Core [TH.DerivClauseQ] -> DsM (Core TH.DecQ)
repData (MkC cxt) (MkC nm) (MkC tvs) Nothing (MkC ksig) (MkC cons) (MkC derivs)
= rep2 dataDName [cxt, nm, tvs, ksig, cons, derivs]
@@ -2055,8 +2014,8 @@ repData (MkC cxt) (MkC nm) (MkC _) (Just (MkC tys)) (MkC ksig) (MkC cons)
(MkC derivs)
= rep2 dataInstDName [cxt, nm, tys, ksig, cons, derivs]
-repNewtype :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndr]
- -> Maybe (Core [TH.TypeQ]) -> Core (Maybe TH.Kind)
+repNewtype :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndrQ]
+ -> Maybe (Core [TH.TypeQ]) -> Core (Maybe TH.KindQ)
-> Core TH.ConQ -> Core [TH.DerivClauseQ] -> DsM (Core TH.DecQ)
repNewtype (MkC cxt) (MkC nm) (MkC tvs) Nothing (MkC ksig) (MkC con)
(MkC derivs)
@@ -2065,7 +2024,7 @@ repNewtype (MkC cxt) (MkC nm) (MkC _) (Just (MkC tys)) (MkC ksig) (MkC con)
(MkC derivs)
= rep2 newtypeInstDName [cxt, nm, tys, ksig, con, derivs]
-repTySyn :: Core TH.Name -> Core [TH.TyVarBndr]
+repTySyn :: Core TH.Name -> Core [TH.TyVarBndrQ]
-> Core TH.TypeQ -> DsM (Core TH.DecQ)
repTySyn (MkC nm) (MkC tvs) (MkC rhs)
= rep2 tySynDName [nm, tvs, rhs]
@@ -2105,7 +2064,7 @@ repOverlap mb =
just = coreJust overlapTyConName
-repClass :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndr]
+repClass :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndrQ]
-> Core [TH.FunDep] -> Core [TH.DecQ]
-> DsM (Core TH.DecQ)
repClass (MkC cxt) (MkC cls) (MkC tvs) (MkC fds) (MkC ds)
@@ -2150,22 +2109,22 @@ repTySynInst :: Core TH.Name -> Core TH.TySynEqnQ -> DsM (Core TH.DecQ)
repTySynInst (MkC nm) (MkC eqn)
= rep2 tySynInstDName [nm, eqn]
-repDataFamilyD :: Core TH.Name -> Core [TH.TyVarBndr]
- -> Core (Maybe TH.Kind) -> DsM (Core TH.DecQ)
+repDataFamilyD :: Core TH.Name -> Core [TH.TyVarBndrQ]
+ -> Core (Maybe TH.KindQ) -> DsM (Core TH.DecQ)
repDataFamilyD (MkC nm) (MkC tvs) (MkC kind)
= rep2 dataFamilyDName [nm, tvs, kind]
repOpenFamilyD :: Core TH.Name
- -> Core [TH.TyVarBndr]
- -> Core TH.FamilyResultSig
+ -> Core [TH.TyVarBndrQ]
+ -> Core TH.FamilyResultSigQ
-> Core (Maybe TH.InjectivityAnn)
-> DsM (Core TH.DecQ)
repOpenFamilyD (MkC nm) (MkC tvs) (MkC result) (MkC inj)
= rep2 openTypeFamilyDName [nm, tvs, result, inj]
repClosedFamilyD :: Core TH.Name
- -> Core [TH.TyVarBndr]
- -> Core TH.FamilyResultSig
+ -> Core [TH.TyVarBndrQ]
+ -> Core TH.FamilyResultSigQ
-> Core (Maybe TH.InjectivityAnn)
-> Core [TH.TySynEqnQ]
-> DsM (Core TH.DecQ)
@@ -2251,7 +2210,7 @@ repConstr _ _ _ =
------------ Types -------------------
-repTForall :: Core [TH.TyVarBndr] -> Core TH.CxtQ -> Core TH.TypeQ
+repTForall :: Core [TH.TyVarBndrQ] -> Core TH.CxtQ -> Core TH.TypeQ
-> DsM (Core TH.TypeQ)
repTForall (MkC tvars) (MkC ctxt) (MkC ty)
= rep2 forallTName [tvars, ctxt, ty]
@@ -2266,7 +2225,7 @@ repTapps :: Core TH.TypeQ -> [Core TH.TypeQ] -> DsM (Core TH.TypeQ)
repTapps f [] = return f
repTapps f (t:ts) = do { f1 <- repTapp f t; repTapps f1 ts }
-repTSig :: Core TH.TypeQ -> Core TH.Kind -> DsM (Core TH.TypeQ)
+repTSig :: Core TH.TypeQ -> Core TH.KindQ -> DsM (Core TH.TypeQ)
repTSig (MkC ty) (MkC ki) = rep2 sigTName [ty, ki]
repTequality :: DsM (Core TH.TypeQ)
@@ -2286,6 +2245,12 @@ repTLit (MkC lit) = rep2 litTName [lit]
repTWildCard :: DsM (Core TH.TypeQ)
repTWildCard = rep2 wildCardTName []
+repTStar :: DsM (Core TH.TypeQ)
+repTStar = rep2 starKName []
+
+repTConstraint :: DsM (Core TH.TypeQ)
+repTConstraint = rep2 constraintKName []
+
--------- Type constructors --------------
repNamedTyCon :: Core TH.Name -> DsM (Core TH.TypeQ)
@@ -2325,56 +2290,24 @@ repPromotedNilTyCon = rep2 promotedNilTName []
repPromotedConsTyCon :: DsM (Core TH.TypeQ)
repPromotedConsTyCon = rep2 promotedConsTName []
------------- Kinds -------------------
+------------ TyVarBndrs -------------------
-repPlainTV :: Core TH.Name -> DsM (Core TH.TyVarBndr)
+repPlainTV :: Core TH.Name -> DsM (Core TH.TyVarBndrQ)
repPlainTV (MkC nm) = rep2 plainTVName [nm]
-repKindedTV :: Core TH.Name -> Core TH.Kind -> DsM (Core TH.TyVarBndr)
+repKindedTV :: Core TH.Name -> Core TH.KindQ -> DsM (Core TH.TyVarBndrQ)
repKindedTV (MkC nm) (MkC ki) = rep2 kindedTVName [nm, ki]
-repKVar :: Core TH.Name -> DsM (Core TH.Kind)
-repKVar (MkC s) = rep2 varKName [s]
-
-repKCon :: Core TH.Name -> DsM (Core TH.Kind)
-repKCon (MkC s) = rep2 conKName [s]
-
-repKTuple :: Int -> DsM (Core TH.Kind)
-repKTuple i = do dflags <- getDynFlags
- rep2 tupleKName [mkIntExprInt dflags i]
-
-repKArrow :: DsM (Core TH.Kind)
-repKArrow = rep2 arrowKName []
-
-repKList :: DsM (Core TH.Kind)
-repKList = rep2 listKName []
-
-repKApp :: Core TH.Kind -> Core TH.Kind -> DsM (Core TH.Kind)
-repKApp (MkC k1) (MkC k2) = rep2 appKName [k1, k2]
-
-repKApps :: Core TH.Kind -> [Core TH.Kind] -> DsM (Core TH.Kind)
-repKApps f [] = return f
-repKApps f (k:ks) = do { f' <- repKApp f k; repKApps f' ks }
-
-repKStar :: DsM (Core TH.Kind)
-repKStar = rep2 starKName []
-
-repKConstraint :: DsM (Core TH.Kind)
-repKConstraint = rep2 constraintKName []
-
-repKSig :: Core TH.Kind -> Core TH.Kind -> DsM (Core TH.Kind)
-repKSig (MkC k) (MkC sort) = rep2 sigTDataConName [k, sort]
-
----------------------------------------------------------
-- Type family result signature
-repNoSig :: DsM (Core TH.FamilyResultSig)
+repNoSig :: DsM (Core TH.FamilyResultSigQ)
repNoSig = rep2 noSigName []
-repKindSig :: Core TH.Kind -> DsM (Core TH.FamilyResultSig)
+repKindSig :: Core TH.KindQ -> DsM (Core TH.FamilyResultSigQ)
repKindSig (MkC ki) = rep2 kindSigName [ki]
-repTyVarSig :: Core TH.TyVarBndr -> DsM (Core TH.FamilyResultSig)
+repTyVarSig :: Core TH.TyVarBndrQ -> DsM (Core TH.FamilyResultSigQ)
repTyVarSig (MkC bndr) = rep2 tyVarSigName [bndr]
----------------------------------------------------------
diff --git a/compiler/deSugar/Match.hs b/compiler/deSugar/Match.hs
index a870c6f9c3..95cf40dcf2 100644
--- a/compiler/deSugar/Match.hs
+++ b/compiler/deSugar/Match.hs
@@ -749,14 +749,9 @@ matchWrapper ctxt mb_scr (MG { mg_alts = L _ matches
matchEquations ctxt new_vars eqns_info rhs_ty
; return (new_vars, result_expr) }
where
- mk_eqn_info vars (L _ (Match ctx pats _ grhss))
+ mk_eqn_info vars (L _ (Match { m_pats = pats, m_grhss = grhss }))
= do { dflags <- getDynFlags
- ; let add_bang
- | FunRhs {mc_strictness=SrcStrict} <- ctx
- = pprTrace "addBang" empty addBang
- | otherwise
- = decideBangHood dflags
- upats = map (unLoc . add_bang) pats
+ ; let upats = map (unLoc . decideBangHood dflags) pats
dicts = toTcTypeBag (collectEvVarsPats upats) -- Only TcTyVars
; tm_cs <- genCaseTmCs2 mb_scr upats vars
; match_result <- addDictsDs dicts $ -- See Note [Type and Term Equality Propagation]
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index e62b8080a9..98f9f3cb25 100644
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -632,10 +632,3 @@ Library
RtClosureInspect
DebuggerUtils
GHCi
-
- if !flag(stage1)
- -- ghc:Serialized moved to ghc-boot:GHC.Serialized. So for
- -- compatibility with GHC 7.10 and earlier, we reexport it
- -- under the old name.
- reexported-modules:
- ghc-boot:GHC.Serialized as Serialized
diff --git a/compiler/ghci/ByteCodeGen.hs b/compiler/ghci/ByteCodeGen.hs
index 2695a98f9e..939d1dd760 100644
--- a/compiler/ghci/ByteCodeGen.hs
+++ b/compiler/ghci/ByteCodeGen.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP, MagicHash, RecordWildCards, BangPatterns #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# OPTIONS_GHC -fprof-auto-top #-}
--
-- (c) The University of Glasgow 2002-2006
@@ -43,8 +44,10 @@ import ErrUtils
import Unique
import FastString
import Panic
-import StgCmmLayout ( ArgRep(..), toArgRep, argRepSizeW )
-import SMRep
+import StgCmmClosure ( NonVoid(..), fromNonVoid, nonVoidIds )
+import StgCmmLayout ( ArgRep(..), toArgRep, argRepSizeW,
+ mkVirtHeapOffsets, mkVirtConstrOffsets )
+import SMRep hiding (WordOff, ByteOff, wordsToBytes)
import Bitmap
import OrdList
import Maybes
@@ -68,11 +71,7 @@ import qualified Data.Map as Map
import qualified Data.IntMap as IntMap
import qualified FiniteMap as Map
import Data.Ord
-#if MIN_VERSION_base(4,9,0)
import GHC.Stack.CCS
-#else
-import GHC.Stack as GHC.Stack.CCS
-#endif
-- -----------------------------------------------------------------------------
-- Generating byte code for a complete module
@@ -209,11 +208,33 @@ simpleFreeVars = go . freeVars
type BCInstrList = OrdList BCInstr
-type Sequel = Word -- back off to this depth before ENTER
+newtype ByteOff = ByteOff Int
+ deriving (Enum, Eq, Integral, Num, Ord, Real)
+
+newtype WordOff = WordOff Int
+ deriving (Enum, Eq, Integral, Num, Ord, Real)
+
+wordsToBytes :: DynFlags -> WordOff -> ByteOff
+wordsToBytes dflags = fromIntegral . (* wORD_SIZE dflags) . fromIntegral
+
+-- Used when we know we have a whole number of words
+bytesToWords :: DynFlags -> ByteOff -> WordOff
+bytesToWords dflags (ByteOff bytes) =
+ let (q, r) = bytes `quotRem` (wORD_SIZE dflags)
+ in if r == 0
+ then fromIntegral q
+ else panic $ "ByteCodeGen.bytesToWords: bytes=" ++ show bytes
+
+wordSize :: DynFlags -> ByteOff
+wordSize dflags = ByteOff (wORD_SIZE dflags)
+
+type Sequel = ByteOff -- back off to this depth before ENTER
+
+type StackDepth = ByteOff
-- | Maps Ids to their stack depth. This allows us to avoid having to mess with
-- it after each push/pop.
-type BCEnv = Map Id Word -- To find vars on the stack
+type BCEnv = Map Id StackDepth -- To find vars on the stack
{-
ppBCEnv :: BCEnv -> SDoc
@@ -296,8 +317,6 @@ argBits dflags (rep : args)
-- Compile code for the right-hand side of a top-level binding
schemeTopBind :: (Id, AnnExpr Id DVarSet) -> BcM (ProtoBCO Name)
-
-
schemeTopBind (id, rhs)
| Just data_con <- isDataConWorkId_maybe id,
isNullaryRepDataCon data_con = do
@@ -358,7 +377,12 @@ collect (_, e) = go [] e
= go (x:xs) e
go xs not_lambda = (reverse xs, not_lambda)
-schemeR_wrk :: [Id] -> Id -> AnnExpr Id DVarSet -> ([Var], AnnExpr' Var DVarSet) -> BcM (ProtoBCO Name)
+schemeR_wrk
+ :: [Id]
+ -> Id
+ -> AnnExpr Id DVarSet
+ -> ([Var], AnnExpr' Var DVarSet)
+ -> BcM (ProtoBCO Name)
schemeR_wrk fvs nm original_body (args, body)
= do
dflags <- getDynFlags
@@ -369,27 +393,30 @@ schemeR_wrk fvs nm original_body (args, body)
-- \fv1..fvn x1..xn -> e
-- i.e. the fvs come first
- szsw_args = map (fromIntegral . idSizeW dflags) all_args
- szw_args = sum szsw_args
- p_init = Map.fromList (zip all_args (mkStackOffsets 0 szsw_args))
+ -- Stack arguments always take a whole number of words, we never pack
+ -- them unlike constructor fields.
+ szsb_args = map (wordsToBytes dflags . idSizeW dflags) all_args
+ sum_szsb_args = sum szsb_args
+ p_init = Map.fromList (zip all_args (mkStackOffsets 0 szsb_args))
-- make the arg bitmap
bits = argBits dflags (reverse (map bcIdArgRep all_args))
bitmap_size = genericLength bits
bitmap = mkBitmap dflags bits
- body_code <- schemeER_wrk szw_args p_init body
+ body_code <- schemeER_wrk sum_szsb_args p_init body
emitBc (mkProtoBCO dflags (getName nm) body_code (Right original_body)
arity bitmap_size bitmap False{-not alts-})
-- introduce break instructions for ticked expressions
-schemeER_wrk :: Word -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
+schemeER_wrk :: StackDepth -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
schemeER_wrk d p rhs
| AnnTick (Breakpoint tick_no fvs) (_annot, newRhs) <- rhs
- = do code <- schemeE (fromIntegral d) 0 p newRhs
+ = do code <- schemeE d 0 p newRhs
cc_arr <- getCCArray
this_mod <- moduleName <$> getCurrentModule
- let idOffSets = getVarOffSets d p fvs
+ dflags <- getDynFlags
+ let idOffSets = getVarOffSets dflags d p fvs
let breakInfo = CgBreakInfo
{ cgb_vars = idOffSets
, cgb_resty = exprType (deAnnotate' newRhs)
@@ -400,10 +427,10 @@ schemeER_wrk d p rhs
| otherwise = toRemotePtr nullPtr
let breakInstr = BRK_FUN (fromIntegral tick_no) (getUnique this_mod) cc
return $ breakInstr `consOL` code
- | otherwise = schemeE (fromIntegral d) 0 p rhs
+ | otherwise = schemeE d 0 p rhs
-getVarOffSets :: Word -> BCEnv -> [Id] -> [(Id, Word16)]
-getVarOffSets depth env = catMaybes . map getOffSet
+getVarOffSets :: DynFlags -> StackDepth -> BCEnv -> [Id] -> [(Id, Word16)]
+getVarOffSets dflags depth env = catMaybes . map getOffSet
where
getOffSet id = case lookupBCEnv_maybe id env of
Nothing -> Nothing
@@ -415,16 +442,20 @@ getVarOffSets depth env = catMaybes . map getOffSet
-- this "adjustment" is needed due to stack manipulation for
-- BRK_FUN in Interpreter.c In any case, this is used only when
-- we trigger a breakpoint.
- let adjustment = 2
- in Just (id, trunc16 $ depth - offset + adjustment)
+ let !var_depth_ws =
+ trunc16W $ bytesToWords dflags (depth - offset) + 2
+ in Just (id, var_depth_ws)
-trunc16 :: Word -> Word16
-trunc16 w
+truncIntegral16 :: Integral a => a -> Word16
+truncIntegral16 w
| w > fromIntegral (maxBound :: Word16)
= panic "stack depth overflow"
| otherwise
= fromIntegral w
+trunc16W :: WordOff -> Word16
+trunc16W = truncIntegral16
+
fvsToEnv :: BCEnv -> DVarSet -> [Id]
-- Takes the free variables of a right-hand side, and
-- delivers an ordered list of the local variables that will
@@ -441,21 +472,26 @@ fvsToEnv p fvs = [v | v <- dVarSetElems fvs,
-- -----------------------------------------------------------------------------
-- schemeE
-returnUnboxedAtom :: Word -> Sequel -> BCEnv
- -> AnnExpr' Id DVarSet -> ArgRep
- -> BcM BCInstrList
+returnUnboxedAtom
+ :: StackDepth
+ -> Sequel
+ -> BCEnv
+ -> AnnExpr' Id DVarSet
+ -> ArgRep
+ -> BcM BCInstrList
-- Returning an unlifted value.
-- Heave it on the stack, SLIDE, and RETURN.
-returnUnboxedAtom d s p e e_rep
- = do (push, szw) <- pushAtom d p e
- return (push -- value onto stack
- `appOL` mkSLIDE szw (d-s) -- clear to sequel
- `snocOL` RETURN_UBX e_rep) -- go
+returnUnboxedAtom d s p e e_rep = do
+ dflags <- getDynFlags
+ (push, szb) <- pushAtom d p e
+ return (push -- value onto stack
+ `appOL` mkSlideB dflags szb (d - s) -- clear to sequel
+ `snocOL` RETURN_UBX e_rep) -- go
-- Compile code to apply the given expression to the remaining args
-- on the stack, returning a HNF.
-schemeE :: Word -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
-
+schemeE
+ :: StackDepth -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
schemeE d s p e
| Just e' <- bcView e
= schemeE d s p e'
@@ -478,7 +514,8 @@ schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))
-- saturated constructor application.
-- Just allocate the constructor and carry on
alloc_code <- mkConAppCode d s p data_con args_r_to_l
- let !d2 = d + 1
+ dflags <- getDynFlags
+ let !d2 = d + wordSize dflags
body_code <- schemeE d2 s (Map.insert x d2 p) body
return (alloc_code `appOL` body_code)
@@ -493,28 +530,39 @@ schemeE d s p (AnnLet binds (_,body)) = do
fvss = map (fvsToEnv p' . fst) rhss
-- Sizes of free vars
- sizes = map (\rhs_fvs -> sum (map (fromIntegral . idSizeW dflags) rhs_fvs)) fvss
+ size_w = trunc16W . idSizeW dflags
+ sizes = map (\rhs_fvs -> sum (map size_w rhs_fvs)) fvss
-- the arity of each rhs
arities = map (genericLength . fst . collect) rhss
-- This p', d' defn is safe because all the items being pushed
- -- are ptrs, so all have size 1. d' and p' reflect the stack
+ -- are ptrs, so all have size 1 word. d' and p' reflect the stack
-- after the closures have been allocated in the heap (but not
-- filled in), and pointers to them parked on the stack.
- p' = Map.insertList (zipE xs (mkStackOffsets d (genericReplicate n_binds 1))) p
- d' = d + fromIntegral n_binds
- zipE = zipEqual "schemeE"
+ offsets = mkStackOffsets d (genericReplicate n_binds (wordSize dflags))
+ p' = Map.insertList (zipE xs offsets) p
+ d' = d + wordsToBytes dflags n_binds
+ zipE = zipEqual "schemeE"
-- ToDo: don't build thunks for things with no free variables
+ build_thunk
+ :: StackDepth
+ -> [Id]
+ -> Word16
+ -> ProtoBCO Name
+ -> Word16
+ -> Word16
+ -> BcM BCInstrList
build_thunk _ [] size bco off arity
= return (PUSH_BCO bco `consOL` unitOL (mkap (off+size) size))
where
mkap | arity == 0 = MKAP
| otherwise = MKPAP
build_thunk dd (fv:fvs) size bco off arity = do
- (push_code, pushed_szw) <- pushAtom dd p' (AnnVar fv)
- more_push_code <- build_thunk (dd + fromIntegral pushed_szw) fvs size bco off arity
+ (push_code, pushed_szb) <- pushAtom dd p' (AnnVar fv)
+ more_push_code <-
+ build_thunk (dd + pushed_szb) fvs size bco off arity
return (push_code `appOL` more_push_code)
alloc_code = toOL (zipWith mkAlloc sizes arities)
@@ -532,7 +580,7 @@ schemeE d s p (AnnLet binds (_,body)) = do
build_thunk d' fvs size bco off arity
compile_binds =
- [ compile_bind d' fvs x rhs size arity n
+ [ compile_bind d' fvs x rhs size arity (trunc16W n)
| (fvs, x, rhs, size, arity, n) <-
zip6 fvss xs rhss sizes arities [n_binds, n_binds-1 .. 1]
]
@@ -661,7 +709,7 @@ schemeE _ _ _ expr
-- 4. Otherwise, it must be a function call. Push the args
-- right to left, SLIDE and ENTER.
-schemeT :: Word -- Stack depth
+schemeT :: StackDepth -- Stack depth
-> Sequel -- Sequel depth
-> BCEnv -- stack env
-> AnnExpr' Id DVarSet
@@ -669,12 +717,6 @@ schemeT :: Word -- Stack depth
schemeT d s p app
--- | trace ("schemeT: env in = \n" ++ showSDocDebug (ppBCEnv p)) False
--- = panic "schemeT ?!?!"
-
--- | trace ("\nschemeT\n" ++ showSDoc (pprCoreExpr (deAnnotate' app)) ++ "\n") False
--- = error "?!?!"
-
-- Case 0
| Just (arg, constr_names) <- maybe_is_tagToEnum_call app
= implement_tagToId d s p arg constr_names
@@ -699,8 +741,9 @@ schemeT d s p app
-- Case 3: Ordinary data constructor
| Just con <- maybe_saturated_dcon
= do alloc_con <- mkConAppCode d s p con args_r_to_l
+ dflags <- getDynFlags
return (alloc_con `appOL`
- mkSLIDE 1 (d - s) `snocOL`
+ mkSlideW 1 (bytesToWords dflags $ d - s) `snocOL`
ENTER)
-- Case 4: Tail call of function
@@ -725,33 +768,46 @@ schemeT d s p app
-- Generate code to build a constructor application,
-- leaving it on top of the stack
-mkConAppCode :: Word -> Sequel -> BCEnv
- -> DataCon -- The data constructor
- -> [AnnExpr' Id DVarSet] -- Args, in *reverse* order
- -> BcM BCInstrList
-
+mkConAppCode
+ :: StackDepth
+ -> Sequel
+ -> BCEnv
+ -> DataCon -- The data constructor
+ -> [AnnExpr' Id DVarSet] -- Args, in *reverse* order
+ -> BcM BCInstrList
mkConAppCode _ _ _ con [] -- Nullary constructor
= ASSERT( isNullaryRepDataCon con )
return (unitOL (PUSH_G (getName (dataConWorkId con))))
-- Instead of doing a PACK, which would allocate a fresh
-- copy of this constructor, use the single shared version.
-mkConAppCode orig_d _ p con args_r_to_l
- = ASSERT( args_r_to_l `lengthIs` dataConRepArity con )
- do_pushery orig_d (non_ptr_args ++ ptr_args)
- where
- -- The args are already in reverse order, which is the way PACK
- -- expects them to be. We must push the non-ptrs after the ptrs.
- (ptr_args, non_ptr_args) = partition isPtrAtom args_r_to_l
+mkConAppCode orig_d _ p con args_r_to_l =
+ ASSERT( args_r_to_l `lengthIs` dataConRepArity con ) app_code
+ where
+ app_code = do
+ dflags <- getDynFlags
- do_pushery d (arg:args)
- = do (push, arg_words) <- pushAtom d p arg
- more_push_code <- do_pushery (d + fromIntegral arg_words) args
- return (push `appOL` more_push_code)
- do_pushery d []
- = return (unitOL (PACK con n_arg_words))
- where
- n_arg_words = trunc16 $ d - orig_d
+ -- The args are initially in reverse order, but mkVirtHeapOffsets
+ -- expects them to be left-to-right.
+ let non_voids =
+ [ NonVoid (prim_rep, arg)
+ | arg <- reverse args_r_to_l
+ , let prim_rep = atomPrimRep arg
+ , not (isVoidRep prim_rep)
+ ]
+ is_thunk = False
+ (_, _, args_offsets) = mkVirtHeapOffsets dflags is_thunk non_voids
+
+ do_pushery !d ((arg, _) : args) = do
+ (push, arg_bytes) <- pushAtom d p (fromNonVoid arg)
+ more_push_code <- do_pushery (d + arg_bytes) args
+ return (push `appOL` more_push_code)
+ do_pushery !d [] = do
+ let !n_arg_words = trunc16W $ bytesToWords dflags (d - orig_d)
+ return (unitOL (PACK con n_arg_words))
+
+ -- Push on the stack in the reverse order.
+ do_pushery orig_d (reverse args_offsets)
-- -----------------------------------------------------------------------------
@@ -762,39 +818,41 @@ mkConAppCode orig_d _ p con args_r_to_l
-- returned, even if it is a pointed type. We always just return.
unboxedTupleReturn
- :: Word -> Sequel -> BCEnv
- -> AnnExpr' Id DVarSet -> BcM BCInstrList
+ :: StackDepth -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
unboxedTupleReturn d s p arg = returnUnboxedAtom d s p arg (atomRep arg)
-- -----------------------------------------------------------------------------
-- Generate code for a tail-call
doTailCall
- :: Word -> Sequel -> BCEnv
- -> Id -> [AnnExpr' Id DVarSet]
- -> BcM BCInstrList
-doTailCall init_d s p fn args
- = do_pushes init_d args (map atomRep args)
+ :: StackDepth
+ -> Sequel
+ -> BCEnv
+ -> Id
+ -> [AnnExpr' Id DVarSet]
+ -> BcM BCInstrList
+doTailCall init_d s p fn args = do_pushes init_d args (map atomRep args)
where
- do_pushes d [] reps = do
+ do_pushes !d [] reps = do
ASSERT( null reps ) return ()
(push_fn, sz) <- pushAtom d p (AnnVar fn)
- ASSERT( sz == 1 ) return ()
- return (push_fn `appOL` (
- mkSLIDE (trunc16 $ d - init_d + 1) (init_d - s) `appOL`
- unitOL ENTER))
- do_pushes d args reps = do
+ dflags <- getDynFlags
+ ASSERT( sz == wordSize dflags ) return ()
+ let slide = mkSlideB dflags (d - init_d + wordSize dflags) (init_d - s)
+ return (push_fn `appOL` (slide `appOL` unitOL ENTER))
+ do_pushes !d args reps = do
let (push_apply, n, rest_of_reps) = findPushSeq reps
(these_args, rest_of_args) = splitAt n args
(next_d, push_code) <- push_seq d these_args
- instrs <- do_pushes (next_d + 1) rest_of_args rest_of_reps
+ dflags <- getDynFlags
+ instrs <- do_pushes (next_d + wordSize dflags) rest_of_args rest_of_reps
-- ^^^ for the PUSH_APPLY_ instruction
return (push_code `appOL` (push_apply `consOL` instrs))
push_seq d [] = return (d, nilOL)
push_seq d (arg:args) = do
(push_code, sz) <- pushAtom d p arg
- (final_d, more_push_code) <- push_seq (d + fromIntegral sz) args
+ (final_d, more_push_code) <- push_seq (d + sz) args
return (final_d, push_code `appOL` more_push_code)
-- v. similar to CgStackery.findMatch, ToDo: merge
@@ -827,10 +885,16 @@ findPushSeq _
-- -----------------------------------------------------------------------------
-- Case expressions
-doCase :: Word -> Sequel -> BCEnv
- -> AnnExpr Id DVarSet -> Id -> [AnnAlt Id DVarSet]
- -> Maybe Id -- Just x <=> is an unboxed tuple case with scrut binder, don't enter the result
- -> BcM BCInstrList
+doCase
+ :: StackDepth
+ -> Sequel
+ -> BCEnv
+ -> AnnExpr Id DVarSet
+ -> Id
+ -> [AnnAlt Id DVarSet]
+ -> Maybe Id -- Just x <=> is an unboxed tuple case with scrut binder,
+ -- don't enter the result
+ -> BcM BCInstrList
doCase d s p (_,scrut) bndr alts is_unboxed_tuple
| typePrimRep (idType bndr) `lengthExceeds` 1
= multiValException
@@ -846,30 +910,31 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
-- underneath it is the pointer to the alt_code BCO.
-- When an alt is entered, it assumes the returned value is
-- on top of the itbl.
- ret_frame_sizeW :: Word
- ret_frame_sizeW = 2
+ ret_frame_size_b :: StackDepth
+ ret_frame_size_b = 2 * wordSize dflags
-- The extra frame we push to save/restor the CCCS when profiling
- save_ccs_sizeW | profiling = 2
- | otherwise = 0
+ save_ccs_size_b | profiling = 2 * wordSize dflags
+ | otherwise = 0
-- An unlifted value gets an extra info table pushed on top
-- when it is returned.
- unlifted_itbl_sizeW :: Word
- unlifted_itbl_sizeW | isAlgCase = 0
- | otherwise = 1
+ unlifted_itbl_size_b :: StackDepth
+ unlifted_itbl_size_b | isAlgCase = 0
+ | otherwise = wordSize dflags
-- depth of stack after the return value has been pushed
- d_bndr = d + ret_frame_sizeW + fromIntegral (idSizeW dflags bndr)
+ d_bndr = d + ret_frame_size_b + idSizeB dflags bndr
-- depth of stack after the extra info table for an unboxed return
-- has been pushed, if any. This is the stack depth at the
-- continuation.
- d_alts = d_bndr + unlifted_itbl_sizeW
+ d_alts = d_bndr + unlifted_itbl_size_b
-- Env in which to compile the alts, not including
-- any vars bound by the alts themselves
p_alts0 = Map.insert bndr d_bndr p
+
p_alts = case is_unboxed_tuple of
Just ubx_bndr -> Map.insert ubx_bndr d_bndr p_alts0
Nothing -> p_alts0
@@ -889,21 +954,25 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
return (my_discr alt, rhs_code)
-- algebraic alt with some binders
| otherwise =
- let
- (ptrs,nptrs) = partition (isFollowableArg.bcIdArgRep) real_bndrs
- ptr_sizes = map (fromIntegral . idSizeW dflags) ptrs
- nptrs_sizes = map (fromIntegral . idSizeW dflags) nptrs
- bind_sizes = ptr_sizes ++ nptrs_sizes
- size = sum ptr_sizes + sum nptrs_sizes
- -- the UNPACK instruction unpacks in reverse order...
+ let (tot_wds, _ptrs_wds, args_offsets) =
+ mkVirtConstrOffsets dflags
+ [ NonVoid (bcIdPrimRep id, id)
+ | NonVoid id <- nonVoidIds real_bndrs
+ ]
+ size = WordOff tot_wds
+
+ stack_bot = d_alts + wordsToBytes dflags size
+
+ -- convert offsets from Sp into offsets into the virtual stack
p' = Map.insertList
- (zip (reverse (ptrs ++ nptrs))
- (mkStackOffsets d_alts (reverse bind_sizes)))
+ [ (arg, stack_bot + wordSize dflags - ByteOff offset)
+ | (NonVoid arg, offset) <- args_offsets ]
p_alts
in do
MASSERT(isAlgCase)
- rhs_code <- schemeE (d_alts + size) s p' rhs
- return (my_discr alt, unitOL (UNPACK (trunc16 size)) `appOL` rhs_code)
+ rhs_code <- schemeE stack_bot s p' rhs
+ return (my_discr alt,
+ unitOL (UNPACK (trunc16W size)) `appOL` rhs_code)
where
real_bndrs = filterOut isTyVar bndrs
@@ -942,7 +1011,7 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
-- really want a bitmap up to depth (d-s). This affects compilation of
-- case-of-case expressions, which is the only time we can be compiling a
-- case expression with s /= 0.
- bitmap_size = trunc16 $ d-s
+ bitmap_size = trunc16W $ bytesToWords dflags (d - s)
bitmap_size' :: Int
bitmap_size' = fromIntegral bitmap_size
bitmap = intsToReverseBitmap dflags bitmap_size'{-size-}
@@ -954,7 +1023,7 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
rel_slots = nub $ map fromIntegral $ concat (map spread binds)
spread (id, offset) | isFollowableArg (bcIdArgRep id) = [ rel_offset ]
| otherwise = []
- where rel_offset = trunc16 $ d - fromIntegral offset
+ where rel_offset = trunc16W $ bytesToWords dflags (d - offset)
alt_stuff <- mapM codeAlt alts
alt_final <- mkMultiBranch maybe_ncons alt_stuff
@@ -966,8 +1035,8 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
-- trace ("case: bndr = " ++ showSDocDebug (ppr bndr) ++ "\ndepth = " ++ show d ++ "\nenv = \n" ++ showSDocDebug (ppBCEnv p) ++
-- "\n bitmap = " ++ show bitmap) $ do
- scrut_code <- schemeE (d + ret_frame_sizeW + save_ccs_sizeW)
- (d + ret_frame_sizeW + save_ccs_sizeW)
+ scrut_code <- schemeE (d + ret_frame_size_b + save_ccs_size_b)
+ (d + ret_frame_size_b + save_ccs_size_b)
p scrut
alt_bco' <- emitBc alt_bco
let push_alts
@@ -985,27 +1054,30 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple
-- (machine) code for the ccall, and create bytecodes to call that and
-- then return in the right way.
-generateCCall :: Word -> Sequel -- stack and sequel depths
- -> BCEnv
- -> CCallSpec -- where to call
- -> Id -- of target, for type info
- -> [AnnExpr' Id DVarSet] -- args (atoms)
- -> BcM BCInstrList
-
+generateCCall
+ :: StackDepth
+ -> Sequel
+ -> BCEnv
+ -> CCallSpec -- where to call
+ -> Id -- of target, for type info
+ -> [AnnExpr' Id DVarSet] -- args (atoms)
+ -> BcM BCInstrList
generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
= do
dflags <- getDynFlags
let
-- useful constants
- addr_sizeW :: Word16
- addr_sizeW = fromIntegral (argRepSizeW dflags N)
+ addr_size_b :: ByteOff
+ addr_size_b = wordSize dflags
-- Get the args on the stack, with tags and suitably
-- dereferenced for the CCall. For each arg, return the
-- depth to the first word of the bits for that arg, and the
-- ArgRep of what was actually pushed.
+ pargs
+ :: ByteOff -> [AnnExpr' Id DVarSet] -> BcM [(BCInstrList, PrimRep)]
pargs _ [] = return []
pargs d (a:az)
= let arg_ty = unwrapType (exprType (deAnnotate' a))
@@ -1015,31 +1087,35 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
-- contains.
Just t
| t == arrayPrimTyCon || t == mutableArrayPrimTyCon
- -> do rest <- pargs (d + fromIntegral addr_sizeW) az
+ -> do rest <- pargs (d + addr_size_b) az
code <- parg_ArrayishRep (fromIntegral (arrPtrsHdrSize dflags)) d p a
return ((code,AddrRep):rest)
| t == smallArrayPrimTyCon || t == smallMutableArrayPrimTyCon
- -> do rest <- pargs (d + fromIntegral addr_sizeW) az
+ -> do rest <- pargs (d + addr_size_b) az
code <- parg_ArrayishRep (fromIntegral (smallArrPtrsHdrSize dflags)) d p a
return ((code,AddrRep):rest)
| t == byteArrayPrimTyCon || t == mutableByteArrayPrimTyCon
- -> do rest <- pargs (d + fromIntegral addr_sizeW) az
+ -> do rest <- pargs (d + addr_size_b) az
code <- parg_ArrayishRep (fromIntegral (arrWordsHdrSize dflags)) d p a
return ((code,AddrRep):rest)
-- Default case: push taggedly, but otherwise intact.
_
-> do (code_a, sz_a) <- pushAtom d p a
- rest <- pargs (d + fromIntegral sz_a) az
+ rest <- pargs (d + sz_a) az
return ((code_a, atomPrimRep a) : rest)
-- Do magic for Ptr/Byte arrays. Push a ptr to the array on
-- the stack but then advance it over the headers, so as to
-- point to the payload.
- parg_ArrayishRep :: Word16 -> Word -> BCEnv -> AnnExpr' Id DVarSet
- -> BcM BCInstrList
+ parg_ArrayishRep
+ :: Word16
+ -> StackDepth
+ -> BCEnv
+ -> AnnExpr' Id DVarSet
+ -> BcM BCInstrList
parg_ArrayishRep hdrSize d p a
= do (push_fo, _) <- pushAtom d p a
-- The ptr points at the header. Advance it over the
@@ -1049,10 +1125,11 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
code_n_reps <- pargs d0 args_r_to_l
let
(pushs_arg, a_reps_pushed_r_to_l) = unzip code_n_reps
- a_reps_sizeW = fromIntegral (sum (map (primRepSizeW dflags) a_reps_pushed_r_to_l))
+ a_reps_sizeW =
+ WordOff (sum (map (primRepSizeW dflags) a_reps_pushed_r_to_l))
push_args = concatOL pushs_arg
- d_after_args = d0 + a_reps_sizeW
+ !d_after_args = d0 + wordsToBytes dflags a_reps_sizeW
a_reps_pushed_RAW
| null a_reps_pushed_r_to_l || head a_reps_pushed_r_to_l /= VoidRep
= panic "ByteCodeGen.generateCCall: missing or invalid World token?"
@@ -1104,6 +1181,7 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
void marshall_code ( StgWord* ptr_to_top_of_stack )
-}
-- resolve static address
+ maybe_static_target :: Maybe Literal
maybe_static_target =
case target of
DynamicTarget -> Nothing
@@ -1132,18 +1210,18 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
-- push the Addr#
(push_Addr, d_after_Addr)
| Just machlabel <- maybe_static_target
- = (toOL [PUSH_UBX machlabel addr_sizeW],
- d_after_args + fromIntegral addr_sizeW)
+ = (toOL [PUSH_UBX machlabel 1], d_after_args + addr_size_b)
| otherwise -- is already on the stack
= (nilOL, d_after_args)
-- Push the return placeholder. For a call returning nothing,
-- this is a V (tag).
- r_sizeW = fromIntegral (primRepSizeW dflags r_rep)
- d_after_r = d_after_Addr + fromIntegral r_sizeW
- push_r = (if returns_void
- then nilOL
- else unitOL (PUSH_UBX (mkDummyLiteral r_rep) r_sizeW))
+ r_sizeW = WordOff (primRepSizeW dflags r_rep)
+ d_after_r = d_after_Addr + wordsToBytes dflags r_sizeW
+ push_r =
+ if returns_void
+ then nilOL
+ else unitOL (PUSH_UBX (mkDummyLiteral r_rep) (trunc16W r_sizeW))
-- generate the marshalling code we're going to call
@@ -1151,7 +1229,7 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
-- instruction needs to describe the chunk of stack containing
-- the ccall args to the GC, so it needs to know how large it
-- is. See comment in Interpreter.c with the CCALL instruction.
- stk_offset = trunc16 $ d_after_r - s
+ stk_offset = trunc16W $ bytesToWords dflags (d_after_r - s)
conv = case cconv of
CCallConv -> FFICCall
@@ -1178,7 +1256,8 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
PlayRisky -> 0x2
-- slide and return
- wrapup = mkSLIDE r_sizeW (d_after_r - fromIntegral r_sizeW - s)
+ d_after_r_min_s = bytesToWords dflags (d_after_r - s)
+ wrapup = mkSlideW (trunc16W r_sizeW) (d_after_r_min_s - r_sizeW)
`snocOL` RETURN_UBX (toArgRep r_rep)
--trace (show (arg1_offW, args_offW , (map argRepSizeW a_reps) )) $
return (
@@ -1311,18 +1390,25 @@ a 1-word null. See Trac #8383.
-}
-implement_tagToId :: Word -> Sequel -> BCEnv
- -> AnnExpr' Id DVarSet -> [Name] -> BcM BCInstrList
+implement_tagToId
+ :: StackDepth
+ -> Sequel
+ -> BCEnv
+ -> AnnExpr' Id DVarSet
+ -> [Name]
+ -> BcM BCInstrList
-- See Note [Implementing tagToEnum#]
implement_tagToId d s p arg names
= ASSERT( notNull names )
- do (push_arg, arg_words) <- pushAtom d p arg
+ do (push_arg, arg_bytes) <- pushAtom d p arg
labels <- getLabelsBc (genericLength names)
label_fail <- getLabelBc
label_exit <- getLabelBc
+ dflags <- getDynFlags
let infos = zip4 labels (tail labels ++ [label_fail])
[0 ..] names
steps = map (mkStep label_exit) infos
+ slide_ws = bytesToWords dflags (d - s + arg_bytes)
return (push_arg
`appOL` unitOL (PUSH_UBX MachNullAddr 1)
@@ -1330,10 +1416,10 @@ implement_tagToId d s p arg names
`appOL` concatOL steps
`appOL` toOL [ LABEL label_fail, CASEFAIL,
LABEL label_exit ]
- `appOL` mkSLIDE 1 (d - s + fromIntegral arg_words + 1)
+ `appOL` mkSlideW 1 (slide_ws + 1)
-- "+1" to account for bogus word
-- (see Note [Implementing tagToEnum#])
- `appOL` unitOL ENTER)
+ `appOL` unitOL ENTER)
where
mkStep l_exit (my_label, next_label, n, name_for_n)
= toOL [LABEL my_label,
@@ -1355,8 +1441,8 @@ implement_tagToId d s p arg names
-- to 5 and not to 4. Stack locations are numbered from zero, so a
-- depth 6 stack has valid words 0 .. 5.
-pushAtom :: Word -> BCEnv -> AnnExpr' Id DVarSet -> BcM (BCInstrList, Word16)
-
+pushAtom
+ :: StackDepth -> BCEnv -> AnnExpr' Id DVarSet -> BcM (BCInstrList, ByteOff)
pushAtom d p e
| Just e' <- bcView e
= pushAtom d p e'
@@ -1370,22 +1456,26 @@ pushAtom _ _ (AnnCoercion {}) -- Coercions are zero-width things,
pushAtom d p (AnnCase (_, a) _ _ []) -- trac #12128
= pushAtom d p a
-pushAtom d p (AnnVar v)
- | [] <- typePrimRep (idType v)
+pushAtom d p (AnnVar var)
+ | [] <- typePrimRep (idType var)
= return (nilOL, 0)
- | isFCallId v
- = pprPanic "pushAtom: shouldn't get an FCallId here" (ppr v)
+ | isFCallId var
+ = pprPanic "pushAtom: shouldn't get an FCallId here" (ppr var)
- | Just primop <- isPrimOpId_maybe v
- = return (unitOL (PUSH_PRIMOP primop), 1)
+ | Just primop <- isPrimOpId_maybe var
+ = do
+ dflags <-getDynFlags
+ return (unitOL (PUSH_PRIMOP primop), wordSize dflags)
- | Just d_v <- lookupBCEnv_maybe v p -- v is a local variable
+ | Just d_v <- lookupBCEnv_maybe var p -- var is a local variable
= do dflags <- getDynFlags
- let sz :: Word16
- sz = fromIntegral (idSizeW dflags v)
- l = trunc16 $ d - d_v + fromIntegral sz - 1
- return (toOL (genericReplicate sz (PUSH_L l)), sz)
+ -- Currently this code assumes that @szb@ is a multiple of full words.
+ -- It'll need to change to support, e.g., sub-word constructor fields.
+ let !szb = idSizeB dflags var
+ !szw = bytesToWords dflags szb -- szb is a multiple of words
+ l = trunc16W $ bytesToWords dflags (d - d_v) + szw - 1
+ return (toOL (genericReplicate szw (PUSH_L l)), szb)
-- d - d_v offset from TOS to the first slot of the object
--
-- d - d_v + sz - 1 offset from the TOS of the last slot of the object
@@ -1393,25 +1483,24 @@ pushAtom d p (AnnVar v)
-- Having found the last slot, we proceed to copy the right number of
-- slots on to the top of the stack.
- | otherwise -- v must be a global variable
+ | otherwise -- var must be a global variable
= do topStrings <- getTopStrings
- case lookupVarEnv topStrings v of
+ case lookupVarEnv topStrings var of
Just ptr -> pushAtom d p $ AnnLit $ MachWord $ fromIntegral $
ptrToWordPtr $ fromRemotePtr ptr
Nothing -> do
dflags <- getDynFlags
- let sz :: Word16
- sz = fromIntegral (idSizeW dflags v)
- MASSERT(sz == 1)
- return (unitOL (PUSH_G (getName v)), sz)
+ let sz = idSizeB dflags var
+ MASSERT( sz == wordSize dflags )
+ return (unitOL (PUSH_G (getName var)), sz)
pushAtom _ _ (AnnLit lit) = do
dflags <- getDynFlags
let code rep
- = let size_host_words = fromIntegral (argRepSizeW dflags rep)
- in return (unitOL (PUSH_UBX lit size_host_words),
- size_host_words)
+ = let size_words = WordOff (argRepSizeW dflags rep)
+ in return (unitOL (PUSH_UBX lit (trunc16W size_words)),
+ wordsToBytes dflags size_words)
case lit of
MachLabel _ _ _ -> code N
@@ -1572,11 +1661,14 @@ instance Outputable Discr where
ppr NoDiscr = text "DEF"
-lookupBCEnv_maybe :: Id -> BCEnv -> Maybe Word
+lookupBCEnv_maybe :: Id -> BCEnv -> Maybe ByteOff
lookupBCEnv_maybe = Map.lookup
-idSizeW :: DynFlags -> Id -> Int
-idSizeW dflags = argRepSizeW dflags . bcIdArgRep
+idSizeW :: DynFlags -> Id -> WordOff
+idSizeW dflags = WordOff . argRepSizeW dflags . bcIdArgRep
+
+idSizeB :: DynFlags -> Id -> ByteOff
+idSizeB dflags = wordsToBytes dflags . idSizeW dflags
bcIdArgRep :: Id -> ArgRep
bcIdArgRep = toArgRep . bcIdPrimRep
@@ -1618,19 +1710,25 @@ unsupportedCConvException = throwGhcException (ProgramError
("Error: bytecode compiler can't handle some foreign calling conventions\n"++
" Workaround: use -fobject-code, or compile this module to .o separately."))
-mkSLIDE :: Word16 -> Word -> OrdList BCInstr
-mkSLIDE n d
- -- if the amount to slide doesn't fit in a word,
- -- generate multiple slide instructions
- | d > fromIntegral limit
- = SLIDE n limit `consOL` mkSLIDE n (d - fromIntegral limit)
- | d == 0
+mkSlideB :: DynFlags -> ByteOff -> ByteOff -> OrdList BCInstr
+mkSlideB dflags !nb !db = mkSlideW n d
+ where
+ !n = trunc16W $ bytesToWords dflags nb
+ !d = bytesToWords dflags db
+
+mkSlideW :: Word16 -> WordOff -> OrdList BCInstr
+mkSlideW !n !ws
+ | ws > fromIntegral limit
+ -- If the amount to slide doesn't fit in a Word16, generate multiple slide
+ -- instructions
+ = SLIDE n limit `consOL` mkSlideW n (ws - fromIntegral limit)
+ | ws == 0
= nilOL
| otherwise
- = if d == 0 then nilOL else unitOL (SLIDE n $ fromIntegral d)
- where
- limit :: Word16
- limit = maxBound
+ = unitOL (SLIDE n $ fromIntegral ws)
+ where
+ limit :: Word16
+ limit = maxBound
splitApp :: AnnExpr' Var ann -> (AnnExpr' Var ann, [AnnExpr' Var ann])
-- The arguments are returned in *right-to-left* order
@@ -1676,14 +1774,11 @@ atomPrimRep other = pprPanic "atomPrimRep" (ppr (deAnnotate' other))
atomRep :: AnnExpr' Id ann -> ArgRep
atomRep e = toArgRep (atomPrimRep e)
-isPtrAtom :: AnnExpr' Id ann -> Bool
-isPtrAtom e = isFollowableArg (atomRep e)
-
--- | Let szsw be the sizes in words of some items pushed onto the stack, which
+-- | Let szsw be the sizes in bytes of some items pushed onto the stack, which
-- has initial depth @original_depth@. Return the values which the stack
-- environment should map these items to.
-mkStackOffsets :: Word -> [Word] -> [Word]
-mkStackOffsets original_depth szsw = tail (scanl' (+) original_depth szsw)
+mkStackOffsets :: ByteOff -> [ByteOff] -> [ByteOff]
+mkStackOffsets original_depth szsb = tail (scanl' (+) original_depth szsb)
typeArgRep :: Type -> ArgRep
typeArgRep = toArgRep . typePrimRep1
diff --git a/compiler/ghci/ByteCodeInstr.hs b/compiler/ghci/ByteCodeInstr.hs
index 525280290f..fabde4e52d 100644
--- a/compiler/ghci/ByteCodeInstr.hs
+++ b/compiler/ghci/ByteCodeInstr.hs
@@ -30,11 +30,7 @@ import PrimOp
import SMRep
import Data.Word
-#if MIN_VERSION_base(4,9,0)
import GHC.Stack.CCS (CostCentre)
-#else
-import GHC.Stack (CostCentre)
-#endif
-- ----------------------------------------------------------------------------
-- Bytecode instructions
diff --git a/compiler/ghci/ByteCodeTypes.hs b/compiler/ghci/ByteCodeTypes.hs
index 1318a47ef4..4b78600f70 100644
--- a/compiler/ghci/ByteCodeTypes.hs
+++ b/compiler/ghci/ByteCodeTypes.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, MagicHash, RecordWildCards, GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MagicHash, RecordWildCards, GeneralizedNewtypeDeriving #-}
--
-- (c) The University of Glasgow 2002-2006
--
@@ -34,11 +34,7 @@ import Data.Array.Base ( UArray(..) )
import Data.ByteString (ByteString)
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
-#if MIN_VERSION_base(4,9,0)
import GHC.Stack.CCS
-#else
-import GHC.Stack as GHC.Stack.CCS
-#endif
-- -----------------------------------------------------------------------------
-- Compiled Byte Code
diff --git a/compiler/ghci/GHCi.hsc b/compiler/ghci/GHCi.hs
index d2f2f5a833..403cffdc70 100644
--- a/compiler/ghci/GHCi.hsc
+++ b/compiler/ghci/GHCi.hs
@@ -75,23 +75,13 @@ import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as LB
import Data.IORef
import Foreign hiding (void)
-#if MIN_VERSION_base(4,9,0)
import GHC.Stack.CCS (CostCentre,CostCentreStack)
-#else
-import GHC.Stack (CostCentre,CostCentreStack)
-#endif
import System.Exit
import Data.Maybe
import GHC.IO.Handle.Types (Handle)
#if defined(mingw32_HOST_OS)
import Foreign.C
import GHC.IO.Handle.FD (fdToHandle)
-#if !MIN_VERSION_process(1,4,2)
-import System.Posix.Internals
-import Foreign.Marshal.Array
-import Foreign.C.Error
-import Foreign.Storable
-#endif
#else
import System.Posix as Posix
#endif
@@ -545,22 +535,6 @@ runWithPipes createProc prog opts = do
where mkHandle :: CInt -> IO Handle
mkHandle fd = (fdToHandle fd) `onException` (c__close fd)
-#if !MIN_VERSION_process(1,4,2)
--- This #include and the _O_BINARY below are the only reason this is hsc,
--- so we can remove that once we can depend on process 1.4.2
-#include <fcntl.h>
-
-createPipeFd :: IO (FD, FD)
-createPipeFd = do
- allocaArray 2 $ \ pfds -> do
- throwErrnoIfMinus1_ "_pipe" $ c__pipe pfds 2 (#const _O_BINARY)
- readfd <- peek pfds
- writefd <- peekElemOff pfds 1
- return (readfd, writefd)
-
-foreign import ccall "io.h _pipe" c__pipe ::
- Ptr CInt -> CUInt -> CInt -> IO CInt
-#endif
#else
runWithPipes createProc prog opts = do
(rfd1, wfd1) <- Posix.createPipe -- we read on rfd1
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs
index aee7684157..d174cc089d 100644
--- a/compiler/ghci/Linker.hs
+++ b/compiler/ghci/Linker.hs
@@ -722,15 +722,6 @@ getLinkDeps hsc_env hpt pls replace_osuf span mods
adjust_ul _ (DotA fp) = panic ("adjust_ul DotA " ++ show fp)
adjust_ul _ (DotDLL fp) = panic ("adjust_ul DotDLL " ++ show fp)
adjust_ul _ l@(BCOs {}) = return l
-#if !MIN_VERSION_filepath(1,4,1)
- stripExtension :: String -> FilePath -> Maybe FilePath
- stripExtension [] path = Just path
- stripExtension ext@(x:_) path = stripSuffix dotExt path
- where dotExt = if isExtSeparator x then ext else '.':ext
-
- stripSuffix :: Eq a => [a] -> [a] -> Maybe [a]
- stripSuffix xs ys = fmap reverse $ stripPrefix (reverse xs) (reverse ys)
-#endif
diff --git a/compiler/ghci/RtClosureInspect.hs b/compiler/ghci/RtClosureInspect.hs
index 785513b3b6..263aeba7e9 100644
--- a/compiler/ghci/RtClosureInspect.hs
+++ b/compiler/ghci/RtClosureInspect.hs
@@ -637,7 +637,7 @@ addConstraint actual expected = do
discardResult $
captureConstraints $
do { (ty1, ty2) <- congruenceNewtypes actual expected
- ; unifyType noThing ty1 ty2 }
+ ; unifyType Nothing ty1 ty2 }
-- TOMDO: what about the coercion?
-- we should consider family instances
@@ -1186,7 +1186,7 @@ congruenceNewtypes lhs rhs = go lhs rhs >>= \rhs' -> return (lhs,rhs')
(_, vars) <- instTyVars (tyConTyVars new_tycon)
let ty' = mkTyConApp new_tycon (mkTyVarTys vars)
rep_ty = unwrapType ty'
- _ <- liftTcM (unifyType noThing ty rep_ty)
+ _ <- liftTcM (unifyType Nothing ty rep_ty)
-- assumes that reptype doesn't ^^^^ touch tyconApp args
return ty'
diff --git a/compiler/hsSyn/HsBinds.hs b/compiler/hsSyn/HsBinds.hs
index f2b562d2d1..20ee4d2a5d 100644
--- a/compiler/hsSyn/HsBinds.hs
+++ b/compiler/hsSyn/HsBinds.hs
@@ -278,7 +278,7 @@ pattern
--
-- The pattern is never a simple variable;
-- That case is done by FunBind.
- -- See Note [Varieties of binding pattern matches] for details about the
+ -- See Note [FunBind vs PatBind] for details about the
-- relationship between FunBind and PatBind.
--
@@ -315,22 +315,9 @@ pattern
-- Note [Typechecking plan for instance declarations]
(LHsBinds pass) ->
-- ^ Typechecked user bindings
+ Bool -> -- See Note [The abs_sig field of AbsBinds]
HsBindLR pass pass'
-- ^ Abstraction Bindings
-pattern
- AbsBindsSig ::
- -- Simpler form of AbsBinds, used with a type sig
- -- in tcPolyCheck. Produces simpler desugaring and
- -- is necessary to avoid #11405, comment:3.
- ([TyVar]) ->
- ([EvVar]) ->
- (IdP pass) -> -- like abe_poly
- (TcSpecPrags) ->
- (TcEvBinds) -> -- no list needed here
- (LHsBind pass) -> -- always only one, and it's always a
- -- FunBind
- HsBindLR pass pass'
- -- | ^ Abstraction Bindings Signature
pattern
PatSynBind ::
@@ -369,15 +356,11 @@ pattern
= AST.VarBind NoFieldExt var_id var_rhs var_inline
pattern
AbsBinds { abs_tvsa, abs_ev_varsa, abs_exports, abs_ev_binds,
- abs_binds } -- abs_tvs --> abs_tvsa
- = AST.NewBindLR
- (NAbsBinds abs_tvsa abs_ev_varsa abs_exports abs_ev_binds abs_binds)
-pattern
- AbsBindsSig { abs_tvs, abs_ev_vars, abs_sig_export, abs_sig_prags,
- abs_sig_ev_bind, abs_sig_bind }
+ abs_binds, abs_sig } -- abs_tvs --> abs_tvsa
= AST.NewBindLR
- (NAbsBindsSig abs_tvs abs_ev_vars abs_sig_export abs_sig_prags
- abs_sig_ev_bind abs_sig_bind)
+ (NAbsBinds abs_tvsa abs_ev_varsa abs_exports abs_ev_binds abs_binds
+ abs_sig)
+
pattern
PatSynBind a
= AST.PatSynBind NoFieldExt a
@@ -393,7 +376,6 @@ get_bind_fvs _ = error "field selector applied to a wrong constructor"
PatBind,
VarBind,
AbsBinds,
- AbsBindsSig,
PatSynBind
#-}
@@ -420,14 +402,8 @@ data NewHsBindLR pass pass'
[ABExport pass]
[TcEvBinds]
(LHsBinds pass)
+ Bool
- | NAbsBindsSig
- [TyVar]
- [EvVar]
- (IdP pass)
- TcSpecPrags
- TcEvBinds
- (LHsBind pass)
-- | Located Haskell Binding with separate Left and Right identifier types
type
@@ -438,7 +414,7 @@ type
-- | Abtraction Bindings Export
data ABExport p
- = ABE { abe_poly :: IdP p -- ^ Any INLINE pragmas is attached to this Id
+ = ABE { abe_poly :: IdP p -- ^ Any INLINE pragma is attached to this Id
, abe_mono :: IdP p
, abe_wrap :: HsWrapper -- ^ See Note [ABExport wrapper]
-- Shape: (forall abs_tvs. abs_ev_vars => abe_mono) ~ abe_poly
@@ -1281,21 +1257,6 @@ ppr_monobind (AbsBinds { abs_tvsa = tyvars, abs_ev_varsa = dictvars
, text "Evidence:" <+> ppr ev_binds ]
else
pprLHsBinds val_binds
-ppr_monobind (AbsBindsSig { abs_tvs = tyvars
- , abs_ev_vars = dictvars
- , abs_sig_export = poly_id
- , abs_sig_ev_bind = ev_bind
- , abs_sig_bind = bind })
- = sdocWithDynFlags $ \ dflags ->
- if gopt Opt_PrintTypecheckerElaboration dflags then
- hang (text "AbsBindsSig" <+> brackets (interpp'SP tyvars)
- <+> brackets (interpp'SP dictvars))
- 2 $ braces $ vcat
- [ text "Exported type:" <+> pprBndr LetBind poly_id
- , text "Bind:" <+> ppr bind
- , text "Evidence:" <+> ppr ev_bind ]
- else
- ppr bind
instance (OutputableBndrId p) => Outputable (ABExport p) where
ppr (ABE { abe_wrap = wrap, abe_poly = gbl, abe_mono = lcl, abe_prags = prags })
@@ -1449,9 +1410,8 @@ pprMinimalSig (L _ bf) = ppr (fmap unLoc bf)
-- Notes
-- -----------------------------------------------------------------------------
{-
-Note [Varieties of binding pattern matches]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+Note [FunBind vs PatBind]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
The distinction between FunBind and PatBind is a bit subtle. FunBind covers
patterns which resemble function bindings and simple variable bindings.
@@ -1462,12 +1422,17 @@ patterns which resemble function bindings and simple variable bindings.
x `f` y = e -- FunRhs has Infix
The actual patterns and RHSs of a FunBind are encoding in fun_matches.
-The m_ctxt field of Match will be FunRhs and carries two bits of information
-about the match,
+The m_ctxt field of each Match in fun_matches will be FunRhs and carries
+two bits of information about the match,
+
+ * The mc_fixity field on each Match describes the fixity of the
+ function binder in that match. E.g. this is legal:
+ f True False = e1
+ True `f` True = e2
- * the mc_strictness field describes whether the match is decorated with a bang
- (e.g. `!x = e`)
- * the mc_fixity field describes the fixity of the function binder
+ * The mc_strictness field is used /only/ for nullary FunBinds: ones
+ with one Match, which has no pats. For these, it describes whether
+ the match is decorated with a bang (e.g. `!x = e`).
By contrast, PatBind represents data constructor patterns, as well as a few
other interesting cases. Namely,
@@ -1618,6 +1583,52 @@ bindings only when
lacks a user type signature
* The group forms a strongly connected component
+Note [The abs_sig field of AbsBinds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The abs_sig field supports a couple of special cases for bindings.
+Consider
+
+ x :: Num a => (# a, a #)
+ x = (# 3, 4 #)
+
+The general desugaring for AbsBinds would give
+
+ x = /\a. \ ($dNum :: Num a) ->
+ letrec xm = (# fromInteger $dNum 3, fromInteger $dNum 4 #) in
+ xm
+
+But that has an illegal let-binding for an unboxed tuple. In this
+case we'd prefer to generate the (more direct)
+
+ x = /\ a. \ ($dNum :: Num a) ->
+ (# fromInteger $dNum 3, fromInteger $dNum 4 #)
+
+A similar thing happens with representation-polymorphic defns
+(Trac #11405):
+
+ undef :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
+ undef = error "undef"
+
+Again, the vanilla desugaring gives a local let-binding for a
+representation-polymorphic (undefm :: a), which is illegal. But
+again we can desugar without a let:
+
+ undef = /\ a. \ (d:HasCallStack) -> error a d "undef"
+
+The abs_sig field supports this direct desugaring, with no local
+let-bining. When abs_sig = True
+
+ * the abs_binds is single FunBind
+
+ * the abs_exports is a singleton
+
+ * we have a complete type sig for binder
+ and hence the abs_binds is non-recursive
+ (it binds the mono_id but refers to the poly_id
+
+These properties are exploited in DsBinds.dsAbsBinds to
+generate code without a let-binding.
+
Note [ABExport wrapper]
~~~~~~~~~~~~~~~~~~~~~~~
Consider
diff --git a/compiler/hsSyn/HsDecls.hs b/compiler/hsSyn/HsDecls.hs
index 5598207a4c..e9e888a76b 100644
--- a/compiler/hsSyn/HsDecls.hs
+++ b/compiler/hsSyn/HsDecls.hs
@@ -2826,7 +2826,7 @@ ppr_fam_inst_eqn (L _ (TyFamEqn { tfe_tycon = tycon
, tfe_pats = pats
, tfe_fixity = fixity
, tfe_rhs = rhs }))
- = pp_fam_inst_lhs tycon pats fixity [] <+> equals <+> ppr rhs
+ = pprFamInstLHS tycon pats fixity [] Nothing <+> equals <+> ppr rhs
ppr_fam_deflt_eqn :: (SourceTextX pass, OutputableBndrId pass)
=> LTyFamDefltEqn pass -> SDoc
@@ -2850,21 +2850,22 @@ pprDataFamInstDecl top_lvl (DataFamInstDecl { dfid_tycon = tycon
= pp_data_defn pp_hdr defn
where
pp_hdr ctxt = ppr_instance_keyword top_lvl
- <+> pp_fam_inst_lhs tycon pats fixity ctxt
+ <+> pprFamInstLHS tycon pats fixity ctxt (dd_kindSig defn)
pprDataFamInstFlavour :: DataFamInstDecl pass -> SDoc
pprDataFamInstFlavour (DataFamInstDecl { dfid_defn = (HsDataDefn { dd_ND = nd }) })
= ppr nd
-pp_fam_inst_lhs :: (SourceTextX pass, OutputableBndrId pass)
+pprFamInstLHS :: (SourceTextX pass, OutputableBndrId pass)
=> LIdP pass
-> HsTyPats pass
-> LexicalFixity
-> HsContext pass
+ -> Maybe (LHsKind pass)
-> SDoc
-pp_fam_inst_lhs thing (HsIB { hsib_body = typats }) fixity context
+pprFamInstLHS thing (HsIB { hsib_body = typats }) fixity context mb_kind_sig
-- explicit type patterns
- = hsep [ pprHsContext context, pp_pats typats]
+ = hsep [ pprHsContext context, pp_pats typats, pp_kind_sig ]
where
pp_pats (patl:patsr)
| fixity == Infix
@@ -2872,7 +2873,13 @@ pp_fam_inst_lhs thing (HsIB { hsib_body = typats }) fixity context
, hsep (map (pprHsType.unLoc) patsr)]
| otherwise = hsep [ pprPrefixOcc (unLoc thing)
, hsep (map (pprHsType.unLoc) (patl:patsr))]
- pp_pats [] = empty
+ pp_pats [] = pprPrefixOcc (unLoc thing)
+
+ pp_kind_sig
+ | Just k <- mb_kind_sig
+ = dcolon <+> ppr k
+ | otherwise
+ = empty
instance (SourceTextX pass, OutputableBndrId pass)
=> Outputable (ClsInstDecl pass) where
diff --git a/compiler/hsSyn/HsExpr.hs b/compiler/hsSyn/HsExpr.hs
index f6e96dd4c1..fadde4ea0a 100644
--- a/compiler/hsSyn/HsExpr.hs
+++ b/compiler/hsSyn/HsExpr.hs
@@ -2486,7 +2486,7 @@ matchGroupArity (MG { mg_alts = alts })
| otherwise = panic "matchGroupArity"
hsLMatchPats :: LMatch id body -> [LPat id]
-hsLMatchPats (L _ (Match _ pats _ _)) = pats
+hsLMatchPats (L _ (Match { m_pats = pats })) = pats
-- ------------------------------------
diff --git a/compiler/hsSyn/HsLit.hs b/compiler/hsSyn/HsLit.hs
index 9bf5467a00..d2f29ed166 100644
--- a/compiler/hsSyn/HsLit.hs
+++ b/compiler/hsSyn/HsLit.hs
@@ -282,7 +282,7 @@ deriving instance
(DataId x) => Data (HsLit x)
deriving instance
- (DataId p, DataId p) => Data (HsOverLit p)
+ (DataId p) => Data (HsOverLit p)
deriving instance
Data OverLitVal
diff --git a/compiler/hsSyn/HsPat.hs b/compiler/hsSyn/HsPat.hs
index 40a8bbd434..4188b3cd34 100644
--- a/compiler/hsSyn/HsPat.hs
+++ b/compiler/hsSyn/HsPat.hs
@@ -81,7 +81,6 @@ module HsPat
, mkNilPat
, looksLazyPatBind
, isBangedLPat
- , isBangedPatBind
, hsPatNeedsParens
, isIrrefutableHsPat
, collectEvVarsPats
@@ -729,10 +728,6 @@ patterns are treated specially, of course.
The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
-}
-isBangedPatBind :: HsBind p -> Bool
-isBangedPatBind (PatBind {pat_lhs = pat}) = isBangedLPat pat
-isBangedPatBind _ = False
-
isBangedLPat :: LPat p -> Bool
isBangedLPat (L _ (ParPat p)) = isBangedLPat p
isBangedLPat (L _ (BangPat {})) = True
@@ -748,8 +743,6 @@ looksLazyPatBind (PatBind { pat_lhs = p })
= looksLazyLPat p
looksLazyPatBind (AbsBinds { abs_binds = binds })
= anyBag (looksLazyPatBind . unLoc) binds
-looksLazyPatBind (AbsBindsSig { abs_sig_bind = L _ bind })
- = looksLazyPatBind bind
looksLazyPatBind _
= False
diff --git a/compiler/hsSyn/HsUtils.hs b/compiler/hsSyn/HsUtils.hs
index 5f3a94920b..8588f3d4be 100644
--- a/compiler/hsSyn/HsUtils.hs
+++ b/compiler/hsSyn/HsUtils.hs
@@ -72,7 +72,7 @@ module HsUtils(
noRebindableInfo,
-- Collecting binders
- isUnliftedHsBind, isBangedBind,
+ isUnliftedHsBind, isBangedHsBind,
collectLocalBinders, collectHsValBinders, collectHsBindListBinders,
collectHsIdBinders,
@@ -146,7 +146,8 @@ mkSimpleMatch :: HsMatchContext (NameOrRdrName (IdP id))
-> LMatch id (Located (body (GHC id)))
mkSimpleMatch ctxt pats rhs
= L loc $
- Match ctxt pats Nothing (unguardedGRHSs rhs)
+ Match { m_ctxt = ctxt, m_pats = pats, m_type = Nothing
+ , m_grhss = unguardedGRHSs rhs }
where
loc = case pats of
[] -> getLoc rhs
@@ -758,14 +759,18 @@ mk_easy_FunBind loc fun pats expr
-- | Make a prefix, non-strict function 'HsMatchContext'
mkPrefixFunRhs :: Located id -> HsMatchContext id
-mkPrefixFunRhs n = FunRhs n Prefix NoSrcStrict
+mkPrefixFunRhs n = FunRhs { mc_fun = n
+ , mc_fixity = Prefix
+ , mc_strictness = NoSrcStrict }
------------
mkMatch :: HsMatchContext (NameOrRdrName (IdP p)) -> [LPat p] -> LHsExpr p
-> Located (HsLocalBinds p) -> LMatch p (LHsExpr p)
mkMatch ctxt pats expr lbinds
- = noLoc (Match ctxt (map paren pats) Nothing
- (GRHSs (unguardedRHS noSrcSpan expr) lbinds))
+ = noLoc (Match { m_ctxt = ctxt
+ , m_pats = map paren pats
+ , m_type = Nothing
+ , m_grhss = GRHSs (unguardedRHS noSrcSpan expr) lbinds })
where
paren lp@(L l p) | hsPatNeedsParens p = L l (ParPat lp)
| otherwise = lp
@@ -794,49 +799,31 @@ 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 isHsUnliftedBind]
+Note [Unlifted id check in isUnliftedHsBind]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Suppose there is a binding with the type (Num a => (# a, a #)). Is this a
-strict binding that should be disallowed at the top level? At first glance,
-no, because it's a function. But consider how this is desugared via
-AbsBinds:
+The function isUnliftedHsBind is used to complain if we make a top-level
+binding for a variable of unlifted type.
- -- x :: Num a => (# a, a #)
- x = (# 3, 4 #)
+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...
-becomes
+The top-level bindings for f,g are not unlifted (because of the Num a =>),
+but the local, recursive, monomorphic bindings are:
- x = \ $dictNum ->
- let x_mono = (# fromInteger $dictNum 3, fromInteger $dictNum 4 #) in
- x_mono
+ t = /\a \(d:Num a).
+ letrec fm :: (# a, a #) = ...g...
+ gm :: a -> a = ...f...
+ in (fm, gm)
-Note that the inner let is strict. And thus if we have a bunch of mutually
-recursive bindings of this form, we could end up in trouble. This was shown
-up in #9140.
-
-But if there is a type signature on x, everything changes because of the
-desugaring used by AbsBindsSig:
-
- x :: Num a => (# a, a #)
- x = (# 3, 4 #)
-
-becomes
-
- x = \ $dictNum -> (# fromInteger $dictNum 3, fromInteger $dictNum 4 #)
-
-No strictness anymore! The bottom line here is that, for inferred types, we
-care about the strictness of the type after the =>. For checked types
-(AbsBindsSig), we care about the overall strictness.
-
-This matters. If we don't separate out the AbsBindsSig case, then GHC runs into
-a problem when compiling
-
- undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
-
-Looking only after the =>, we cannot tell if this is strict or not. (GHC panics
-if you try.) Looking at the whole type, on the other hand, tells you that this
-is a lifted function type, with no trouble at all.
+Here the binding for 'fm' is illegal. So generally we check the abe_mono types.
+BUT we have a special case when abs_sig is true;
+ see HsBinds Note [The abs_sig field of AbsBinds]
-}
----------------- Bindings --------------------------
@@ -846,27 +833,32 @@ is a lifted function type, with no trouble at all.
-- AbsBinds. See Note [Unlifted id check in isUnliftedHsBind]. For usage
-- information, see Note [Strict binds check] is DsBinds.
isUnliftedHsBind :: HsBind GhcTc -> Bool -- works only over typechecked binds
-isUnliftedHsBind (AbsBindsSig { abs_sig_export = id })
- = isUnliftedType (idType id)
isUnliftedHsBind bind
+ | 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
+ -- If has_sig is True we wil 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 #)
+
+ | otherwise
= any is_unlifted_id (collectHsBindBinders bind)
where
- is_unlifted_id id
- = case tcSplitSigmaTy (idType id) of
- (_, _, tau) -> isUnliftedType tau
- -- For the is_unlifted check, we need to look inside polymorphism
- -- and overloading. E.g. x = (# 1, True #)
- -- would get type forall a. Num a => (# a, Bool #)
- -- and we want to reject that. See Trac #9140
-
--- | Is a binding a strict variable bind (e.g. @!x = ...@)?
-isBangedBind :: HsBind GhcTc -> Bool
-isBangedBind b | isBangedPatBind b = True
-isBangedBind (FunBind {fun_matches = matches})
+ is_unlifted_id id = isUnliftedType (idType id)
+
+-- | Is a binding a strict variable or pattern bind (e.g. @!x = ...@)?
+isBangedHsBind :: HsBind GhcTc -> Bool
+isBangedHsBind (AbsBinds { abs_binds = binds })
+ = anyBag (isBangedHsBind . unLoc) binds
+isBangedHsBind (FunBind {fun_matches = matches})
| [L _ match] <- unLoc $ mg_alts matches
, FunRhs{mc_strictness = SrcStrict} <- m_ctxt match
= True
-isBangedBind _ = False
+isBangedHsBind (PatBind {pat_lhs = pat})
+ = isBangedLPat pat
+isBangedHsBind _
+ = False
collectLocalBinders :: HsLocalBindsLR idL idR -> [IdP idL]
collectLocalBinders (HsValBinds binds) = collectHsIdBinders binds
@@ -909,7 +901,6 @@ collect_bind _ (AbsBinds { abs_exports = dbinds }) acc = map abe_poly dbinds ++
-- I don't think we want the binders from the abe_binds
-- The only time we collect binders from a typechecked
-- binding (hence see AbsBinds) is in zonking in TcHsSyn
-collect_bind _ (AbsBindsSig { abs_sig_export = poly }) acc = poly : acc
collect_bind omitPatSyn (PatSynBind (PSB { psb_id = L _ ps })) acc
| omitPatSyn = acc
| otherwise = ps : acc
diff --git a/compiler/iface/BuildTyCl.hs b/compiler/iface/BuildTyCl.hs
index 76b7793859..a5b724994c 100644
--- a/compiler/iface/BuildTyCl.hs
+++ b/compiler/iface/BuildTyCl.hs
@@ -6,7 +6,7 @@
{-# LANGUAGE CPP #-}
module BuildTyCl (
- buildDataCon, mkDataConUnivTyVarBinders,
+ buildDataCon,
buildPatSyn,
TcMethInfo, buildClass,
mkNewTyConRhs, mkDataTyConRhs,
@@ -119,7 +119,6 @@ buildDataCon :: FamInstEnvs
-- a) makes the worker Id
-- b) makes the wrapper Id if necessary, including
-- allocating its unique (hence monadic)
--- c) Sorts out the TyVarBinders. See mkDataConUnivTyBinders
buildDataCon fam_envs src_name declared_infix prom_info src_bangs impl_bangs field_lbls
univ_tvs ex_tvs eq_spec ctxt arg_tys res_ty rep_tycon
= do { wrap_name <- newImplicitBinder src_name mkDataConWrapperOcc
@@ -165,69 +164,6 @@ mkDataConStupidTheta tycon arg_tys univ_tvs
tyCoVarsOfType pred `intersectVarSet` arg_tyvars
-mkDataConUnivTyVarBinders :: [TyConBinder] -- From the TyCon
- -> [TyVarBinder] -- For the DataCon
--- See Note [Building the TyBinders for a DataCon]
-mkDataConUnivTyVarBinders tc_bndrs
- = map mk_binder tc_bndrs
- where
- mk_binder (TvBndr tv tc_vis) = mkTyVarBinder vis tv
- where
- vis = case tc_vis of
- AnonTCB -> Specified
- NamedTCB Required -> Specified
- NamedTCB vis -> vis
-
-{- Note [Building the TyBinders for a DataCon]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A DataCon needs to keep track of the visibility of its universals and
-existentials, so that visible type application can work properly. This
-is done by storing the universal and existential TyVarBinders.
-See Note [TyVarBinders in DataCons] in DataCon.
-
-During construction of a DataCon, we often start from the TyBinders of
-the parent TyCon. For example
- data Maybe a = Nothing | Just a
-The DataCons start from the TyBinders of the parent TyCon.
-
-But the ultimate TyBinders for the DataCon are *different* than those
-of the DataCon. Here is an example:
-
- data App a b = MkApp (a b) -- App :: forall {k}. (k->*) -> k -> *
-
-The TyCon has
-
- tyConTyVars = [ k:*, a:k->*, b:k]
- tyConTyBinders = [ Named (TvBndr (k :: *) Inferred), Anon (k->*), Anon k ]
-
-The TyBinders for App line up with App's kind, given above.
-
-But the DataCon MkApp has the type
- MkApp :: forall {k} (a:k->*) (b:k). a b -> App k a b
-
-That is, its TyBinders should be
-
- dataConUnivTyVarBinders = [ TvBndr (k:*) Inferred
- , TvBndr (a:k->*) Specified
- , TvBndr (b:k) Specified ]
-
-So we want to take the TyCon's TyBinders and the TyCon's TyVars and
-merge them, pulling
- - variable names from the TyVars
- - visibilities from the TyBinders
- - but changing Anon/Required to Specified
-
-The last part about Required->Specified comes from this:
- data T k (a:k) b = MkT (a b)
-Here k is Required in T's kind, but we don't have Required binders in
-the TyBinders for a term (see Note [No Required TyBinder in terms]
-in TyCoRep), so we change it to Specified when making MkT's TyBinders
-
-This merging operation is done by mkDataConUnivTyBinders. In contrast,
-the TyBinders passed to mkDataCon are the final TyBinders stored in the
-DataCon (mkDataCon does no further work).
--}
-
------------------------------------------------------
buildPatSyn :: Name -> Bool
-> (Id,Bool) -> Maybe (Id, Bool)
@@ -310,7 +246,7 @@ buildClass tycon_name binders roles fds Nothing
do { traceIf (text "buildClass")
; tc_rep_name <- newTyConRepName tycon_name
- ; let univ_bndrs = mkDataConUnivTyVarBinders binders
+ ; let univ_bndrs = tyConTyVarBinders binders
univ_tvs = binderVars univ_bndrs
tycon = mkClassTyCon tycon_name binders roles
AbstractTyCon rec_clas tc_rep_name
@@ -359,7 +295,7 @@ buildClass tycon_name binders roles fds
op_names = [op | (op,_,_) <- sig_stuff]
arg_tys = sc_theta ++ op_tys
rec_tycon = classTyCon rec_clas
- univ_bndrs = mkDataConUnivTyVarBinders binders
+ univ_bndrs = tyConTyVarBinders binders
univ_tvs = binderVars univ_bndrs
; rep_nm <- newTyConRepName datacon_name
diff --git a/compiler/iface/IfaceSyn.hs b/compiler/iface/IfaceSyn.hs
index 60206ea076..3360d742ef 100644
--- a/compiler/iface/IfaceSyn.hs
+++ b/compiler/iface/IfaceSyn.hs
@@ -1424,6 +1424,7 @@ freeNamesIfCoercion (IfaceAppCo c1 c2)
= freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2
freeNamesIfCoercion (IfaceForAllCo _ kind_co co)
= freeNamesIfCoercion kind_co &&& freeNamesIfCoercion co
+freeNamesIfCoercion (IfaceFreeCoVar _) = emptyNameSet
freeNamesIfCoercion (IfaceCoVarCo _)
= emptyNameSet
freeNamesIfCoercion (IfaceAxiomInstCo ax _ cos)
diff --git a/compiler/iface/IfaceType.hs b/compiler/iface/IfaceType.hs
index 39e30283db..b1ad780782 100644
--- a/compiler/iface/IfaceType.hs
+++ b/compiler/iface/IfaceType.hs
@@ -109,7 +109,7 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy
type IfaceKind = IfaceType
data IfaceType -- A kind of universal type, used for types and kinds
- = IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType]
+ = IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType]
| IfaceTyVar IfLclName -- Type/coercion variable only, not tycon
| IfaceLitTy IfaceTyLit
| IfaceAppTy IfaceType IfaceType
@@ -204,6 +204,7 @@ Note that:
to deserialise one. IfaceFreeTyVar is used only in the "convert to IfaceType
and then pretty-print" pipeline.
+We do the same for covars, naturally.
Note [Equality predicates in IfaceType]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -242,6 +243,7 @@ data IfaceCoercion
| IfaceTyConAppCo Role IfaceTyCon [IfaceCoercion]
| IfaceAppCo IfaceCoercion IfaceCoercion
| IfaceForAllCo IfaceTvBndr IfaceCoercion IfaceCoercion
+ | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType]
| IfaceCoVarCo IfLclName
| IfaceAxiomInstCo IfExtName BranchIndex [IfaceCoercion]
| IfaceUnivCo IfaceUnivCoProv Role IfaceType IfaceType
@@ -395,6 +397,7 @@ substIfaceType env ty
go_co (IfaceTyConAppCo r tc cos) = IfaceTyConAppCo r tc (go_cos cos)
go_co (IfaceAppCo c1 c2) = IfaceAppCo (go_co c1) (go_co c2)
go_co (IfaceForAllCo {}) = pprPanic "substIfaceCoercion" (ppr ty)
+ go_co (IfaceFreeCoVar cv) = IfaceFreeCoVar cv
go_co (IfaceCoVarCo cv) = IfaceCoVarCo cv
go_co (IfaceAxiomInstCo a i cos) = IfaceAxiomInstCo a i (go_cos cos)
go_co (IfaceUnivCo prov r t1 t2) = IfaceUnivCo (go_prov prov) r (go t1) (go t2)
@@ -1039,6 +1042,8 @@ ppr_co ctxt_prec co@(IfaceForAllCo {})
= let (tvs, co'') = split_co co' in ((name,kind_co):tvs,co'')
split_co co' = ([], co')
+-- Why these two? See Note [TcTyVars in IfaceType]
+ppr_co _ (IfaceFreeCoVar covar) = ppr covar
ppr_co _ (IfaceCoVarCo covar) = ppr covar
ppr_co ctxt_prec (IfaceUnivCo IfaceUnsafeCoerceProv r ty1 ty2)
@@ -1065,7 +1070,8 @@ ppr_co ctxt_prec (IfaceAxiomInstCo n i cos)
ppr_co ctxt_prec (IfaceSymCo co)
= ppr_special_co ctxt_prec (text "Sym") [co]
ppr_co ctxt_prec (IfaceTransCo co1 co2)
- = ppr_special_co ctxt_prec (text "Trans") [co1,co2]
+ = maybeParen ctxt_prec TyOpPrec $
+ ppr_co TyOpPrec co1 <+> semi <+> ppr_co TyOpPrec co2
ppr_co ctxt_prec (IfaceNthCo d co)
= ppr_special_co ctxt_prec (text "Nth:" <> int d) [co]
ppr_co ctxt_prec (IfaceLRCo lr co)
@@ -1321,6 +1327,8 @@ instance Binary IfaceCoercion where
put_ bh a
put_ bh b
put_ bh c
+ put_ _ (IfaceFreeCoVar cv)
+ = pprPanic "Can't serialise IfaceFreeCoVar" (ppr cv)
put_ bh (IfaceCoVarCo a) = do
putByte bh 6
put_ bh a
diff --git a/compiler/iface/TcIface.hs b/compiler/iface/TcIface.hs
index 1477f462fc..9e0616518f 100644
--- a/compiler/iface/TcIface.hs
+++ b/compiler/iface/TcIface.hs
@@ -893,7 +893,7 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons
; mkNewTyConRhs tycon_name tycon data_con }
where
univ_tv_bndrs :: [TyVarBinder]
- univ_tv_bndrs = mkDataConUnivTyVarBinders tc_tybinders
+ univ_tv_bndrs = tyConTyVarBinders tc_tybinders
tc_con_decl (IfCon { ifConInfix = is_infix,
ifConExTvs = ex_bndrs,
@@ -915,7 +915,14 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons
; ~(eq_spec, theta, arg_tys, stricts) <- forkM (mk_doc dc_name) $
do { eq_spec <- tcIfaceEqSpec spec
; theta <- tcIfaceCtxt ctxt
- ; arg_tys <- mapM tcIfaceType args
+ -- This fixes #13710. The enclosing lazy thunk gets
+ -- forced when typechecking record wildcard pattern
+ -- matching (it's not completely clear why this
+ -- tuple is needed), which causes trouble if one of
+ -- the argument types was recursively defined.
+ -- See also Note [Tying the knot]
+ ; arg_tys <- forkM (mk_doc dc_name <+> text "arg_tys")
+ $ mapM tcIfaceType args
; stricts <- mapM tc_strict if_stricts
-- The IfBang field can mention
-- the type itself; hence inside forkM
@@ -1321,6 +1328,7 @@ tcIfaceCo = go
go (IfaceForAllCo tv k c) = do { k' <- go k
; bindIfaceTyVar tv $ \ tv' ->
ForAllCo tv' k' <$> go c }
+ go (IfaceFreeCoVar c) = pprPanic "tcIfaceCo:IfaceFreeCoVar" (ppr c)
go (IfaceCoVarCo n) = CoVarCo <$> go_var n
go (IfaceAxiomInstCo n i cs) = AxiomInstCo <$> tcIfaceCoAxiom n <*> pure i <*> mapM go cs
go (IfaceUnivCo p r t1 t2) = UnivCo <$> tcIfaceUnivCoProv p <*> pure r
diff --git a/compiler/iface/ToIface.hs b/compiler/iface/ToIface.hs
index 6f2acba21d..f5cbe9e5c7 100644
--- a/compiler/iface/ToIface.hs
+++ b/compiler/iface/ToIface.hs
@@ -22,7 +22,7 @@ module ToIface
, tidyToIfaceContext
, tidyToIfaceTcArgs
-- * Coercions
- , toIfaceCoercion
+ , toIfaceCoercion, toIfaceCoercionX
-- * Pattern synonyms
, patSynToIfaceDecl
-- * Expressions
@@ -216,8 +216,11 @@ toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion
toIfaceCoercionX fr co
= go co
where
- go (Refl r ty) = IfaceReflCo r (toIfaceType ty)
- go (CoVarCo cv) = IfaceCoVarCo (toIfaceCoVar cv)
+ go (Refl r ty) = IfaceReflCo r (toIfaceTypeX fr ty)
+ go (CoVarCo cv)
+ -- See [TcTyVars in IfaceType] in IfaceType
+ | cv `elemVarSet` fr = IfaceFreeCoVar cv
+ | otherwise = IfaceCoVarCo (toIfaceCoVar cv)
go (AppCo co1 co2) = IfaceAppCo (go co1) (go co2)
go (SymCo co) = IfaceSymCo (go co)
go (TransCo co1 co2) = IfaceTransCo (go co1) (go co2)
@@ -236,8 +239,7 @@ toIfaceCoercionX fr co
| tc `hasKey` funTyConKey
, [_,_,_,_] <- cos = pprPanic "toIfaceCoercion" (ppr co)
| otherwise = IfaceTyConAppCo r (toIfaceTyCon tc) (map go cos)
- go (FunCo r co1 co2) = IfaceFunCo r (toIfaceCoercion co1)
- (toIfaceCoercion co2)
+ go (FunCo r co1 co2) = IfaceFunCo r (go co1) (go co2)
go (ForAllCo tv k co) = IfaceForAllCo (toIfaceTvBndr tv)
(toIfaceCoercionX fr' k)
diff --git a/compiler/iface/ToIface.hs-boot b/compiler/iface/ToIface.hs-boot
index e2431b82dc..cdb472692e 100644
--- a/compiler/iface/ToIface.hs-boot
+++ b/compiler/iface/ToIface.hs-boot
@@ -13,4 +13,4 @@ toIfaceTyLit :: TyLit -> IfaceTyLit
toIfaceForAllBndr :: TyVarBinder -> IfaceForAllBndr
toIfaceTyCon :: TyCon -> IfaceTyCon
toIfaceTcArgs :: TyCon -> [Type] -> IfaceTcArgs
-toIfaceCoercion :: Coercion -> IfaceCoercion
+toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion
diff --git a/compiler/llvmGen/Llvm/AbsSyn.hs b/compiler/llvmGen/Llvm/AbsSyn.hs
index 8f38c799c7..7dd3c4807b 100644
--- a/compiler/llvmGen/Llvm/AbsSyn.hs
+++ b/compiler/llvmGen/Llvm/AbsSyn.hs
@@ -323,8 +323,8 @@ data LlvmExpression
basic block in a new variable of type tp.
* tp: type of the merged variable, must match the types of the
predecessor variables.
- * precessors: A list of variables and the basic block that they originate
- from.
+ * predecessors: A list of variables and the basic block that they originate
+ from.
-}
| Phi LlvmType [(LlvmVar,LlvmVar)]
diff --git a/compiler/llvmGen/Llvm/PpLlvm.hs b/compiler/llvmGen/Llvm/PpLlvm.hs
index 293999bd1e..f2eeffe114 100644
--- a/compiler/llvmGen/Llvm/PpLlvm.hs
+++ b/compiler/llvmGen/Llvm/PpLlvm.hs
@@ -238,7 +238,7 @@ ppLlvmExpression expr
Malloc tp amount -> ppMalloc tp amount
AtomicRMW aop tgt src ordering -> ppAtomicRMW aop tgt src ordering
CmpXChg addr old new s_ord f_ord -> ppCmpXChg addr old new s_ord f_ord
- Phi tp precessors -> ppPhi tp precessors
+ Phi tp predecessors -> ppPhi tp predecessors
Asm asm c ty v se sk -> ppAsm asm c ty v se sk
MExpr meta expr -> ppMetaExpr meta expr
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index f6ff838d14..f09237c6d9 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -36,10 +36,8 @@ import Util
import Control.Monad.Trans.Class
import Control.Monad.Trans.Writer
-#if __GLASGOW_HASKELL__ > 710
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
-#endif
import Data.List ( nub )
import Data.Maybe ( catMaybes )
@@ -1863,11 +1861,9 @@ getTBAARegMeta = getTBAAMeta . getTBAA
-- | A more convenient way of accumulating LLVM statements and declarations.
data LlvmAccum = LlvmAccum LlvmStatements [LlvmCmmDecl]
-#if __GLASGOW_HASKELL__ > 710
instance Semigroup LlvmAccum where
LlvmAccum stmtsA declsA <> LlvmAccum stmtsB declsB =
LlvmAccum (stmtsA Semigroup.<> stmtsB) (declsA Semigroup.<> declsB)
-#endif
instance Monoid LlvmAccum where
mempty = LlvmAccum nilOL []
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 3fc35e5992..7f70377c25 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -1932,6 +1932,7 @@ linkBinary' staticLink dflags o_files dep_packages = do
++ [ SysTools.Option "-o"
, SysTools.FileOption "" output_fn
]
+ ++ libmLinkOpts
++ map SysTools.Option (
[]
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index cc9bbb8684..e57ea02834 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -1319,7 +1319,9 @@ data DynLibLoader
| SystemDependent
deriving Eq
-data RtsOptsEnabled = RtsOptsNone | RtsOptsSafeOnly | RtsOptsAll
+data RtsOptsEnabled
+ = RtsOptsNone | RtsOptsIgnore | RtsOptsIgnoreAll | RtsOptsSafeOnly
+ | RtsOptsAll
deriving (Show)
shouldUseColor :: DynFlags -> Bool
@@ -2835,6 +2837,10 @@ dynamic_flags_deps = [
(NoArg (setRtsOptsEnabled RtsOptsSafeOnly))
, make_ord_flag defGhcFlag "rtsopts=none"
(NoArg (setRtsOptsEnabled RtsOptsNone))
+ , make_ord_flag defGhcFlag "rtsopts=ignore"
+ (NoArg (setRtsOptsEnabled RtsOptsIgnore))
+ , make_ord_flag defGhcFlag "rtsopts=ignoreAll"
+ (NoArg (setRtsOptsEnabled RtsOptsIgnoreAll))
, make_ord_flag defGhcFlag "no-rtsopts"
(NoArg (setRtsOptsEnabled RtsOptsNone))
, make_ord_flag defGhcFlag "no-rtsopts-suggestions"
diff --git a/compiler/main/InteractiveEvalTypes.hs b/compiler/main/InteractiveEvalTypes.hs
index cb0121950f..e45ef6dde3 100644
--- a/compiler/main/InteractiveEvalTypes.hs
+++ b/compiler/main/InteractiveEvalTypes.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE CPP #-}
-
-- -----------------------------------------------------------------------------
--
-- (c) The University of Glasgow, 2005-2007
@@ -25,11 +23,7 @@ import SrcLoc
import Exception
import Data.Word
-#if MIN_VERSION_base(4,9,0)
import GHC.Stack.CCS
-#else
-import GHC.Stack as GHC.Stack.CCS
-#endif
data ExecOptions
= ExecOptions
diff --git a/compiler/main/Packages.hs b/compiler/main/Packages.hs
index 2c5833fae4..50b9967e01 100644
--- a/compiler/main/Packages.hs
+++ b/compiler/main/Packages.hs
@@ -88,12 +88,9 @@ import Data.Char ( toUpper )
import Data.List as List
import Data.Map (Map)
import Data.Set (Set)
-import Data.Maybe (mapMaybe)
import Data.Monoid (First(..))
-#if __GLASGOW_HASKELL__ > 710
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
-#endif
import qualified Data.Map as Map
import qualified Data.Map.Strict as MapStrict
import qualified Data.Set as Set
@@ -207,7 +204,6 @@ fromReexportedModules False pkg = ModOrigin Nothing [] [pkg] False
fromFlag :: ModuleOrigin
fromFlag = ModOrigin Nothing [] [] True
-#if __GLASGOW_HASKELL__ > 710
instance Semigroup ModuleOrigin where
ModOrigin e res rhs f <> ModOrigin e' res' rhs' f' =
ModOrigin (g e e') (res ++ res') (rhs ++ rhs') (f || f')
@@ -217,7 +213,6 @@ instance Semigroup ModuleOrigin where
g Nothing x = x
g x Nothing = x
_x <> _y = panic "ModOrigin: hidden module redefined"
-#endif
instance Monoid ModuleOrigin where
mempty = ModOrigin Nothing [] [] False
diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs
index 3d16124d72..c73e47c16a 100644
--- a/compiler/main/SysTools.hs
+++ b/compiler/main/SysTools.hs
@@ -39,6 +39,9 @@ module SysTools (
Option(..),
+ -- platform-specifics
+ libmLinkOpts,
+
-- frameworks
getPkgFrameworkOpts,
getFrameworkOpts
@@ -1537,6 +1540,7 @@ linkDynLib dflags0 o_files dep_packages
runLink dflags (
map Option verbFlags
+ ++ libmLinkOpts
++ [ Option "-o"
, FileOption "" output_fn
]
@@ -1556,6 +1560,16 @@ linkDynLib dflags0 o_files dep_packages
++ map Option pkg_link_opts
)
+-- | Some platforms require that we explicitly link against @libm@ if any
+-- math-y things are used (which we assume to include all programs). See #14022.
+libmLinkOpts :: [Option]
+libmLinkOpts =
+#if defined(HAVE_LIBM)
+ [Option "-lm"]
+#else
+ []
+#endif
+
getPkgFrameworkOpts :: DynFlags -> Platform -> [InstalledUnitId] -> IO [String]
getPkgFrameworkOpts dflags platform dep_packages
| platformUsesFrameworks platform = do
diff --git a/compiler/nativeGen/RegAlloc/Graph/Coalesce.hs b/compiler/nativeGen/RegAlloc/Graph/Coalesce.hs
index 7e8047f29f..832df2334e 100644
--- a/compiler/nativeGen/RegAlloc/Graph/Coalesce.hs
+++ b/compiler/nativeGen/RegAlloc/Graph/Coalesce.hs
@@ -62,7 +62,7 @@ sinkReg fm r
-- | Slurp out mov instructions that only serve to join live ranges.
--
--- During a mov, if the source reg dies and the destiation reg is
+-- During a mov, if the source reg dies and the destination reg is
-- born then we can rename the two regs to the same thing and
-- eliminate the move.
slurpJoinMovs
diff --git a/compiler/nativeGen/RegAlloc/Graph/Spill.hs b/compiler/nativeGen/RegAlloc/Graph/Spill.hs
index 0014ab6fed..b86b143f59 100644
--- a/compiler/nativeGen/RegAlloc/Graph/Spill.hs
+++ b/compiler/nativeGen/RegAlloc/Graph/Spill.hs
@@ -34,7 +34,7 @@ import qualified Data.IntSet as IntSet
-- TODO: See if we can split some of the live ranges instead of just globally
-- spilling the virtual reg. This might make the spill cleaner's job easier.
--
--- TODO: On CISCy x86 and x86_64 we don't nessesarally have to add a mov instruction
+-- TODO: On CISCy x86 and x86_64 we don't necessarily have to add a mov instruction
-- when making spills. If an instr is using a spilled virtual we may be able to
-- address the spill slot directly.
--
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
index 341fa43dbc..bd4774ae2c 100644
--- a/compiler/nativeGen/X86/CodeGen.hs
+++ b/compiler/nativeGen/X86/CodeGen.hs
@@ -2,9 +2,7 @@
-- The default iteration limit is a bit too low for the definitions
-- in this module.
-#if __GLASGOW_HASKELL__ >= 800
{-# OPTIONS_GHC -fmax-pmcheck-iterations=10000000 #-}
-#endif
-----------------------------------------------------------------------------
--
diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x
index 936948b40f..c5332fbe2f 100644
--- a/compiler/parser/Lexer.x
+++ b/compiler/parser/Lexer.x
@@ -77,9 +77,7 @@ module Lexer (
-- base
import Control.Monad
-#if __GLASGOW_HASKELL__ > 710
import Control.Monad.Fail
-#endif
import Data.Bits
import Data.Char
import Data.List
@@ -1894,10 +1892,8 @@ instance Monad P where
(>>=) = thenP
fail = failP
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail P where
fail = failP
-#endif
returnP :: a -> P a
returnP a = a `seq` (P $ \s -> POk s a)
diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs
index 8f352ee971..b2a1b41a4c 100644
--- a/compiler/parser/RdrHsSyn.hs
+++ b/compiler/parser/RdrHsSyn.hs
@@ -425,8 +425,8 @@ getMonoBind (L loc1 (FunBind { fun_id = fun_id1@(L _ f1),
getMonoBind bind binds = (bind, binds)
has_args :: [LMatch GhcPs (LHsExpr GhcPs)] -> Bool
-has_args [] = panic "RdrHsSyn:has_args"
-has_args ((L _ (Match _ args _ _)) : _) = not (null args)
+has_args [] = panic "RdrHsSyn:has_args"
+has_args ((L _ (Match { m_pats = args })) : _) = not (null args)
-- Don't group together FunBinds if they have
-- no arguments. This is necessary now that variable bindings
-- with no arguments are now treated as FunBinds rather
@@ -514,10 +514,16 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) =
do { unless (name == patsyn_name) $
wrongNameBindingErr loc decl
; match <- case details of
- PrefixCon pats ->
- return $ Match (FunRhs ln Prefix NoSrcStrict) pats Nothing rhs
- InfixCon pat1 pat2 ->
- return $ Match (FunRhs ln Infix NoSrcStrict) [pat1, pat2] Nothing rhs
+ PrefixCon pats -> return $ Match { m_ctxt = ctxt, m_pats = pats
+ , m_type = Nothing, m_grhss = rhs }
+ where
+ ctxt = FunRhs { mc_fun = ln, mc_fixity = Prefix, mc_strictness = NoSrcStrict }
+
+ InfixCon p1 p2 -> return $ Match { m_ctxt = ctxt, m_pats = [p1, p2]
+ , m_type = Nothing, m_grhss = rhs }
+ where
+ ctxt = FunRhs { mc_fun = ln, mc_fixity = Infix, mc_strictness = NoSrcStrict }
+
RecCon{} -> recordPatSynErr loc pat
; return $ L loc match }
fromDecl (L loc decl) = extraDeclErr loc decl
@@ -960,7 +966,9 @@ checkFunBind msg strictness ann lhs_loc fun is_infix pats opt_sig (L rhs_span gr
-- Add back the annotations stripped from any HsPar values in the lhs
-- mapM_ (\a -> a match_span) ann
return (ann, makeFunBind fun
- [L match_span (Match { m_ctxt = FunRhs fun is_infix strictness
+ [L match_span (Match { m_ctxt = FunRhs { mc_fun = fun
+ , mc_fixity = is_infix
+ , mc_strictness = strictness }
, m_pats = ps
, m_type = opt_sig
, m_grhss = grhss })])
@@ -1075,7 +1083,7 @@ isFunLhs e = go e [] []
go (L l (HsPar e)) es@(_:_) ann = go e es (ann ++ mkParensApiAnn l)
-- Things of the form `!x` are also FunBinds
- -- See Note [Varieties of binding pattern matches]
+ -- See Note [FunBind vs PatBind]
go (L _ (SectionR (L _ (HsVar (L _ bang))) (L l (HsVar (L _ var))))) [] ann
| bang == bang_RDR
, not (isRdrDataCon var) = return (Just (L l var, Prefix, [], ann))
@@ -1239,9 +1247,9 @@ checkCmdMatchGroup :: MatchGroup GhcPs (LHsExpr GhcPs)
checkCmdMatchGroup mg@(MG { mg_alts = L l ms }) = do
ms' <- mapM (locMap $ const convert) ms
return $ mg { mg_alts = L l ms' }
- where convert (Match mf pat mty grhss) = do
+ where convert match@(Match { m_grhss = grhss }) = do
grhss' <- checkCmdGRHSs grhss
- return $ Match mf pat mty grhss'
+ return $ match { m_grhss = grhss'}
checkCmdGRHSs :: GRHSs GhcPs (LHsExpr GhcPs) -> P (GRHSs GhcPs (LHsCmd GhcPs))
checkCmdGRHSs (GRHSs grhss binds) = do
diff --git a/compiler/prelude/KnownUniques.hs b/compiler/prelude/KnownUniques.hs
index 8f1b0b6347..60fa0e2435 100644
--- a/compiler/prelude/KnownUniques.hs
+++ b/compiler/prelude/KnownUniques.hs
@@ -79,7 +79,8 @@ knownUniqueName u =
mkSumTyConUnique :: Arity -> Unique
mkSumTyConUnique arity =
- ASSERT(arity < 0xff)
+ ASSERT(arity < 0x3f) -- 0x3f since we only have 6 bits to encode the
+ -- alternative
mkUnique 'z' (arity `shiftL` 8 .|. 0xfc)
mkSumDataConUnique :: ConTagZ -> Arity -> Unique
@@ -98,16 +99,18 @@ getUnboxedSumName n
_ -> pprPanic "getUnboxedSumName: invalid tag" (ppr tag)
| tag == 0x0
= dataConName $ sumDataCon (alt + 1) arity
+ | tag == 0x1
+ = getName $ dataConWrapId $ sumDataCon (alt + 1) arity
| tag == 0x2
= getRep $ promoteDataCon $ sumDataCon (alt + 1) arity
| otherwise
= pprPanic "getUnboxedSumName" (ppr n)
where
arity = n `shiftR` 8
- alt = (n .&. 0xff) `shiftR` 2
+ alt = (n .&. 0xfc) `shiftR` 2
tag = 0x3 .&. n
getRep tycon =
- fromMaybe (pprPanic "getUnboxedSumName" (ppr tycon))
+ fromMaybe (pprPanic "getUnboxedSumName(getRep)" (ppr tycon))
$ tyConRepName_maybe tycon
-- Note [Uniques for tuple type and data constructors]
diff --git a/compiler/prelude/PrelRules.hs b/compiler/prelude/PrelRules.hs
index 1ef0565ff3..2dbc5e888d 100644
--- a/compiler/prelude/PrelRules.hs
+++ b/compiler/prelude/PrelRules.hs
@@ -1517,7 +1517,7 @@ into
0# -> e1
1# -> e1
-This rule elimiantes a lot of boilerplate. For
+This rule eliminates a lot of boilerplate. For
if (x>y) then e1 else e2
we generate
case tagToEnum (x ># y) of
diff --git a/compiler/prelude/THNames.hs b/compiler/prelude/THNames.hs
index 85362434cc..4128ab375e 100644
--- a/compiler/prelude/THNames.hs
+++ b/compiler/prelude/THNames.hs
@@ -95,7 +95,7 @@ templateHaskellNames = [
-- Type
forallTName, varTName, conTName, appTName, equalityTName,
tupleTName, unboxedTupleTName, unboxedSumTName,
- arrowTName, listTName, sigTName, sigTDataConName, litTName,
+ arrowTName, listTName, sigTName, litTName,
promotedTName, promotedTupleTName, promotedNilTName, promotedConsTName,
wildCardTName,
-- TyLit
@@ -152,10 +152,10 @@ templateHaskellNames = [
clauseQTyConName, expQTyConName, fieldExpTyConName, predTyConName,
stmtQTyConName, decQTyConName, conQTyConName, bangTypeQTyConName,
varBangTypeQTyConName, typeQTyConName, expTyConName, decTyConName,
- typeTyConName, tyVarBndrTyConName, matchTyConName, clauseTyConName,
+ typeTyConName, tyVarBndrQTyConName, matchTyConName, clauseTyConName,
patQTyConName, fieldPatQTyConName, fieldExpQTyConName, funDepTyConName,
predQTyConName, decsQTyConName, ruleBndrQTyConName, tySynEqnQTyConName,
- roleTyConName, tExpTyConName, injAnnTyConName, kindTyConName,
+ roleTyConName, tExpTyConName, injAnnTyConName, kindQTyConName,
overlapTyConName, derivClauseQTyConName, derivStrategyTyConName,
-- Quasiquoting
@@ -163,7 +163,7 @@ templateHaskellNames = [
thSyn, thLib, qqLib :: Module
thSyn = mkTHModule (fsLit "Language.Haskell.TH.Syntax")
-thLib = mkTHModule (fsLit "Language.Haskell.TH.Lib")
+thLib = mkTHModule (fsLit "Language.Haskell.TH.Lib.Internal")
qqLib = mkTHModule (fsLit "Language.Haskell.TH.Quote")
mkTHModule :: FastString -> Module
@@ -184,9 +184,9 @@ liftClassName = thCls (fsLit "Lift") liftClassKey
qTyConName, nameTyConName, fieldExpTyConName, patTyConName,
fieldPatTyConName, expTyConName, decTyConName, typeTyConName,
- tyVarBndrTyConName, matchTyConName, clauseTyConName, funDepTyConName,
- predTyConName, tExpTyConName, injAnnTyConName, kindTyConName,
- overlapTyConName, derivStrategyTyConName :: Name
+ matchTyConName, clauseTyConName, funDepTyConName, predTyConName,
+ tExpTyConName, injAnnTyConName, overlapTyConName,
+ derivStrategyTyConName :: Name
qTyConName = thTc (fsLit "Q") qTyConKey
nameTyConName = thTc (fsLit "Name") nameTyConKey
fieldExpTyConName = thTc (fsLit "FieldExp") fieldExpTyConKey
@@ -195,14 +195,12 @@ fieldPatTyConName = thTc (fsLit "FieldPat") fieldPatTyConKey
expTyConName = thTc (fsLit "Exp") expTyConKey
decTyConName = thTc (fsLit "Dec") decTyConKey
typeTyConName = thTc (fsLit "Type") typeTyConKey
-tyVarBndrTyConName = thTc (fsLit "TyVarBndr") tyVarBndrTyConKey
matchTyConName = thTc (fsLit "Match") matchTyConKey
clauseTyConName = thTc (fsLit "Clause") clauseTyConKey
funDepTyConName = thTc (fsLit "FunDep") funDepTyConKey
predTyConName = thTc (fsLit "Pred") predTyConKey
tExpTyConName = thTc (fsLit "TExp") tExpTyConKey
injAnnTyConName = thTc (fsLit "InjectivityAnn") injAnnTyConKey
-kindTyConName = thTc (fsLit "Kind") kindTyConKey
overlapTyConName = thTc (fsLit "Overlap") overlapTyConKey
derivStrategyTyConName = thTc (fsLit "DerivStrategy") derivStrategyTyConKey
@@ -347,38 +345,36 @@ funDName, valDName, dataDName, newtypeDName, tySynDName, classDName,
openTypeFamilyDName, closedTypeFamilyDName, infixLDName, infixRDName,
infixNDName, roleAnnotDName, patSynDName, patSynSigDName,
pragCompleteDName :: Name
-funDName = libFun (fsLit "funD") funDIdKey
-valDName = libFun (fsLit "valD") valDIdKey
-dataDName = libFun (fsLit "dataD") dataDIdKey
-newtypeDName = libFun (fsLit "newtypeD") newtypeDIdKey
-tySynDName = libFun (fsLit "tySynD") tySynDIdKey
-classDName = libFun (fsLit "classD") classDIdKey
-instanceWithOverlapDName
- = libFun (fsLit "instanceWithOverlapD") instanceWithOverlapDIdKey
-standaloneDerivWithStrategyDName = libFun
- (fsLit "standaloneDerivWithStrategyD") standaloneDerivWithStrategyDIdKey
-sigDName = libFun (fsLit "sigD") sigDIdKey
-defaultSigDName = libFun (fsLit "defaultSigD") defaultSigDIdKey
-forImpDName = libFun (fsLit "forImpD") forImpDIdKey
-pragInlDName = libFun (fsLit "pragInlD") pragInlDIdKey
-pragSpecDName = libFun (fsLit "pragSpecD") pragSpecDIdKey
-pragSpecInlDName = libFun (fsLit "pragSpecInlD") pragSpecInlDIdKey
-pragSpecInstDName = libFun (fsLit "pragSpecInstD") pragSpecInstDIdKey
-pragRuleDName = libFun (fsLit "pragRuleD") pragRuleDIdKey
-pragCompleteDName = libFun (fsLit "pragCompleteD") pragCompleteDIdKey
-pragAnnDName = libFun (fsLit "pragAnnD") pragAnnDIdKey
-dataInstDName = libFun (fsLit "dataInstD") dataInstDIdKey
-newtypeInstDName = libFun (fsLit "newtypeInstD") newtypeInstDIdKey
-tySynInstDName = libFun (fsLit "tySynInstD") tySynInstDIdKey
-openTypeFamilyDName = libFun (fsLit "openTypeFamilyD") openTypeFamilyDIdKey
-closedTypeFamilyDName= libFun (fsLit "closedTypeFamilyD") closedTypeFamilyDIdKey
-dataFamilyDName = libFun (fsLit "dataFamilyD") dataFamilyDIdKey
-infixLDName = libFun (fsLit "infixLD") infixLDIdKey
-infixRDName = libFun (fsLit "infixRD") infixRDIdKey
-infixNDName = libFun (fsLit "infixND") infixNDIdKey
-roleAnnotDName = libFun (fsLit "roleAnnotD") roleAnnotDIdKey
-patSynDName = libFun (fsLit "patSynD") patSynDIdKey
-patSynSigDName = libFun (fsLit "patSynSigD") patSynSigDIdKey
+funDName = libFun (fsLit "funD") funDIdKey
+valDName = libFun (fsLit "valD") valDIdKey
+dataDName = libFun (fsLit "dataD") dataDIdKey
+newtypeDName = libFun (fsLit "newtypeD") newtypeDIdKey
+tySynDName = libFun (fsLit "tySynD") tySynDIdKey
+classDName = libFun (fsLit "classD") classDIdKey
+instanceWithOverlapDName = libFun (fsLit "instanceWithOverlapD") instanceWithOverlapDIdKey
+standaloneDerivWithStrategyDName = libFun (fsLit "standaloneDerivWithStrategyD") standaloneDerivWithStrategyDIdKey
+sigDName = libFun (fsLit "sigD") sigDIdKey
+defaultSigDName = libFun (fsLit "defaultSigD") defaultSigDIdKey
+forImpDName = libFun (fsLit "forImpD") forImpDIdKey
+pragInlDName = libFun (fsLit "pragInlD") pragInlDIdKey
+pragSpecDName = libFun (fsLit "pragSpecD") pragSpecDIdKey
+pragSpecInlDName = libFun (fsLit "pragSpecInlD") pragSpecInlDIdKey
+pragSpecInstDName = libFun (fsLit "pragSpecInstD") pragSpecInstDIdKey
+pragRuleDName = libFun (fsLit "pragRuleD") pragRuleDIdKey
+pragCompleteDName = libFun (fsLit "pragCompleteD") pragCompleteDIdKey
+pragAnnDName = libFun (fsLit "pragAnnD") pragAnnDIdKey
+dataInstDName = libFun (fsLit "dataInstD") dataInstDIdKey
+newtypeInstDName = libFun (fsLit "newtypeInstD") newtypeInstDIdKey
+tySynInstDName = libFun (fsLit "tySynInstD") tySynInstDIdKey
+openTypeFamilyDName = libFun (fsLit "openTypeFamilyD") openTypeFamilyDIdKey
+closedTypeFamilyDName = libFun (fsLit "closedTypeFamilyD") closedTypeFamilyDIdKey
+dataFamilyDName = libFun (fsLit "dataFamilyD") dataFamilyDIdKey
+infixLDName = libFun (fsLit "infixLD") infixLDIdKey
+infixRDName = libFun (fsLit "infixRD") infixRDIdKey
+infixNDName = libFun (fsLit "infixND") infixNDIdKey
+roleAnnotDName = libFun (fsLit "roleAnnotD") roleAnnotDIdKey
+patSynDName = libFun (fsLit "patSynD") patSynDIdKey
+patSynSigDName = libFun (fsLit "patSynSigD") patSynSigDIdKey
-- type Ctxt = ...
cxtName :: Name
@@ -432,7 +428,7 @@ recordPatSynName = libFun (fsLit "recordPatSyn") recordPatSynIdKey
-- data Type = ...
forallTName, varTName, conTName, tupleTName, unboxedTupleTName,
unboxedSumTName, arrowTName, listTName, appTName, sigTName,
- sigTDataConName, equalityTName, litTName, promotedTName,
+ equalityTName, litTName, promotedTName,
promotedTupleTName, promotedNilTName, promotedConsTName,
wildCardTName :: Name
forallTName = libFun (fsLit "forallT") forallTIdKey
@@ -445,9 +441,6 @@ arrowTName = libFun (fsLit "arrowT") arrowTIdKey
listTName = libFun (fsLit "listT") listTIdKey
appTName = libFun (fsLit "appT") appTIdKey
sigTName = libFun (fsLit "sigT") sigTIdKey
--- Yes, we need names for both the monadic sigT as well as the pure SigT. Why?
--- Refer to the documentation for repLKind in DsMeta.
-sigTDataConName = thCon (fsLit "SigT") sigTDataConKey
equalityTName = libFun (fsLit "equalityT") equalityTIdKey
litTName = libFun (fsLit "litT") litTIdKey
promotedTName = libFun (fsLit "promotedT") promotedTIdKey
@@ -463,8 +456,8 @@ strTyLitName = libFun (fsLit "strTyLit") strTyLitIdKey
-- data TyVarBndr = ...
plainTVName, kindedTVName :: Name
-plainTVName = libFun (fsLit "plainTV") plainTVIdKey
-kindedTVName = libFun (fsLit "kindedTV") kindedTVIdKey
+plainTVName = libFun (fsLit "plainTV") plainTVIdKey
+kindedTVName = libFun (fsLit "kindedTV") kindedTVIdKey
-- data Role = ...
nominalRName, representationalRName, phantomRName, inferRName :: Name
@@ -487,9 +480,9 @@ constraintKName = libFun (fsLit "constraintK") constraintKIdKey
-- data FamilyResultSig = ...
noSigName, kindSigName, tyVarSigName :: Name
-noSigName = libFun (fsLit "noSig") noSigIdKey
-kindSigName = libFun (fsLit "kindSig") kindSigIdKey
-tyVarSigName = libFun (fsLit "tyVarSig") tyVarSigIdKey
+noSigName = libFun (fsLit "noSig") noSigIdKey
+kindSigName = libFun (fsLit "kindSig") kindSigIdKey
+tyVarSigName = libFun (fsLit "tyVarSig") tyVarSigIdKey
-- data InjectivityAnn = ...
injectivityAnnName :: Name
@@ -546,7 +539,7 @@ matchQTyConName, clauseQTyConName, expQTyConName, stmtQTyConName,
varBangTypeQTyConName, typeQTyConName, fieldExpQTyConName,
patQTyConName, fieldPatQTyConName, predQTyConName, decsQTyConName,
ruleBndrQTyConName, tySynEqnQTyConName, roleTyConName,
- derivClauseQTyConName :: Name
+ derivClauseQTyConName, kindQTyConName, tyVarBndrQTyConName :: Name
matchQTyConName = libTc (fsLit "MatchQ") matchQTyConKey
clauseQTyConName = libTc (fsLit "ClauseQ") clauseQTyConKey
expQTyConName = libTc (fsLit "ExpQ") expQTyConKey
@@ -565,6 +558,8 @@ ruleBndrQTyConName = libTc (fsLit "RuleBndrQ") ruleBndrQTyConKey
tySynEqnQTyConName = libTc (fsLit "TySynEqnQ") tySynEqnQTyConKey
roleTyConName = libTc (fsLit "Role") roleTyConKey
derivClauseQTyConName = libTc (fsLit "DerivClauseQ") derivClauseQTyConKey
+kindQTyConName = libTc (fsLit "KindQ") kindQTyConKey
+tyVarBndrQTyConName = libTc (fsLit "TyVarBndrQ") tyVarBndrQTyConKey
-- quasiquoting
quoteExpName, quotePatName, quoteDecName, quoteTypeName :: Name
@@ -630,12 +625,12 @@ liftClassKey = mkPreludeClassUnique 200
expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey,
decQTyConKey, patTyConKey, matchQTyConKey, clauseQTyConKey,
- stmtQTyConKey, conQTyConKey, typeQTyConKey, typeTyConKey, tyVarBndrTyConKey,
- decTyConKey, bangTypeQTyConKey, varBangTypeQTyConKey,
+ stmtQTyConKey, conQTyConKey, typeQTyConKey, typeTyConKey,
+ tyVarBndrQTyConKey, decTyConKey, bangTypeQTyConKey, varBangTypeQTyConKey,
fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey,
fieldPatQTyConKey, fieldExpQTyConKey, funDepTyConKey, predTyConKey,
predQTyConKey, decsQTyConKey, ruleBndrQTyConKey, tySynEqnQTyConKey,
- roleTyConKey, tExpTyConKey, injAnnTyConKey, kindTyConKey,
+ roleTyConKey, tExpTyConKey, injAnnTyConKey, kindQTyConKey,
overlapTyConKey, derivClauseQTyConKey, derivStrategyTyConKey :: Unique
expTyConKey = mkPreludeTyConUnique 200
matchTyConKey = mkPreludeTyConUnique 201
@@ -662,14 +657,14 @@ fieldExpQTyConKey = mkPreludeTyConUnique 221
funDepTyConKey = mkPreludeTyConUnique 222
predTyConKey = mkPreludeTyConUnique 223
predQTyConKey = mkPreludeTyConUnique 224
-tyVarBndrTyConKey = mkPreludeTyConUnique 225
+tyVarBndrQTyConKey = mkPreludeTyConUnique 225
decsQTyConKey = mkPreludeTyConUnique 226
ruleBndrQTyConKey = mkPreludeTyConUnique 227
tySynEqnQTyConKey = mkPreludeTyConUnique 228
roleTyConKey = mkPreludeTyConUnique 229
tExpTyConKey = mkPreludeTyConUnique 230
injAnnTyConKey = mkPreludeTyConUnique 231
-kindTyConKey = mkPreludeTyConUnique 232
+kindQTyConKey = mkPreludeTyConUnique 232
overlapTyConKey = mkPreludeTyConUnique 233
derivClauseQTyConKey = mkPreludeTyConUnique 234
derivStrategyTyConKey = mkPreludeTyConUnique 235
@@ -955,7 +950,7 @@ recordPatSynIdKey = mkPreludeMiscIdUnique 372
-- data Type = ...
forallTIdKey, varTIdKey, conTIdKey, tupleTIdKey, unboxedTupleTIdKey,
unboxedSumTIdKey, arrowTIdKey, listTIdKey, appTIdKey, sigTIdKey,
- sigTDataConKey, equalityTIdKey, litTIdKey, promotedTIdKey,
+ equalityTIdKey, litTIdKey, promotedTIdKey,
promotedTupleTIdKey, promotedNilTIdKey, promotedConsTIdKey,
wildCardTIdKey :: Unique
forallTIdKey = mkPreludeMiscIdUnique 381
@@ -968,14 +963,13 @@ arrowTIdKey = mkPreludeMiscIdUnique 387
listTIdKey = mkPreludeMiscIdUnique 388
appTIdKey = mkPreludeMiscIdUnique 389
sigTIdKey = mkPreludeMiscIdUnique 390
-sigTDataConKey = mkPreludeMiscIdUnique 391
-equalityTIdKey = mkPreludeMiscIdUnique 392
-litTIdKey = mkPreludeMiscIdUnique 393
-promotedTIdKey = mkPreludeMiscIdUnique 394
-promotedTupleTIdKey = mkPreludeMiscIdUnique 395
-promotedNilTIdKey = mkPreludeMiscIdUnique 396
-promotedConsTIdKey = mkPreludeMiscIdUnique 397
-wildCardTIdKey = mkPreludeMiscIdUnique 398
+equalityTIdKey = mkPreludeMiscIdUnique 391
+litTIdKey = mkPreludeMiscIdUnique 392
+promotedTIdKey = mkPreludeMiscIdUnique 393
+promotedTupleTIdKey = mkPreludeMiscIdUnique 394
+promotedNilTIdKey = mkPreludeMiscIdUnique 395
+promotedConsTIdKey = mkPreludeMiscIdUnique 396
+wildCardTIdKey = mkPreludeMiscIdUnique 397
-- data TyLit = ...
numTyLitIdKey, strTyLitIdKey :: Unique
diff --git a/compiler/prelude/TysWiredIn.hs b/compiler/prelude/TysWiredIn.hs
index 28c6629a91..5a8c4aae78 100644
--- a/compiler/prelude/TysWiredIn.hs
+++ b/compiler/prelude/TysWiredIn.hs
@@ -162,10 +162,6 @@ import Util
import BooleanFormula ( mkAnd )
import qualified Data.ByteString.Char8 as BS
-#if !MIN_VERSION_bytestring(0,10,8)
-import qualified Data.ByteString.Internal as BSI
-import qualified Data.ByteString.Unsafe as BSU
-#endif
alpha_tyvar :: [TyVar]
alpha_tyvar = [alphaTyVar]
@@ -690,7 +686,7 @@ isBuiltInOcc_maybe occ =
-- boxed tuple data/tycon
"()" -> Just $ tup_name Boxed 0
- _ | Just rest <- "(" `stripPrefix` name
+ _ | Just rest <- "(" `BS.stripPrefix` name
, (commas, rest') <- BS.span (==',') rest
, ")" <- rest'
-> Just $ tup_name Boxed (1+BS.length commas)
@@ -698,21 +694,21 @@ isBuiltInOcc_maybe occ =
-- unboxed tuple data/tycon
"(##)" -> Just $ tup_name Unboxed 0
"Unit#" -> Just $ tup_name Unboxed 1
- _ | Just rest <- "(#" `stripPrefix` name
+ _ | Just rest <- "(#" `BS.stripPrefix` name
, (commas, rest') <- BS.span (==',') rest
, "#)" <- rest'
-> Just $ tup_name Unboxed (1+BS.length commas)
-- unboxed sum tycon
- _ | Just rest <- "(#" `stripPrefix` name
+ _ | Just rest <- "(#" `BS.stripPrefix` name
, (pipes, rest') <- BS.span (=='|') rest
, "#)" <- rest'
-> Just $ tyConName $ sumTyCon (1+BS.length pipes)
-- unboxed sum datacon
- _ | Just rest <- "(#" `stripPrefix` name
+ _ | Just rest <- "(#" `BS.stripPrefix` name
, (pipes1, rest') <- BS.span (=='|') rest
- , Just rest'' <- "_" `stripPrefix` rest'
+ , Just rest'' <- "_" `BS.stripPrefix` rest'
, (pipes2, rest''') <- BS.span (=='|') rest''
, "#)" <- rest'''
-> let arity = BS.length pipes1 + BS.length pipes2 + 1
@@ -720,15 +716,6 @@ isBuiltInOcc_maybe occ =
in Just $ dataConName $ sumDataCon alt arity
_ -> Nothing
where
- -- TODO: Drop when bytestring 0.10.8 can be assumed
-#if MIN_VERSION_bytestring(0,10,8)
- stripPrefix = BS.stripPrefix
-#else
- stripPrefix bs1@(BSI.PS _ _ l1) bs2
- | bs1 `BS.isPrefixOf` bs2 = Just (BSU.unsafeDrop l1 bs2)
- | otherwise = Nothing
-#endif
-
name = fastStringToByteString $ occNameFS occ
choose_ns :: Name -> Name -> Name
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index 97ae89cb84..8039913110 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -1238,7 +1238,7 @@ primop ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp
primop ReadByteArrayOp_Int "readIntArray#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
- {Read intger; offset in words.}
+ {Read integer; offset in words.}
with has_side_effects = True
can_fail = True
diff --git a/compiler/rename/RnBinds.hs b/compiler/rename/RnBinds.hs
index cb14ceb840..25613dc018 100644
--- a/compiler/rename/RnBinds.hs
+++ b/compiler/rename/RnBinds.hs
@@ -47,7 +47,7 @@ import NameSet
import RdrName ( RdrName, rdrNameOcc )
import SrcLoc
import ListSetOps ( findDupsEq )
-import BasicTypes ( RecFlag(..), LexicalFixity(..) )
+import BasicTypes ( RecFlag(..) )
import Digraph ( SCC(..) )
import Bag
import Util
@@ -58,7 +58,9 @@ import Maybes ( orElse )
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
-import Data.List ( partition, sort )
+import Data.Foldable ( toList )
+import Data.List ( partition, sort )
+import Data.List.NonEmpty ( NonEmpty(..) )
{-
-- ToDo: Put the annotations into the monad, so that they arrive in the proper
@@ -1091,7 +1093,7 @@ okHsSig ctxt (L _ sig)
(CompleteMatchSig {}, _) -> False
-------------------
-findDupSigs :: [LSig GhcPs] -> [[(Located RdrName, Sig GhcPs)]]
+findDupSigs :: [LSig GhcPs] -> [NonEmpty (Located RdrName, Sig GhcPs)]
-- Check for duplicates on RdrName version,
-- because renamed version has unboundName for
-- not-in-scope binders, which gives bogus dup-sig errors
@@ -1162,14 +1164,13 @@ rnMatch' ctxt rnBody match@(Match { m_ctxt = mf, m_pats = pats
Nothing -> return ()
Just (L loc ty) -> addErrAt loc (resSigErr match ty)
- ; let fixity = if isInfixMatch match then Infix else Prefix
-- Now the main event
-- Note that there are no local fixity decls for matches
; rnPats ctxt pats $ \ pats' -> do
{ (grhss', grhss_fvs) <- rnGRHSs ctxt rnBody grhss
- ; let mf' = case (ctxt,mf) of
- (FunRhs (L _ funid) _ _,FunRhs (L lf _) _ strict)
- -> FunRhs (L lf funid) fixity strict
+ ; let mf' = case (ctxt, mf) of
+ (FunRhs { mc_fun = L _ funid }, FunRhs { mc_fun = L lf _ })
+ -> mf { mc_fun = L lf funid }
_ -> ctxt
; return (Match { m_ctxt = mf', m_pats = pats'
, m_type = Nothing, m_grhss = grhss'}, grhss_fvs ) }}
@@ -1244,17 +1245,18 @@ rnGRHS' ctxt rnBody (GRHS guards rhs)
************************************************************************
-}
-dupSigDeclErr :: [(Located RdrName, Sig GhcPs)] -> RnM ()
-dupSigDeclErr pairs@((L loc name, sig) : _)
+dupSigDeclErr :: NonEmpty (Located RdrName, Sig GhcPs) -> RnM ()
+dupSigDeclErr pairs@((L loc name, sig) :| _)
= addErrAt loc $
vcat [ text "Duplicate" <+> what_it_is
<> text "s for" <+> quotes (ppr name)
- , text "at" <+> vcat (map ppr $ sort $ map (getLoc . fst) pairs) ]
+ , text "at" <+> vcat (map ppr $ sort
+ $ map (getLoc . fst)
+ $ toList pairs)
+ ]
where
what_it_is = hsSigDoc sig
-dupSigDeclErr [] = panic "dupSigDeclErr"
-
misplacedSigErr :: LSig GhcRn -> RnM ()
misplacedSigErr (L loc sig)
= addErrAt loc $
diff --git a/compiler/rename/RnEnv.hs b/compiler/rename/RnEnv.hs
index 617b3556bb..298de54168 100644
--- a/compiler/rename/RnEnv.hs
+++ b/compiler/rename/RnEnv.hs
@@ -53,7 +53,7 @@ import HscTypes
import TcEnv
import TcRnMonad
import RdrHsSyn ( setRdrNameSpace )
-import TysWiredIn ( starKindTyConName, unicodeStarKindTyConName )
+import TysWiredIn
import Name
import NameSet
import NameEnv
@@ -1573,5 +1573,17 @@ opDeclErr n
badOrigBinding :: RdrName -> SDoc
badOrigBinding name
- = text "Illegal binding of built-in syntax:" <+> ppr (rdrNameOcc name)
- -- The rdrNameOcc is because we don't want to print Prelude.(,)
+ | Just _ <- isBuiltInOcc_maybe occ
+ = text "Illegal binding of built-in syntax:" <+> ppr occ
+ -- Use an OccName here because we don't want to print Prelude.(,)
+ | otherwise
+ = text "Cannot redefine a Name retrieved by a Template Haskell quote:"
+ <+> ppr name
+ -- This can happen when one tries to use a Template Haskell splice to
+ -- define a top-level identifier with an already existing name, e.g.,
+ --
+ -- $(pure [ValD (VarP 'succ) (NormalB (ConE 'True)) []])
+ --
+ -- (See Trac #13968.)
+ where
+ occ = rdrNameOcc name
diff --git a/compiler/rename/RnExpr.hs b/compiler/rename/RnExpr.hs
index 100ace3f24..45979ca10e 100644
--- a/compiler/rename/RnExpr.hs
+++ b/compiler/rename/RnExpr.hs
@@ -57,6 +57,7 @@ import qualified GHC.LanguageExtensions as LangExt
import Data.Ord
import Data.Array
+import qualified Data.List.NonEmpty as NE
{-
************************************************************************
@@ -577,7 +578,7 @@ methodNamesMatch :: MatchGroup GhcRn (LHsCmd GhcRn) -> FreeVars
methodNamesMatch (MG { mg_alts = L _ ms })
= plusFVs (map do_one ms)
where
- do_one (L _ (Match _ _ _ grhss)) = methodNamesGRHSs grhss
+ do_one (L _ (Match { m_grhss = grhss })) = methodNamesGRHSs grhss
-------------------------------------------------
-- gaw 2004
@@ -970,7 +971,7 @@ rnParallelStmts ctxt return_op segs thing_inside
cmpByOcc n1 n2 = nameOccName n1 `compare` nameOccName n2
dupErr vs = addErr (text "Duplicate binding in parallel list comprehension for:"
- <+> quotes (ppr (head vs)))
+ <+> quotes (ppr (NE.head vs)))
lookupStmtName :: HsStmtContext Name -> Name -> RnM (SyntaxExpr GhcRn, FreeVars)
-- Like lookupSyntaxName, but respects contexts
diff --git a/compiler/rename/RnPat.hs b/compiler/rename/RnPat.hs
index ff88dbffbc..320e4f3d12 100644
--- a/compiler/rename/RnPat.hs
+++ b/compiler/rename/RnPat.hs
@@ -68,6 +68,7 @@ import DataCon
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad ( when, liftM, ap, unless )
+import qualified Data.List.NonEmpty as NE
import Data.Ratio
{-
@@ -690,7 +691,7 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot })
-- Data constructor not lexically in scope at all
-- See Note [Disambiguation and Template Haskell]
- dup_flds :: [[RdrName]]
+ dup_flds :: [NE.NonEmpty RdrName]
-- Each list represents a RdrName that occurred more than once
-- (the list contains all occurrences)
-- Each list in dup_fields is non-empty
@@ -769,7 +770,7 @@ rnHsRecUpdFields flds
, hsRecFieldArg = arg''
, hsRecPun = pun }), fvs') }
- dup_flds :: [[RdrName]]
+ dup_flds :: [NE.NonEmpty RdrName]
-- Each list represents a RdrName that occurred more than once
-- (the list contains all occurrences)
-- Each list in dup_fields is non-empty
@@ -803,10 +804,10 @@ badPun :: Located RdrName -> SDoc
badPun fld = vcat [text "Illegal use of punning for field" <+> quotes (ppr fld),
text "Use NamedFieldPuns to permit this"]
-dupFieldErr :: HsRecFieldContext -> [RdrName] -> SDoc
+dupFieldErr :: HsRecFieldContext -> NE.NonEmpty RdrName -> SDoc
dupFieldErr ctxt dups
= hsep [text "duplicate field name",
- quotes (ppr (head dups)),
+ quotes (ppr (NE.head dups)),
text "in record", pprRFC ctxt]
pprRFC :: HsRecFieldContext -> SDoc
diff --git a/compiler/rename/RnSource.hs b/compiler/rename/RnSource.hs
index 1ffa6f1f3e..696bb0937e 100644
--- a/compiler/rename/RnSource.hs
+++ b/compiler/rename/RnSource.hs
@@ -64,7 +64,9 @@ import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
import Control.Arrow ( first )
-import Data.List ( sortBy, mapAccumL )
+import Data.List ( mapAccumL )
+import qualified Data.List.NonEmpty as NE
+import Data.List.NonEmpty ( NonEmpty(..) )
import Data.Maybe ( isJust )
import qualified Data.Set as Set ( difference, fromList, toList, null )
@@ -321,7 +323,7 @@ rnSrcWarnDecls _ []
rnSrcWarnDecls bndr_set decls'
= do { -- check for duplicates
- ; mapM_ (\ dups -> let (L loc rdr:lrdr':_) = dups
+ ; mapM_ (\ dups -> let (L loc rdr :| (lrdr':_)) = dups
in addErrAt loc (dupWarnDecl lrdr' rdr))
warn_rdr_dups
; pairs_s <- mapM (addLocM rn_deprec) decls
@@ -342,7 +344,7 @@ rnSrcWarnDecls bndr_set decls'
warn_rdr_dups = findDupRdrNames $ concatMap (\(L _ (Warning ns _)) -> ns)
decls
-findDupRdrNames :: [Located RdrName] -> [[Located RdrName]]
+findDupRdrNames :: [Located RdrName] -> [NonEmpty (Located RdrName)]
findDupRdrNames = findDupsEq (\ x -> \ y -> rdrNameOcc (unLoc x) == rdrNameOcc (unLoc y))
-- look for duplicates among the OccNames;
@@ -746,11 +748,11 @@ rnFamInstDecl doc mb_cls tycon (HsIB { hsib_body = pats }) payload rnPayload
-- Report unused binders on the LHS
-- See Note [Unused type variables in family instances]
- ; let groups :: [[Located RdrName]]
+ ; let groups :: [NonEmpty (Located RdrName)]
groups = equivClasses cmpLocated $
freeKiTyVarsAllVars pat_kity_vars_with_dups
; tv_nms_dups <- mapM (lookupOccRn . unLoc) $
- [ tv | (tv:_:_) <- groups ]
+ [ tv | (tv :| (_:_)) <- groups ]
-- Add to the used variables
-- a) any variables that appear *more than once* on the LHS
-- e.g. F a Int a = Bool
@@ -1531,16 +1533,15 @@ rnRoleAnnots tc_names role_annots
tycon
; return $ RoleAnnotDecl tycon' roles }
-dupRoleAnnotErr :: [LRoleAnnotDecl GhcPs] -> RnM ()
-dupRoleAnnotErr [] = panic "dupRoleAnnotErr"
+dupRoleAnnotErr :: NonEmpty (LRoleAnnotDecl GhcPs) -> RnM ()
dupRoleAnnotErr list
= addErrAt loc $
hang (text "Duplicate role annotations for" <+>
quotes (ppr $ roleAnnotDeclName first_decl) <> colon)
- 2 (vcat $ map pp_role_annot sorted_list)
+ 2 (vcat $ map pp_role_annot $ NE.toList sorted_list)
where
- sorted_list = sortBy cmp_annot list
- (L loc first_decl : _) = sorted_list
+ sorted_list = NE.sortBy cmp_annot list
+ (L loc first_decl :| _) = sorted_list
pp_role_annot (L loc decl) = hang (ppr decl)
4 (text "-- written at" <+> ppr loc)
diff --git a/compiler/rename/RnTypes.hs b/compiler/rename/RnTypes.hs
index f648856fb7..83d28aadd6 100644
--- a/compiler/rename/RnTypes.hs
+++ b/compiler/rename/RnTypes.hs
@@ -62,8 +62,9 @@ import FastString
import Maybes
import qualified GHC.LanguageExtensions as LangExt
-import Data.List ( nubBy, partition )
-import Control.Monad ( unless, when )
+import Data.List ( nubBy, partition )
+import Data.List.NonEmpty ( NonEmpty(..) )
+import Control.Monad ( unless, when )
#include "HsVersions.h"
@@ -974,7 +975,7 @@ bindLHsTyVarBndr doc mb_assoc kv_names tv_names hs_tv_bndr thing_inside
addErrAt loc (vcat [ ki_ty_err_msg name
, pprHsDocContext doc ])
; when (name `elemNameSet` tv_names) $
- dupNamesErr getLoc [L loc name, L (nameSrcSpan name) name] }}
+ dupNamesErr getLoc (L loc name :| [L (nameSrcSpan name) name]) }}
ki_ty_err_msg n = text "Variable" <+> quotes (ppr n) <+>
text "used as a kind variable before being bound" $$
@@ -1346,7 +1347,7 @@ checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM ()
checkPrecMatch op (MG { mg_alts = L _ ms })
= mapM_ check ms
where
- check (L _ (Match _ (L l1 p1 : L l2 p2 :_) _ _))
+ check (L _ (Match { m_pats = L l1 p1 : L l2 p2 :_ }))
= setSrcSpan (combineSrcSpans l1 l2) $
do checkPrec op p1 False
checkPrec op p2 True
@@ -1717,11 +1718,25 @@ extract_hs_tv_bndrs tvs
= do { FKTV bndr_kvs _
<- foldrM extract_lkind emptyFKTV [k | L _ (KindedTyVar _ k) <- tvs]
- ; let locals = map hsLTyVarName tvs
+ ; let locals = map hsLTyVarLocName tvs
+
+ -- These checks are all tested in typecheck/should_fail/T11963
+ ; check_for_mixed_vars bndr_kvs acc_tvs
+ ; check_for_mixed_vars bndr_kvs body_tvs
+ ; check_for_mixed_vars body_tvs acc_kvs
+ ; check_for_mixed_vars body_kvs acc_tvs
+ ; check_for_mixed_vars locals body_kvs
+
; return $
- FKTV (filterOut ((`elem` locals) . unLoc) (bndr_kvs ++ body_kvs)
+ FKTV (filterOut (`elemRdr` locals) (bndr_kvs ++ body_kvs)
++ acc_kvs)
- (filterOut ((`elem` locals) . unLoc) body_tvs ++ acc_tvs) }
+ (filterOut (`elemRdr` locals) body_tvs ++ acc_tvs) }
+ where
+ check_for_mixed_vars :: [Located RdrName] -> [Located RdrName] -> RnM ()
+ check_for_mixed_vars tvs1 tvs2 = mapM_ check tvs1
+ where
+ check tv1 = when (isRdrTyVar (unLoc tv1) && (tv1 `elemRdr` tvs2)) $
+ mixedVarsErr tv1
extract_tv :: TypeOrKind -> Located RdrName -> FreeKiTyVars
-> RnM FreeKiTyVars
@@ -1737,8 +1752,6 @@ extract_tv t_or_k ltv@(L _ tv) acc
mixedVarsErr ltv
; return (FKTV (ltv : kvs) tvs) }
| otherwise = return acc
- where
- elemRdr x = any (eqLocated x)
mixedVarsErr :: Located RdrName -> RnM ()
mixedVarsErr (L loc tv)
@@ -1751,3 +1764,6 @@ mixedVarsErr (L loc tv)
-- just used in this module; seemed convenient here
nubL :: Eq a => [Located a] -> [Located a]
nubL = nubBy eqLocated
+
+elemRdr :: Located RdrName -> [Located RdrName] -> Bool
+elemRdr x = any (eqLocated x)
diff --git a/compiler/rename/RnUtils.hs b/compiler/rename/RnUtils.hs
index 7b2f74f1da..50598f8b49 100644
--- a/compiler/rename/RnUtils.hs
+++ b/compiler/rename/RnUtils.hs
@@ -45,6 +45,7 @@ import FastString
import Control.Monad
import Data.List
import Constants ( mAX_TUPLE_SIZE )
+import qualified Data.List.NonEmpty as NE
import qualified GHC.LanguageExtensions as LangExt
{-
@@ -316,13 +317,13 @@ unknownSubordinateErr doc op -- Doc is "method of class" or
= quotes (ppr op) <+> text "is not a (visible)" <+> doc
-dupNamesErr :: Outputable n => (n -> SrcSpan) -> [n] -> RnM ()
+dupNamesErr :: Outputable n => (n -> SrcSpan) -> NE.NonEmpty n -> RnM ()
dupNamesErr get_loc names
= addErrAt big_loc $
- vcat [text "Conflicting definitions for" <+> quotes (ppr (head names)),
+ vcat [text "Conflicting definitions for" <+> quotes (ppr (NE.head names)),
locations]
where
- locs = map get_loc names
+ locs = map get_loc (NE.toList names)
big_loc = foldr1 combineSrcSpans locs
locations = text "Bound at:" <+> vcat (map ppr (sort locs))
diff --git a/compiler/simplCore/CSE.hs b/compiler/simplCore/CSE.hs
index 83f5ee6a3b..ccbdf3537d 100644
--- a/compiler/simplCore/CSE.hs
+++ b/compiler/simplCore/CSE.hs
@@ -454,7 +454,7 @@ cseExpr _ (Lit lit) = Lit lit
cseExpr env (Var v) = lookupSubst env v
cseExpr env (App f a) = App (cseExpr env f) (tryForCSE env a)
cseExpr env (Tick t e) = Tick t (cseExpr env e)
-cseExpr env (Cast e co) = Cast (cseExpr env e) (substCo (csEnvSubst env) co)
+cseExpr env (Cast e co) = Cast (tryForCSE env e) (substCo (csEnvSubst env) co)
cseExpr env (Lam b e) = let (env', b') = addBinder env b
in Lam b' (cseExpr env' e)
cseExpr env (Let bind e) = let (env', bind') = cseBind NotTopLevel env bind
diff --git a/compiler/simplCore/CallArity.hs b/compiler/simplCore/CallArity.hs
index 0cf0c2f44f..e41e5bdef9 100644
--- a/compiler/simplCore/CallArity.hs
+++ b/compiler/simplCore/CallArity.hs
@@ -350,7 +350,7 @@ Note [Thunks in recursive groups]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We never eta-expand a thunk in a recursive group, on the grounds that if it is
-part of a recursive group, then it will be called multipe times.
+part of a recursive group, then it will be called multiple times.
This is not necessarily true, e.g. it would be safe to eta-expand t2 (but not
t1) in the following code:
diff --git a/compiler/simplCore/OccurAnal.hs b/compiler/simplCore/OccurAnal.hs
index 5dd30aa668..dbe1c48828 100644
--- a/compiler/simplCore/OccurAnal.hs
+++ b/compiler/simplCore/OccurAnal.hs
@@ -2657,12 +2657,9 @@ tagRecBinders lvl body_uds triples
-- 3. Compute final usage details from adjusted RHS details
adj_uds = body_uds +++ combineUsageDetailsList rhs_udss'
- -- 4. Tag each binder with its adjusted details modulo the
- -- join-point-hood decision
- occs = map (lookupDetails adj_uds) bndrs
- occs' | will_be_joins = occs
- | otherwise = map markNonTailCalled occs
- bndrs' = zipWith setBinderOcc occs' bndrs
+ -- 4. Tag each binder with its adjusted details
+ bndrs' = [ setBinderOcc (lookupDetails adj_uds bndr) bndr
+ | bndr <- bndrs ]
-- 5. Drop the binders from the adjusted details and return
usage' = adj_uds `delDetailsList` bndrs
diff --git a/compiler/simplCore/SimplUtils.hs b/compiler/simplCore/SimplUtils.hs
index e6e660b91f..b01955c8be 100644
--- a/compiler/simplCore/SimplUtils.hs
+++ b/compiler/simplCore/SimplUtils.hs
@@ -1785,7 +1785,7 @@ prepareAlts scrut case_bndr' alts
mkCase tries these things
* Note [Nerge nested cases]
-* Note [Elimiante identity case]
+* Note [Eliminate identity case]
* Note [Scrutinee constant folding]
Note [Merge Nested Cases]
diff --git a/compiler/simplCore/Simplify.hs b/compiler/simplCore/Simplify.hs
index 91ed644057..1fc9112fcf 100644
--- a/compiler/simplCore/Simplify.hs
+++ b/compiler/simplCore/Simplify.hs
@@ -566,7 +566,6 @@ That's what the 'go' loop in prepareRhs does
prepareRhs :: TopLevelFlag -> SimplEnv -> OutId -> OutExpr -> SimplM (SimplEnv, OutExpr)
-- See Note [prepareRhs]
-- Adds new floats to the env iff that allows us to return a good RHS
--- See Note [prepareRhs]
prepareRhs top_lvl env id (Cast rhs co) -- Note [Float coercions]
| Pair ty1 _ty2 <- coercionKind co -- Do *not* do this if rhs has an unlifted type
, not (isUnliftedType ty1) -- see Note [Float coercions (unlifted)]
@@ -2700,7 +2699,7 @@ Note [Add unfolding for scrutinee]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In general it's unlikely that a variable scrutinee will appear
in the case alternatives case x of { ...x unlikely to appear... }
-because the binder-swap in OccAnal has got rid of all such occcurrences
+because the binder-swap in OccAnal has got rid of all such occurrences
See Note [Binder swap] in OccAnal.
BUT it is still VERY IMPORTANT to add a suitable unfolding for a
diff --git a/compiler/simplStg/StgCse.hs b/compiler/simplStg/StgCse.hs
index 6bd6adc7ec..b221902768 100644
--- a/compiler/simplStg/StgCse.hs
+++ b/compiler/simplStg/StgCse.hs
@@ -5,9 +5,9 @@ Note [CSE for Stg]
~~~~~~~~~~~~~~~~~~
This module implements a simple common subexpression elimination pass for STG.
This is useful because there are expressions that we want to common up (because
-they are operational equivalent), but that we cannot common up in Core, because
+they are operationally equivalent), but that we cannot common up in Core, because
their types differ.
-This was original reported as #9291.
+This was originally reported as #9291.
There are two types of common code occurrences that we aim for, see
note [Case 1: CSEing allocated closures] and
@@ -16,7 +16,7 @@ note [Case 2: CSEing case binders] below.
Note [Case 1: CSEing allocated closures]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The fist kind of CSE opportunity we aim for is generated by this Haskell code:
+The first kind of CSE opportunity we aim for is generated by this Haskell code:
bar :: a -> (Either Int a, Either Bool a)
bar x = (Right x, Right x)
@@ -137,7 +137,7 @@ data CseEnv = CseEnv
-- * If we remove `let x = Con z` because `let y = Con z` is in scope,
-- we note this here as x ↦ y.
, ce_bndrMap :: IdEnv OutId
- -- If we come across a case expression case x as b of … with a trivial
+ -- ^ If we come across a case expression case x as b of … with a trivial
-- binder, we add b ↦ x to this.
-- This map is *only* used when looking something up in the ce_conAppMap.
-- See Note [Trivial case scrutinee]
@@ -217,7 +217,7 @@ substVar env id = fromMaybe id $ lookupVarEnv (ce_subst env) id
-- Functions to enter binders
--- This is much simpler than the requivalent code in CoreSubst:
+-- This is much simpler than the equivalent code in CoreSubst:
-- * We do not substitute type variables, and
-- * There is nothing relevant in IdInfo at this stage
-- that needs substitutions.
@@ -438,7 +438,7 @@ we first replace v with r2. Next we want to replace Right r2 with r1. But the
ce_conAppMap contains Right a!
Therefore, we add r1 ↦ x to ce_bndrMap when analysing the outer case, and use
-this subsitution before looking Right r2 up in ce_conAppMap, and everything
+this substitution before looking Right r2 up in ce_conAppMap, and everything
works out.
Note [Free variables of an StgClosure]
diff --git a/compiler/specialise/Specialise.hs b/compiler/specialise/Specialise.hs
index 869da640ea..0fb7eb0472 100644
--- a/compiler/specialise/Specialise.hs
+++ b/compiler/specialise/Specialise.hs
@@ -43,9 +43,7 @@ import State
import UniqDFM
import Control.Monad
-#if __GLASGOW_HASKELL__ > 710
import qualified Control.Monad.Fail as MonadFail
-#endif
{-
************************************************************************
@@ -147,7 +145,7 @@ becomes
in
fl
-We still have recusion for non-overloaded functions which we
+We still have recursion for non-overloaded functions which we
specialise, but the recursive call should get specialised to the
same recursive version.
@@ -2289,10 +2287,8 @@ instance Monad SpecM where
z
fail str = SpecM $ fail str
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail.MonadFail SpecM where
fail str = SpecM $ fail str
-#endif
instance MonadUnique SpecM where
getUniqueSupplyM
diff --git a/compiler/typecheck/Inst.hs b/compiler/typecheck/Inst.hs
index 20c3d5cbb9..34e6e71d46 100644
--- a/compiler/typecheck/Inst.hs
+++ b/compiler/typecheck/Inst.hs
@@ -33,7 +33,7 @@ module Inst (
#include "HsVersions.h"
import {-# SOURCE #-} TcExpr( tcPolyExpr, tcSyntaxOp )
-import {-# SOURCE #-} TcUnify( unifyType, unifyKind, noThing )
+import {-# SOURCE #-} TcUnify( unifyType, unifyKind )
import BasicTypes ( IntegralLit(..), SourceText(..) )
import FastString
@@ -324,13 +324,13 @@ instCallConstraints orig preds
where
go pred
| Just (Nominal, ty1, ty2) <- getEqPredTys_maybe pred -- Try short-cut #1
- = do { co <- unifyType noThing ty1 ty2
+ = do { co <- unifyType Nothing ty1 ty2
; return (EvCoercion co) }
-- Try short-cut #2
| Just (tc, args@[_, _, ty1, ty2]) <- splitTyConApp_maybe pred
, tc `hasKey` heqTyConKey
- = do { co <- unifyType noThing ty1 ty2
+ = do { co <- unifyType Nothing ty1 ty2
; return (EvDFunApp (dataConWrapId heqDataCon) args [EvCoercion co]) }
| otherwise
@@ -407,9 +407,10 @@ tcInstBinder _ subst (Anon ty)
| Just (mk, role, k1, k2) <- get_pred_tys_maybe substed_ty
= do { let origin = TypeEqOrigin { uo_actual = k1
, uo_expected = k2
- , uo_thing = Nothing }
+ , uo_thing = Nothing
+ , uo_visible = True }
; co <- case role of
- Nominal -> unifyKind noThing k1 k2
+ Nominal -> unifyKind Nothing k1 k2
Representational -> emitWantedEq origin KindLevel role k1 k2
Phantom -> pprPanic "tcInstBinder Phantom" (ppr ty)
; arg' <- mk co k1 k2
diff --git a/compiler/typecheck/TcArrows.hs b/compiler/typecheck/TcArrows.hs
index b72b9b193c..d56a8d8c74 100644
--- a/compiler/typecheck/TcArrows.hs
+++ b/compiler/typecheck/TcArrows.hs
@@ -239,7 +239,7 @@ tc_cmd env cmd@(HsCmdApp fun arg) (cmd_stk, res_ty)
tc_cmd env
(HsCmdLam (MG { mg_alts = L l [L mtch_loc
- (match@(Match _ pats _maybe_rhs_sig grhss))],
+ (match@(Match { m_pats = pats, m_grhss = grhss }))],
mg_origin = origin }))
(cmd_stk, res_ty)
= addErrCtxt (pprMatchInCtxt match) $
@@ -250,7 +250,8 @@ tc_cmd env
tcPats LambdaExpr pats (map mkCheckExpType arg_tys) $
tc_grhss grhss cmd_stk' (mkCheckExpType res_ty)
- ; let match' = L mtch_loc (Match LambdaExpr pats' Nothing grhss')
+ ; let match' = L mtch_loc (Match { m_ctxt = LambdaExpr, m_pats = pats'
+ , m_type = Nothing, m_grhss = grhss' })
arg_tys = map hsLPatType pats'
cmd' = HsCmdLam (MG { mg_alts = L l [match'], mg_arg_tys = arg_tys
, mg_res_ty = res_ty, mg_origin = origin })
@@ -275,7 +276,7 @@ tc_cmd env
-- Do notation
tc_cmd env (HsCmdDo (L l stmts) _) (cmd_stk, res_ty)
- = do { co <- unifyType noThing unitTy cmd_stk -- Expecting empty argument stack
+ = do { co <- unifyType Nothing unitTy cmd_stk -- Expecting empty argument stack
; stmts' <- tcStmts ArrowExpr (tcArrDoStmt env) stmts res_ty
; return (mkHsCmdWrap (mkWpCastN co) (HsCmdDo (L l stmts') res_ty)) }
diff --git a/compiler/typecheck/TcBinds.hs b/compiler/typecheck/TcBinds.hs
index 4d3c5cb578..16d359c593 100644
--- a/compiler/typecheck/TcBinds.hs
+++ b/compiler/typecheck/TcBinds.hs
@@ -38,7 +38,7 @@ import FamInstEnv( normaliseType )
import FamInst( tcGetFamInstEnvs )
import TyCon
import TcType
-import Type( mkStrLitTy, tidyOpenType, mkTyVarBinder, splitTyConApp_maybe)
+import Type( mkStrLitTy, tidyOpenType, splitTyConApp_maybe)
import TysPrim
import TysWiredIn( cTupleTyConName )
import Id
@@ -67,6 +67,7 @@ import qualified GHC.LanguageExtensions as LangExt
import ConLike
import Control.Monad
+import Data.List.NonEmpty ( NonEmpty(..) )
#include "HsVersions.h"
@@ -717,13 +718,18 @@ tcPolyCheck prag_fn
, bind_fvsf = placeHolderNamesTc
, fun_tick = funBindTicks nm_loc mono_id mod prag_sigs }
- abs_bind = L loc $ AbsBindsSig
- { abs_sig_export = poly_id
- , abs_tvs = skol_tvs
- , abs_ev_vars = ev_vars
- , abs_sig_prags = SpecPrags spec_prags
- , abs_sig_ev_bind = ev_binds
- , abs_sig_bind = L loc bind' }
+ export = ABE { abe_wrap = idHsWrapper
+ , abe_poly = poly_id
+ , abe_mono = mono_id
+ , abe_prags = SpecPrags spec_prags }
+
+ abs_bind = L loc $
+ AbsBinds { abs_tvsa = skol_tvs
+ , abs_ev_varsa = ev_vars
+ , abs_ev_binds = [ev_binds]
+ , abs_exports = [export]
+ , abs_binds = unitBag (L loc bind')
+ , abs_sig = True }
; return (unitBag abs_bind, [poly_id]) }
@@ -787,19 +793,20 @@ tcPolyInfer rec_tc prag_fn tc_sig_fn mono bind_list
; mapM_ (checkOverloadedSig mono) sigs
; traceTc "simplifyInfer call" (ppr tclvl $$ ppr name_taus $$ ppr wanted)
- ; (qtvs, givens, ev_binds)
+ ; (qtvs, givens, ev_binds, insoluble)
<- simplifyInfer tclvl infer_mode sigs name_taus wanted
; let inferred_theta = map evVarPred givens
; exports <- checkNoErrs $
- mapM (mkExport prag_fn qtvs inferred_theta) mono_infos
+ mapM (mkExport prag_fn insoluble qtvs inferred_theta) mono_infos
; loc <- getSrcSpanM
; let poly_ids = map abe_poly exports
abs_bind = L loc $
AbsBinds { abs_tvsa = qtvs
, abs_ev_varsa = givens, abs_ev_binds = [ev_binds]
- , abs_exports = exports, abs_binds = binds' }
+ , abs_exports = exports, abs_binds = binds'
+ , abs_sig = False }
; traceTc "Binding:" (ppr (poly_ids `zip` map idType poly_ids))
; return (unitBag abs_bind, poly_ids) }
@@ -807,6 +814,8 @@ tcPolyInfer rec_tc prag_fn tc_sig_fn mono bind_list
--------------
mkExport :: TcPragEnv
+ -> Bool -- True <=> there was an insoluble type error
+ -- when typechecking the bindings
-> [TyVar] -> TcThetaType -- Both already zonked
-> MonoBindInfo
-> TcM (ABExport GhcTc)
@@ -823,12 +832,12 @@ mkExport :: TcPragEnv
-- Pre-condition: the qtvs and theta are already zonked
-mkExport prag_fn qtvs theta
+mkExport prag_fn insoluble qtvs theta
mono_info@(MBI { mbi_poly_name = poly_name
, mbi_sig = mb_sig
, mbi_mono_id = mono_id })
= do { mono_ty <- zonkTcType (idType mono_id)
- ; poly_id <- mkInferredPolyId qtvs theta poly_name mb_sig mono_ty
+ ; poly_id <- mkInferredPolyId insoluble qtvs theta poly_name mb_sig mono_ty
-- NB: poly_id has a zonked type
; poly_id <- addInlinePrags poly_id prag_sigs
@@ -856,17 +865,19 @@ mkExport prag_fn qtvs theta
; return (ABE { abe_wrap = wrap
-- abe_wrap :: idType poly_id ~ (forall qtvs. theta => mono_ty)
- , abe_poly = poly_id
- , abe_mono = mono_id
- , abe_prags = SpecPrags spec_prags}) }
+ , abe_poly = poly_id
+ , abe_mono = mono_id
+ , abe_prags = SpecPrags spec_prags }) }
where
prag_sigs = lookupPragEnv prag_fn poly_name
sig_ctxt = InfSigCtxt poly_name
-mkInferredPolyId :: [TyVar] -> TcThetaType
+mkInferredPolyId :: Bool -- True <=> there was an insoluble error when
+ -- checking the binding group for this Id
+ -> [TyVar] -> TcThetaType
-> Name -> Maybe TcIdSigInst -> TcType
-> TcM TcId
-mkInferredPolyId qtvs inferred_theta poly_name mb_sig_inst mono_ty
+mkInferredPolyId insoluble qtvs inferred_theta poly_name mb_sig_inst mono_ty
| Just (TISI { sig_inst_sig = sig }) <- mb_sig_inst
, CompleteSig { sig_bndr = poly_id } <- sig
= return poly_id
@@ -894,9 +905,13 @@ mkInferredPolyId qtvs inferred_theta poly_name mb_sig_inst mono_ty
; traceTc "mkInferredPolyId" (vcat [ppr poly_name, ppr qtvs, ppr theta'
, ppr inferred_poly_ty])
- ; addErrCtxtM (mk_inf_msg poly_name inferred_poly_ty) $
+ ; unless insoluble $
+ addErrCtxtM (mk_inf_msg poly_name 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 (Trac #14000) we may report an ambiguity
+ -- error for a rather bogus type.
; return (mkLocalIdOrCoVar poly_name inferred_poly_ty) }
@@ -1146,7 +1161,7 @@ tcVectDecls decls
; return decls'
}
where
- reportVectDups (first:_second:_more)
+ reportVectDups (first :| (_second:_more))
= addErrAt (getSrcSpan first) $
text "Duplicate vectorisation declarations for" <+> ppr first
reportVectDups _ = return ()
@@ -1603,7 +1618,7 @@ data GeneralisationPlan
| CheckGen (LHsBind GhcRn) TcIdSigInfo
-- One FunBind with a signature
- -- Explicit generalisation; there is an AbsBindsSig
+ -- Explicit generalisation
-- A consequence of the no-AbsBinds choice (NoGen) is that there is
-- no "polymorphic Id" and "monmomorphic Id"; there is just the one
diff --git a/compiler/typecheck/TcCanonical.hs b/compiler/typecheck/TcCanonical.hs
index be51914a27..7b259257c4 100644
--- a/compiler/typecheck/TcCanonical.hs
+++ b/compiler/typecheck/TcCanonical.hs
@@ -24,7 +24,6 @@ import FamInstEnv ( FamInstEnvs )
import FamInst ( tcTopNormaliseNewTypeTF_maybe )
import Var
import VarEnv( mkInScopeSet )
-import VarSet( extendVarSetList )
import Outputable
import DynFlags( DynFlags )
import NameSet
@@ -563,6 +562,22 @@ can_eq_nc' _flat rdr_env envs ev ReprEq ty1 ps_ty1 ty2 _
| Just stuff2 <- tcTopNormaliseNewTypeTF_maybe envs rdr_env ty2
= can_eq_newtype_nc ev IsSwapped ty2 stuff2 ty1 ps_ty1
+-- Now, check for tyvars. This must happen before CastTy because we need
+-- to catch casted tyvars, as the flattener might produce these,
+-- due to the fact that flattened types have flattened kinds.
+-- See Note [Flattening].
+-- Note that there can be only one cast on the tyvar because this will
+-- run after the "get rid of casts" case of can_eq_nc' function on the
+-- not-yet-flattened types.
+-- NB: pattern match on True: we want only flat types sent to canEqTyVar.
+-- See also Note [No top-level newtypes on RHS of representational equalities]
+can_eq_nc' True _rdr_env _envs ev eq_rel ty1 ps_ty1 ty2 ps_ty2
+ | Just (tv1, co1) <- getCastedTyVar_maybe ty1
+ = canEqTyVar ev eq_rel NotSwapped tv1 co1 ps_ty1 ty2 ps_ty2
+can_eq_nc' True _rdr_env _envs ev eq_rel ty1 ps_ty1 ty2 ps_ty2
+ | Just (tv2, co2) <- getCastedTyVar_maybe ty2
+ = canEqTyVar ev eq_rel IsSwapped tv2 co2 ps_ty2 ty1 ps_ty1
+
-- Then, get rid of casts
can_eq_nc' flat _rdr_env _envs ev eq_rel (CastTy ty1 co1) _ ty2 ps_ty2
= canEqCast flat ev eq_rel NotSwapped ty1 co1 ty2 ps_ty2
@@ -609,14 +624,6 @@ can_eq_nc' False rdr_env envs ev eq_rel _ ps_ty1 _ ps_ty2
`andWhenContinue` \ new_ev ->
can_eq_nc' True rdr_env envs new_ev eq_rel xi1 xi1 xi2 xi2 }
--- Type variable on LHS or RHS are last.
--- NB: pattern match on True: we want only flat types sent to canEqTyVar.
--- See also Note [No top-level newtypes on RHS of representational equalities]
-can_eq_nc' True _rdr_env _envs ev eq_rel (TyVarTy tv1) ps_ty1 ty2 ps_ty2
- = canEqTyVar ev eq_rel NotSwapped tv1 ps_ty1 ty2 ps_ty2
-can_eq_nc' True _rdr_env _envs ev eq_rel ty1 ps_ty1 (TyVarTy tv2) ps_ty2
- = canEqTyVar ev eq_rel IsSwapped tv2 ps_ty2 ty1 ps_ty1
-
-- We've flattened and the types don't match. Give up.
can_eq_nc' True _rdr_env _envs ev _eq_rel _ ps_ty1 _ ps_ty2
= do { traceTcS "can_eq_nc' catch-all case" (ppr ps_ty1 $$ ppr ps_ty2)
@@ -636,8 +643,7 @@ can_eq_nc_forall :: CtEvidence -> EqRel
can_eq_nc_forall ev eq_rel s1 s2
| CtWanted { ctev_loc = loc, ctev_dest = orig_dest } <- ev
- = do { let free_tvs1 = tyCoVarsOfType s1
- free_tvs2 = tyCoVarsOfType s2
+ = do { let free_tvs = tyCoVarsOfTypes [s1,s2]
(bndrs1, phi1) = tcSplitForAllTyVarBndrs s1
(bndrs2, phi2) = tcSplitForAllTyVarBndrs s2
; if not (equalLength bndrs1 bndrs2)
@@ -648,7 +654,7 @@ can_eq_nc_forall ev eq_rel s1 s2
; canEqHardFailure ev s1 s2 }
else
do { traceTcS "Creating implication for polytype equality" $ ppr ev
- ; let empty_subst1 = mkEmptyTCvSubst $ mkInScopeSet free_tvs1
+ ; let empty_subst1 = mkEmptyTCvSubst $ mkInScopeSet free_tvs
; (subst1, skol_tvs) <- tcInstSkolTyVarsX empty_subst1 $
binderVars bndrs1
@@ -674,8 +680,7 @@ can_eq_nc_forall ev eq_rel s1 s2
go _ _ _ = panic "cna_eq_nc_forall" -- case (s:ss) []
- empty_subst2 = mkEmptyTCvSubst $ mkInScopeSet $
- free_tvs2 `extendVarSetList` skol_tvs
+ empty_subst2 = mkEmptyTCvSubst (getTCvInScope subst1)
; (implic, _ev_binds, all_co) <- buildImplication skol_info skol_tvs [] $
go skol_tvs empty_subst2 bndrs2
@@ -922,7 +927,10 @@ can_eq_app ev NomEq s1 t1 s2 t2
; stopWith ev "Decomposed [D] AppTy" }
| CtWanted { ctev_dest = dest, ctev_loc = loc } <- ev
= do { co_s <- unifyWanted loc Nominal s1 s2
- ; co_t <- unifyWanted loc Nominal t1 t2
+ ; let arg_loc
+ | isNextArgVisible s1 = loc
+ | otherwise = updateCtLocOrigin loc toInvisibleOrigin
+ ; co_t <- unifyWanted arg_loc Nominal t1 t2
; let co = mkAppCo co_s co_t
; setWantedEq dest co
; stopWith ev "Decomposed [W] AppTy" }
@@ -1216,13 +1224,16 @@ canDecomposableTyConAppOK ev eq_rel tc tys1 tys2
-- the following makes a better distinction between "kind" and "type"
-- in error messages
bndrs = tyConBinders tc
- kind_loc = toKindLoc loc
is_kinds = map isNamedTyConBinder bndrs
- new_locs | Just KindLevel <- ctLocTypeOrKind_maybe loc
- = repeat loc
- | otherwise
- = map (\is_kind -> if is_kind then kind_loc else loc) is_kinds
+ is_viss = map isVisibleTyConBinder bndrs
+
+ kind_xforms = map (\is_kind -> if is_kind then toKindLoc else id) is_kinds
+ vis_xforms = map (\is_vis -> if is_vis then id
+ else flip updateCtLocOrigin toInvisibleOrigin)
+ is_viss
+ -- zipWith3 (.) composes its first two arguments and applies it to the third
+ new_locs = zipWith3 (.) kind_xforms vis_xforms (repeat loc)
-- | Call when canonicalizing an equality fails, but if the equality is
-- representational, there is some hope for the future.
@@ -1356,19 +1367,6 @@ isInsolubleOccursCheck does.
See also #10715, which induced this addition.
-Note [No derived kind equalities]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When we're working with a heterogeneous derived equality
-
- [D] (t1 :: k1) ~ (t2 :: k2)
-
-we want to homogenise to establish the kind invariant on CTyEqCans.
-But we can't emit [D] k1 ~ k2 because we wouldn't then be able to
-use the evidence in the homogenised types. So we emit a wanted
-constraint, because we do really need the evidence here.
-
-Thus: no derived kind equalities.
-
-}
canCFunEqCan :: CtEvidence
@@ -1396,54 +1394,120 @@ canCFunEqCan ev fn tys fsk
---------------------
canEqTyVar :: CtEvidence -- ev :: lhs ~ rhs
-> EqRel -> SwapFlag
- -> TcTyVar -> TcType -- lhs: already flat, not a cast
- -> TcType -> TcType -- rhs: already flat, not a cast
+ -> TcTyVar -> CoercionN -- tv1 |> co1
+ -> TcType -- lhs: pretty lhs, already flat
+ -> TcType -> TcType -- rhs: already flat
-> TcS (StopOrContinue Ct)
-canEqTyVar ev eq_rel swapped tv1 ps_ty1 (TyVarTy tv2) _
- | tv1 == tv2
- = canEqReflexive ev eq_rel ps_ty1
+canEqTyVar ev eq_rel swapped tv1 co1 ps_ty1 xi2 ps_xi2
+ | k1 `eqType` k2
+ = canEqTyVarHomo ev eq_rel swapped tv1 co1 ps_ty1 xi2 ps_xi2
+
+ -- See Note [Equalities with incompatible kinds]
+ | CtGiven { ctev_evar = evar } <- ev
+ -- unswapped: tm :: (lhs :: k1) ~ (rhs :: k2)
+ -- swapped : tm :: (rhs :: k2) ~ (lhs :: k1)
+ = do { kind_ev_id <- newBoundEvVarId kind_pty
+ (EvCoercion $
+ if isSwapped swapped
+ then mkTcSymCo $ mkTcKindCo $ mkTcCoVarCo evar
+ else mkTcKindCo $ mkTcCoVarCo evar)
+ -- kind_ev_id :: (k1 :: *) ~ (k2 :: *) (whether swapped or not)
+ ; let kind_ev = CtGiven { ctev_pred = kind_pty
+ , ctev_evar = kind_ev_id
+ , ctev_loc = kind_loc }
+ homo_co = mkSymCo $ mkCoVarCo kind_ev_id
+ rhs' = mkCastTy xi2 homo_co
+ ps_rhs' = mkCastTy ps_xi2 homo_co
+ ; traceTcS "Hetero equality gives rise to given kind equality"
+ (ppr kind_ev_id <+> dcolon <+> ppr kind_pty)
+ ; emitWorkNC [kind_ev]
+ ; type_ev <- newGivenEvVar loc $
+ if isSwapped swapped
+ then ( mkTcEqPredLikeEv ev rhs' lhs
+ , EvCoercion $
+ mkTcCoherenceLeftCo (mkTcCoVarCo evar) homo_co )
+ else ( mkTcEqPredLikeEv ev lhs rhs'
+ , EvCoercion $
+ mkTcCoherenceRightCo (mkTcCoVarCo evar) homo_co )
+ -- unswapped: type_ev :: (lhs :: k1) ~ ((rhs |> sym kind_ev_id) :: k1)
+ -- swapped : type_ev :: ((rhs |> sym kind_ev_id) :: k1) ~ (lhs :: k1)
+ ; canEqTyVarHomo type_ev eq_rel swapped tv1 co1 ps_ty1 rhs' ps_rhs' }
+
+ -- See Note [Equalities with incompatible kinds]
+ | otherwise -- Wanted and Derived
+ -- NB: all kind equalities are Nominal
+ = do { emitNewDerivedEq kind_loc Nominal k1 k2
+ -- kind_ev :: (k1 :: *) ~ (k2 :: *)
+ ; traceTcS "Hetero equality gives rise to derived kind equality" $
+ ppr ev
+ ; continueWith (CIrredEvCan { cc_ev = ev }) }
+
+ where
+ lhs = mkTyVarTy tv1 `mkCastTy` co1
- | swapOverTyVars tv1 tv2
+ Pair _ k1 = coercionKind co1
+ k2 = typeKind xi2
+
+ kind_pty = mkHeteroPrimEqPred liftedTypeKind liftedTypeKind k1 k2
+ kind_loc = mkKindLoc lhs xi2 loc
+
+ loc = ctev_loc ev
+
+-- guaranteed that typeKind lhs == typeKind rhs
+canEqTyVarHomo :: CtEvidence
+ -> EqRel -> SwapFlag
+ -> TcTyVar -> CoercionN -- lhs: tv1 |> co1
+ -> TcType -- pretty lhs
+ -> TcType -> TcType -- rhs (might not be flat)
+ -> TcS (StopOrContinue Ct)
+canEqTyVarHomo ev eq_rel swapped tv1 co1 ps_ty1 ty2 _
+ | Just (tv2, _) <- tcGetCastedTyVar_maybe ty2
+ , tv1 == tv2
+ = canEqReflexive ev eq_rel (mkTyVarTy tv1 `mkCastTy` co1)
+ -- we don't need to check co2 because its type must match co1
+
+ | Just (tv2, co2) <- tcGetCastedTyVar_maybe ty2
+ , swapOverTyVars tv1 tv2
= do { traceTcS "canEqTyVar" (ppr tv1 $$ ppr tv2 $$ ppr swapped)
-- FM_Avoid commented out: see Note [Lazy flattening] in TcFlatten
-- let fmode = FE { fe_ev = ev, fe_mode = FM_Avoid tv1' True }
-- Flatten the RHS less vigorously, to avoid gratuitous flattening
-- True <=> xi2 should not itself be a type-function application
; dflags <- getDynFlags
- ; canEqTyVar2 dflags ev eq_rel (flipSwap swapped) tv2 ps_ty1 }
+ ; canEqTyVar2 dflags ev eq_rel (flipSwap swapped) tv2 co2 ps_ty1 }
-canEqTyVar ev eq_rel swapped tv1 _ _ ps_ty2
+canEqTyVarHomo ev eq_rel swapped tv1 co1 _ _ ps_ty2
= do { dflags <- getDynFlags
- ; canEqTyVar2 dflags ev eq_rel swapped tv1 ps_ty2 }
+ ; canEqTyVar2 dflags ev eq_rel swapped tv1 co1 ps_ty2 }
+-- The RHS here is either not a casted tyvar, or it's a tyvar but we want
+-- to rewrite the LHS to the RHS (as per swapOverTyVars)
canEqTyVar2 :: DynFlags
-> CtEvidence -- lhs ~ rhs (or, if swapped, orhs ~ olhs)
-> EqRel
-> SwapFlag
- -> TcTyVar -- lhs, flat
- -> TcType -- rhs, flat
+ -> TcTyVar -> CoercionN -- lhs = tv |> co, flat
+ -> TcType -- rhs
-> TcS (StopOrContinue Ct)
-- LHS is an inert type variable,
-- and RHS is fully rewritten, but with type synonyms
-- preserved as much as possible
-
-canEqTyVar2 dflags ev eq_rel swapped tv1 xi2
- | Just xi2' <- metaTyVarUpdateOK dflags tv1 xi2 -- No occurs check
+canEqTyVar2 dflags ev eq_rel swapped tv1 co1 orhs
+ | Just nrhs' <- metaTyVarUpdateOK dflags tv1 nrhs -- No occurs check
-- Must do the occurs check even on tyvar/tyvar
-- equalities, in case have x ~ (y :: ..x...)
-- Trac #12593
- = rewriteEqEvidence ev swapped xi1 xi2' co1 co2
+ = rewriteEqEvidence ev swapped nlhs nrhs' rewrite_co1 rewrite_co2
`andWhenContinue` \ new_ev ->
- homogeniseRhsKind new_ev eq_rel xi1 xi2' $ \new_new_ev xi2'' ->
- CTyEqCan { cc_ev = new_new_ev, cc_tyvar = tv1
- , cc_rhs = xi2'', cc_eq_rel = eq_rel }
+ continueWith (CTyEqCan { cc_ev = new_ev, cc_tyvar = tv1
+ , cc_rhs = nrhs', cc_eq_rel = eq_rel })
| otherwise -- For some reason (occurs check, or forall) we can't unify
-- We must not use it for further rewriting!
- = do { traceTcS "canEqTyVar2 can't unify" (ppr tv1 $$ ppr xi2)
- ; rewriteEqEvidence ev swapped xi1 xi2 co1 co2
+ = do { traceTcS "canEqTyVar2 can't unify" (ppr tv1 $$ ppr nrhs)
+ ; rewriteEqEvidence ev swapped nlhs nrhs rewrite_co1 rewrite_co2
`andWhenContinue` \ new_ev ->
- if isInsolubleOccursCheck eq_rel tv1 xi2
+ if isInsolubleOccursCheck eq_rel tv1 nrhs
then do { emitInsoluble (mkNonCanonical new_ev)
-- If we have a ~ [a], it is not canonical, and in particular
-- we don't want to rewrite existing inerts with it, otherwise
@@ -1457,13 +1521,18 @@ canEqTyVar2 dflags ev eq_rel swapped tv1 xi2
-- But, the occurs-check certainly prevents the equality from being
-- canonical, and we might loop if we were to use it in rewriting.
else do { traceTcS "Possibly-soluble occurs check"
- (ppr xi1 $$ ppr xi2)
+ (ppr nlhs $$ ppr nrhs)
; continueWith (CIrredEvCan { cc_ev = new_ev }) } }
where
role = eqRelRole eq_rel
- xi1 = mkTyVarTy tv1
- co1 = mkTcReflCo role xi1
- co2 = mkTcReflCo role xi2
+
+ nlhs = mkTyVarTy tv1
+ nrhs = orhs `mkCastTy` mkTcSymCo co1
+
+ -- rewrite_co1 :: tv1 ~ (tv1 |> co1)
+ -- rewrite_co2 :: (rhs |> sym co1) ~ rhs
+ rewrite_co1 = mkTcReflCo role nlhs `mkTcCoherenceRightCo` co1
+ rewrite_co2 = mkTcReflCo role orhs `mkTcCoherenceLeftCo` mkTcSymCo co1
-- | Solve a reflexive equality constraint
canEqReflexive :: CtEvidence -- ty ~ ty
@@ -1475,75 +1544,6 @@ canEqReflexive ev eq_rel ty
mkTcReflCo (eqRelRole eq_rel) ty)
; stopWith ev "Solved by reflexivity" }
--- See Note [Equalities with incompatible kinds]
-homogeniseRhsKind :: CtEvidence -- ^ the evidence to homogenise
- -> EqRel
- -> TcType -- ^ original LHS
- -> Xi -- ^ original RHS
- -> (CtEvidence -> Xi -> Ct)
- -- ^ how to build the homogenised constraint;
- -- the 'Xi' is the new RHS
- -> TcS (StopOrContinue Ct)
-homogeniseRhsKind ev eq_rel lhs rhs build_ct
- | k1 `tcEqType` k2
- = continueWith (build_ct ev rhs)
-
- | CtGiven { ctev_evar = evar } <- ev
- -- tm :: (lhs :: k1) ~ (rhs :: k2)
- = do { kind_ev_id <- newBoundEvVarId kind_pty
- (EvCoercion $
- mkTcKindCo $ mkTcCoVarCo evar)
- -- kind_ev_id :: (k1 :: *) ~# (k2 :: *)
- ; let kind_ev = CtGiven { ctev_pred = kind_pty
- , ctev_evar = kind_ev_id
- , ctev_loc = kind_loc }
- homo_co = mkSymCo $ mkCoVarCo kind_ev_id
- rhs' = mkCastTy rhs homo_co
- ; traceTcS "Hetero equality gives rise to given kind equality"
- (ppr kind_ev_id <+> dcolon <+> ppr kind_pty)
- ; emitWorkNC [kind_ev]
- ; type_ev <- newGivenEvVar loc
- ( mkTcEqPredLikeEv ev lhs rhs'
- , EvCoercion $
- mkTcCoherenceRightCo (mkTcCoVarCo evar) homo_co )
- -- type_ev :: (lhs :: k1) ~ ((rhs |> sym kind_ev_id) :: k1)
- ; continueWith (build_ct type_ev rhs') }
-
- | otherwise -- Wanted and Derived. See Note [No derived kind equalities]
- -- evar :: (lhs :: k1) ~ (rhs :: k2)
- = do { kind_co <- emitNewWantedEq kind_loc Nominal k1 k2
- -- kind_ev :: (k1 :: *) ~ (k2 :: *)
- ; traceTcS "Hetero equality gives rise to wanted kind equality" $
- ppr (kind_co)
- ; let homo_co = mkSymCo kind_co
- -- homo_co :: k2 ~ k1
- rhs' = mkCastTy rhs homo_co
- ; case ev of
- CtGiven {} -> panic "homogeniseRhsKind"
- CtDerived {} -> continueWith (build_ct (ev { ctev_pred = homo_pred })
- rhs')
- where homo_pred = mkTcEqPredLikeEv ev lhs rhs'
- CtWanted { ctev_dest = dest } -> do
- { (type_ev, hole_co) <- newWantedEq loc role lhs rhs'
- -- type_ev :: (lhs :: k1) ~ (rhs |> sym kind_co :: k1)
- ; setWantedEq dest
- (hole_co `mkTransCo`
- (mkReflCo role rhs
- `mkCoherenceLeftCo` homo_co))
-
- -- dest := hole ; <rhs> |> homo_co :: (lhs :: k1) ~ (rhs :: k2)
- ; continueWith (build_ct type_ev rhs') }}
-
- where
- k1 = typeKind lhs
- k2 = typeKind rhs
-
- kind_pty = mkHeteroPrimEqPred liftedTypeKind liftedTypeKind k1 k2
- kind_loc = mkKindLoc lhs rhs loc
-
- loc = ctev_loc ev
- role = eqRelRole eq_rel
-
{-
Note [Canonical orientation for tyvar/tyvar equality constraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1605,21 +1605,66 @@ the fsk.
Note [Equalities with incompatible kinds]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-canEqLeaf is about to make a CTyEqCan or CFunEqCan; but both have the
-invariant that LHS and RHS satisfy the kind invariants for CTyEqCan,
-CFunEqCan. What if we try to unify two things with incompatible
-kinds?
+What do we do when we have an equality
+
+ (tv :: k1) ~ (rhs :: k2)
+
+where k1 and k2 differ? This Note explores this treacherous area.
+
+First off, the question above is slightly the wrong question. Flattening
+a tyvar will flatten its kind (Note [Flattening] in TcFlatten); flattening
+the kind might introduce a cast. So we might have a casted tyvar on the
+left. We thus revise our test case to
+
+ (tv |> co :: k1) ~ (rhs :: k2)
+
+We must proceed differently here depending on whether we have a Wanted
+or a Given. Consider this:
+
+ [W] w :: (alpha :: k) ~ (Int :: Type)
+
+where k is a skolem. One possible way forward is this:
+
+ [W] co :: k ~ Type
+ [W] w :: (alpha :: k) ~ (Int |> sym co :: k)
+
+The next step will be to unify
+
+ alpha := Int |> sym co
+
+Now, consider what error we'll report if we can't solve the "co"
+wanted. Its CtOrigin is the w wanted... which now reads (after zonking)
+Int ~ Int. The user thus sees that GHC can't solve Int ~ Int, which
+is embarrassing. See #11198 for more tales of destruction.
+
+The reason for this odd behavior is much the same as
+Note [Wanteds do not rewrite Wanteds] in TcRnTypes: note that the
+new `co` is a Wanted. The solution is then not to use `co` to "rewrite"
+-- that is, cast -- `w`, but instead to keep `w` heterogeneous and irreducible.
+Given that we're not using `co`, there is no reason to collect evidence
+for it, so `co` is born a Derived. When the Derived is solved (by unification),
+the original wanted (`w`) will get kicked out.
+
+Note that, if we had [G] co1 :: k ~ Type available, then none of this code would
+trigger, because flattening would have rewritten k to Type. That is,
+`w` would look like [W] (alpha |> co1 :: Type) ~ (Int :: Type), and the tyvar
+case will trigger, correctly rewriting alpha to (Int |> sym co1).
-eg a ~ b where a::*, b::*->*
-or a ~ b where a::*, b::k, k is a kind variable
+Successive canonicalizations of the same Wanted may produce
+duplicate Deriveds. Similar duplications can happen with fundeps, and there
+seems to be no easy way to avoid. I expect this case to be rare.
-The CTyEqCan compatKind invariant is important. If we make a CTyEqCan
-for a~b, then we might well *substitute* 'b' for 'a', and that might make
-a well-kinded type ill-kinded; and that is bad (eg typeKind can crash, see
-Trac #7696).
+For Givens, this problem doesn't bite, so a heterogeneous Given gives
+rise to a Given kind equality. No Deriveds here. We thus homogenise
+the Given (see the "homo_co" in the Given case in canEqTyVar) and
+carry on with a homogeneous equality constraint.
-So instead for these ill-kinded equalities we homogenise the RHS of the
-equality, emitting new constraints as necessary.
+Separately, I (Richard E) spent some time pondering what to do in the case
+that we have [W] (tv |> co1 :: k1) ~ (tv |> co2 :: k2) where k1 and k2
+differ. Note that the tv is the same. (This case is handled as the first
+case in canEqTyVarHomo.) At one point, I thought we could solve this limited
+form of heterogeneous Wanted, but I then reconsidered and now treat this case
+just like any other heterogeneous Wanted.
Note [Type synonyms and canonicalization]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/compiler/typecheck/TcClassDcl.hs b/compiler/typecheck/TcClassDcl.hs
index c420f900c6..4531d0f9ce 100644
--- a/compiler/typecheck/TcClassDcl.hs
+++ b/compiler/typecheck/TcClassDcl.hs
@@ -14,6 +14,7 @@ module TcClassDcl ( tcClassSigs, tcClassDecl2,
tcClassMinimalDef,
HsSigFun, mkHsSigFun,
tcMkDeclCtxt, tcAddDeclCtxt, badMethodErr,
+ instDeclCtxt1, instDeclCtxt2, instDeclCtxt3,
tcATDefault
) where
@@ -278,14 +279,15 @@ tcDefMeth clas tyvars this_dict binds_in hs_sig_fn prag_fn
(L bind_loc lm_bind)
; let export = ABE { abe_poly = global_dm_id
- , abe_mono = local_dm_id
- , abe_wrap = idHsWrapper
- , abe_prags = IsDefaultMethod }
- full_bind = AbsBinds { abs_tvsa = tyvars
- , abs_ev_varsa = [this_dict]
+ , abe_mono = local_dm_id
+ , abe_wrap = idHsWrapper
+ , abe_prags = IsDefaultMethod }
+ full_bind = AbsBinds { abs_tvsa = tyvars
+ , abs_ev_varsa = [this_dict]
, abs_exports = [export]
, abs_ev_binds = [ev_binds]
- , abs_binds = tc_bind }
+ , abs_binds = tc_bind
+ , abs_sig = True }
; return (unitBag (L bind_loc full_bind)) }
@@ -460,9 +462,25 @@ warningMinimalDefIncomplete mindef
, nest 2 (pprBooleanFormulaNice mindef)
, text "but there is no default implementation." ]
-tcATDefault :: Bool -- If a warning should be emitted when a default instance
- -- definition is not provided by the user
- -> SrcSpan
+instDeclCtxt1 :: LHsSigType GhcRn -> SDoc
+instDeclCtxt1 hs_inst_ty
+ = inst_decl_ctxt (ppr (getLHsInstDeclHead hs_inst_ty))
+
+instDeclCtxt2 :: Type -> SDoc
+instDeclCtxt2 dfun_ty
+ = instDeclCtxt3 cls tys
+ where
+ (_,_,cls,tys) = tcSplitDFunTy dfun_ty
+
+instDeclCtxt3 :: Class -> [Type] -> SDoc
+instDeclCtxt3 cls cls_tys
+ = inst_decl_ctxt (ppr (mkClassPred cls cls_tys))
+
+inst_decl_ctxt :: SDoc -> SDoc
+inst_decl_ctxt doc = hang (text "In the instance declaration for")
+ 2 (quotes doc)
+
+tcATDefault :: SrcSpan
-> TCvSubst
-> NameSet
-> ClassATItem
@@ -470,7 +488,7 @@ tcATDefault :: Bool -- If a warning should be emitted when a default instance
-- ^ Construct default instances for any associated types that
-- aren't given a user definition
-- Returns [] or singleton
-tcATDefault emit_warn loc inst_subst defined_ats (ATI fam_tc defs)
+tcATDefault loc inst_subst defined_ats (ATI fam_tc defs)
-- User supplied instances ==> everything is OK
| tyConName fam_tc `elemNameSet` defined_ats
= return []
@@ -502,7 +520,7 @@ tcATDefault emit_warn loc inst_subst defined_ats (ATI fam_tc defs)
-- No defaults ==> generate a warning
| otherwise -- defs = Nothing
- = do { when emit_warn $ warnMissingAT (tyConName fam_tc)
+ = do { warnMissingAT (tyConName fam_tc)
; return [] }
where
subst_tv subst tc_tv
diff --git a/compiler/typecheck/TcDeriv.hs b/compiler/typecheck/TcDeriv.hs
index 96c7764c7d..82f17c201e 100644
--- a/compiler/typecheck/TcDeriv.hs
+++ b/compiler/typecheck/TcDeriv.hs
@@ -21,7 +21,7 @@ import FamInst
import TcDerivInfer
import TcDerivUtils
import TcValidity( allDistinctTyVars )
-import TcClassDcl( tcATDefault, tcMkDeclCtxt )
+import TcClassDcl( instDeclCtxt3, tcATDefault, tcMkDeclCtxt )
import TcEnv
import TcGenDeriv -- Deriv stuff
import InstEnv
@@ -1600,8 +1600,9 @@ genInst spec@(DS { ds_tvs = tvs, ds_tc = rep_tycon
, ds_mechanism = mechanism, ds_tys = tys
, ds_cls = clas, ds_loc = loc })
= do (meth_binds, deriv_stuff, unusedNames)
- <- genDerivStuff mechanism loc clas rep_tycon tys tvs
- let mk_inst_info theta = do
+ <- set_span_and_ctxt $
+ genDerivStuff mechanism loc clas rep_tycon tys tvs
+ let mk_inst_info theta = set_span_and_ctxt $ do
inst_spec <- newDerivClsInst theta spec
doDerivInstErrorChecks2 clas inst_spec mechanism
traceTc "newder" (ppr inst_spec)
@@ -1624,6 +1625,9 @@ genInst spec@(DS { ds_tvs = tvs, ds_tc = rep_tycon
| otherwise
= []
+ set_span_and_ctxt :: TcM a -> TcM a
+ set_span_and_ctxt = setSrcSpan loc . addErrCtxt (instDeclCtxt3 clas tys)
+
doDerivInstErrorChecks1 :: Class -> [Type] -> TyCon -> [Type] -> TyCon
-> DerivContext -> Bool -> DerivSpecMechanism
-> TcM ()
@@ -1665,10 +1669,8 @@ doDerivInstErrorChecks2 clas clas_inst mechanism
DerivSpecStock{} -> False
_ -> True
- gen_inst_err = hang (text ("Generic instances can only be derived in "
- ++ "Safe Haskell using the stock strategy.") $+$
- text "In the following instance:")
- 2 (pprInstanceHdr clas_inst)
+ gen_inst_err = text "Generic instances can only be derived in"
+ <+> text "Safe Haskell using the stock strategy."
genDerivStuff :: DerivSpecMechanism -> SrcSpan -> Class
-> TyCon -> [Type] -> [TyVar]
@@ -1694,7 +1696,7 @@ genDerivStuff mechanism loc clas tycon inst_tys tyvars
-- unless -XDeriveAnyClass is enabled.
ASSERT2( isValid (canDeriveAnyClass dflags)
, ppr "genDerivStuff: bad derived class" <+> ppr clas )
- mapM (tcATDefault False loc mini_subst emptyNameSet)
+ mapM (tcATDefault loc mini_subst emptyNameSet)
(classATItems clas)
return ( emptyBag -- No method bindings are needed...
, listToBag (map DerivFamInst (concat tyfam_insts))
@@ -1755,8 +1757,8 @@ is used:
In the latter case, we must take care to check if C has any associated type
families with default instances, because -XDeriveAnyClass will never provide
an implementation for them. We "fill in" the default instances using the
-tcATDefault function from TcClsDcl (which is also used in TcInstDcls to handle
-the empty instance declaration case).
+tcATDefault function from TcClassDcl (which is also used in TcInstDcls to
+handle the empty instance declaration case).
Note [Deriving strategies]
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/compiler/typecheck/TcDerivInfer.hs b/compiler/typecheck/TcDerivInfer.hs
index 02c0103eec..7d39c31b7b 100644
--- a/compiler/typecheck/TcDerivInfer.hs
+++ b/compiler/typecheck/TcDerivInfer.hs
@@ -67,10 +67,43 @@ inferConstraints :: [TyVar] -> Class -> [TcType] -> TcType
inferConstraints tvs main_cls cls_tys inst_ty
rep_tc rep_tc_args
mechanism
- | is_generic && not is_anyclass -- Generic constraints are easy
+ = do { (inferred_constraints, tvs', inst_tys') <- infer_constraints
+ ; traceTc "inferConstraints" $ vcat
+ [ ppr main_cls <+> ppr inst_tys'
+ , ppr inferred_constraints
+ ]
+ ; return ( sc_constraints ++ inferred_constraints
+ , tvs', inst_tys' ) }
+ where
+ is_anyclass = isDerivSpecAnyClass mechanism
+ infer_constraints
+ | is_anyclass = inferConstraintsDAC tvs main_cls inst_tys
+ | otherwise = inferConstraintsDataConArgs tvs main_cls cls_tys inst_ty
+ rep_tc rep_tc_args
+
+ inst_tys = cls_tys ++ [inst_ty]
+
+ -- Constraints arising from superclasses
+ -- See Note [Superclasses of derived instance]
+ cls_tvs = classTyVars main_cls
+ sc_constraints = ASSERT2( equalLength cls_tvs inst_tys
+ , ppr main_cls <+> ppr inst_tys )
+ [ mkThetaOrigin DerivOrigin TypeLevel [] [] $
+ substTheta cls_subst (classSCTheta main_cls) ]
+ cls_subst = ASSERT( equalLength cls_tvs inst_tys )
+ zipTvSubst cls_tvs inst_tys
+
+-- | Like 'inferConstraints', but used only in the case of deriving strategies
+-- where the constraints are inferred by inspecting the fields of each data
+-- constructor (i.e., stock- and newtype-deriving).
+inferConstraintsDataConArgs
+ :: [TyVar] -> Class -> [TcType] -> TcType -> TyCon -> [TcType]
+ -> TcM ([ThetaOrigin], [TyVar], [TcType])
+inferConstraintsDataConArgs tvs main_cls cls_tys inst_ty rep_tc rep_tc_args
+ | is_generic -- Generic constraints are easy
= return ([], tvs, inst_tys)
- | is_generic1 && not is_anyclass -- Generic1 needs Functor
+ | is_generic1 -- Generic1 needs Functor
= ASSERT( rep_tc_tvs `lengthExceeds` 0 ) -- See Note [Getting base classes]
ASSERT( cls_tys `lengthIs` 1 ) -- Generic1 has a single kind variable
do { functorClass <- tcLookupClass functorClassName
@@ -82,20 +115,15 @@ inferConstraints tvs main_cls cls_tys inst_ty
ASSERT2( equalLength rep_tc_tvs all_rep_tc_args
, ppr main_cls <+> ppr rep_tc
$$ ppr rep_tc_tvs $$ ppr all_rep_tc_args )
- do { (arg_constraints, tvs', inst_tys') <- infer_constraints
- ; traceTc "inferConstraints" $ vcat
+ do { (arg_constraints, tvs', inst_tys')
+ <- con_arg_constraints get_std_constrained_tys
+ ; traceTc "inferConstraintsDataConArgs" $ vcat
[ ppr main_cls <+> ppr inst_tys'
, ppr arg_constraints
]
- ; return (stupid_constraints ++ extra_constraints
- ++ sc_constraints ++ arg_constraints
+ ; return ( stupid_constraints ++ extra_constraints ++ arg_constraints
, tvs', inst_tys') }
where
- is_anyclass = isDerivSpecAnyClass mechanism
- infer_constraints
- | is_anyclass = inferConstraintsDAC main_cls tvs inst_tys
- | otherwise = con_arg_constraints get_std_constrained_tys
-
tc_binders = tyConBinders rep_tc
choose_level bndr
| isNamedTyConBinder bndr = KindLevel
@@ -187,15 +215,7 @@ inferConstraints tvs main_cls cls_tys inst_ty
all_rep_tc_args = rep_tc_args ++ map mkTyVarTy
(drop (length rep_tc_args) rep_tc_tvs)
- -- Constraints arising from superclasses
- -- See Note [Superclasses of derived instance]
- cls_tvs = classTyVars main_cls
inst_tys = cls_tys ++ [inst_ty]
- sc_constraints = ASSERT2( equalLength cls_tvs inst_tys, ppr main_cls <+> ppr rep_tc)
- [ mkThetaOrigin DerivOrigin TypeLevel [] [] $
- substTheta cls_subst (classSCTheta main_cls) ]
- cls_subst = ASSERT( equalLength cls_tvs inst_tys )
- zipTvSubst cls_tvs inst_tys
-- Stupid constraints
stupid_constraints = [ mkThetaOrigin DerivOrigin TypeLevel [] [] $
@@ -240,9 +260,9 @@ typeToTypeKind = liftedTypeKind `mkFunTy` liftedTypeKind
-- See Note [Gathering and simplifying constraints for DeriveAnyClass]
-- for an explanation of how these constraints are used to determine the
-- derived instance context.
-inferConstraintsDAC :: Class -> [TyVar] -> [TcType]
+inferConstraintsDAC :: [TyVar] -> Class -> [TcType]
-> TcM ([ThetaOrigin], [TyVar], [TcType])
-inferConstraintsDAC cls tvs inst_tys
+inferConstraintsDAC tvs cls inst_tys
= do { let gen_dms = [ (sel_id, dm_ty)
| (sel_id, Just (_, GenericDM dm_ty)) <- classOpItems cls ]
@@ -760,7 +780,7 @@ Similarly for 'baz', givng the constraint C2
~ Maybe s -> Maybe s -> Bool)
In this case baz has no local quantification, so the implication
-constraint has no local skolems and there are no unificaiton
+constraint has no local skolems and there are no unification
variables.
[STEP DAC SOLVE]
diff --git a/compiler/typecheck/TcDerivUtils.hs b/compiler/typecheck/TcDerivUtils.hs
index 09876afb70..05d323c8ff 100644
--- a/compiler/typecheck/TcDerivUtils.hs
+++ b/compiler/typecheck/TcDerivUtils.hs
@@ -6,7 +6,6 @@
Error-checking and other utilities for @deriving@ clauses or declarations.
-}
-{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE TypeFamilies #-}
module TcDerivUtils (
diff --git a/compiler/typecheck/TcErrors.hs b/compiler/typecheck/TcErrors.hs
index 016b98521d..925e58068e 100644
--- a/compiler/typecheck/TcErrors.hs
+++ b/compiler/typecheck/TcErrors.hs
@@ -53,17 +53,17 @@ import SrcLoc
import DynFlags
import ListSetOps ( equivClasses )
import Maybes
+import Pair
import qualified GHC.LanguageExtensions as LangExt
import FV ( fvVarList, unionFV )
import Control.Monad ( when )
+import Data.Foldable ( toList )
import Data.List ( partition, mapAccumL, nub, sortBy, unfoldr )
import qualified Data.Set as Set
-#if __GLASGOW_HASKELL__ > 710
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
-#endif
{-
@@ -246,10 +246,8 @@ Unfortunately, unlike the context, the relevant bindings are added in
multiple places so they have to be in the Report.
-}
-#if __GLASGOW_HASKELL__ > 710
instance Semigroup Report where
Report a1 b1 c1 <> Report a2 b2 c2 = Report (a1 ++ a2) (b1 ++ b2) (c1 ++ c2)
-#endif
instance Monoid Report where
mempty = Report [] [] []
@@ -478,19 +476,22 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_insol = insols, wc_impl
-- (see TcRnTypes.trulyInsoluble) is caught here, otherwise
-- we might suppress its error message, and proceed on past
-- type checking to get a Lint error later
- report1 = [ ("custom_error", is_user_type_error,
- True, mkUserTypeErrorReporter)
+ report1 = [ ("custom_error", is_user_type_error,True, mkUserTypeErrorReporter)
, given_eq_spec
- , ("insoluble2", utterly_wrong, True, mkGroupReporter mkEqErr)
- , ("skolem eq1", very_wrong, True, mkSkolReporter)
- , ("skolem eq2", skolem_eq, True, mkSkolReporter)
- , ("non-tv eq", non_tv_eq, True, mkSkolReporter)
- , ("Out of scope", is_out_of_scope, True, mkHoleReporter)
- , ("Holes", is_hole, False, mkHoleReporter)
+ , ("insoluble2", utterly_wrong, True, mkGroupReporter mkEqErr)
+ , ("skolem eq1", very_wrong, True, mkSkolReporter)
+ , ("skolem eq2", skolem_eq, True, mkSkolReporter)
+ , ("non-tv eq", non_tv_eq, True, mkSkolReporter)
+ , ("Out of scope", is_out_of_scope, True, mkHoleReporter)
+ , ("Holes", is_hole, False, mkHoleReporter)
-- The only remaining equalities are alpha ~ ty,
-- where alpha is untouchable; and representational equalities
- , ("Other eqs", is_equality, False, mkGroupReporter mkEqErr) ]
+ -- Prefer homogeneous equalities over hetero, because the
+ -- former might be holding up the latter.
+ -- See Note [Equalities with incompatible kinds] in TcCanonical
+ , ("Homo eqs", is_homo_equality, True, mkGroupReporter mkEqErr)
+ , ("Other eqs", is_equality, False, mkGroupReporter mkEqErr) ]
-- report2: we suppress these if there are insolubles elsewhere in the tree
report2 = [ ("Implicit params", is_ip, False, mkGroupReporter mkIPErr)
@@ -527,6 +528,9 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_insol = insols, wc_impl
is_user_type_error ct _ = isUserTypeErrorCt ct
+ is_homo_equality _ (EqPred _ ty1 ty2) = typeKind ty1 `tcEqType` typeKind ty2
+ is_homo_equality _ _ = False
+
is_equality _ (EqPred {}) = True
is_equality _ _ = False
@@ -694,7 +698,7 @@ mkGroupReporter :: (ReportErrCtxt -> [Ct] -> TcM ErrMsg)
-- Group together errors from same location,
-- and report only the first (to avoid a cascade)
mkGroupReporter mk_err ctxt cts
- = mapM_ (reportGroup mk_err ctxt) (equivClasses cmp_loc cts)
+ = mapM_ (reportGroup mk_err ctxt . toList) (equivClasses cmp_loc cts)
eq_lhs_type :: Ct -> Ct -> Bool
eq_lhs_type ct1 ct2
@@ -815,17 +819,21 @@ maybeAddDeferredHoleBinding ctxt err ct
tryReporters :: ReportErrCtxt -> [ReporterSpec] -> [Ct] -> TcM (ReportErrCtxt, [Ct])
-- Use the first reporter in the list whose predicate says True
tryReporters ctxt reporters cts
- = do { traceTc "tryReporters {" (ppr cts)
- ; (ctxt', cts') <- go ctxt reporters cts
+ = do { let (vis_cts, invis_cts) = partition (isVisibleOrigin . ctOrigin) cts
+ ; traceTc "tryReporters {" (ppr vis_cts $$ ppr invis_cts)
+ ; (ctxt', cts') <- go ctxt reporters vis_cts invis_cts
; traceTc "tryReporters }" (ppr cts')
; return (ctxt', cts') }
where
- go ctxt [] cts
- = return (ctxt, cts)
-
- go ctxt (r : rs) cts
- = do { (ctxt', cts') <- tryReporter ctxt r cts
- ; go ctxt' rs cts' }
+ go ctxt [] vis_cts invis_cts
+ = return (ctxt, vis_cts ++ invis_cts)
+
+ go ctxt (r : rs) vis_cts invis_cts
+ -- always look at *visible* Origins before invisible ones
+ -- this is the whole point of isVisibleOrigin
+ = do { (ctxt', vis_cts') <- tryReporter ctxt r vis_cts
+ ; (ctxt'', invis_cts') <- tryReporter ctxt' r invis_cts
+ ; go ctxt'' rs vis_cts' invis_cts' }
-- Carry on with the rest, because we must make
-- deferred bindings for them if we have -fdefer-type-errors
-- But suppress their error messages
@@ -1447,9 +1455,9 @@ the unsolved (t ~ Bool), t won't look like an untouchable meta-var
any more. So we don't assert that it is.
-}
-mkEqErr :: ReportErrCtxt -> [Ct] -> TcM ErrMsg
-- Don't have multiple equality errors from the same location
-- E.g. (Int,Bool) ~ (Bool,Int) one error will do!
+mkEqErr :: ReportErrCtxt -> [Ct] -> TcM ErrMsg
mkEqErr ctxt (ct:_) = mkEqErr1 ctxt ct
mkEqErr _ [] = panic "mkEqErr"
@@ -1589,9 +1597,12 @@ mkEqErr_help :: DynFlags -> ReportErrCtxt -> Report
-> Maybe SwapFlag -- Nothing <=> not sure
-> TcType -> TcType -> TcM ErrMsg
mkEqErr_help dflags ctxt report ct oriented ty1 ty2
- | Just tv1 <- tcGetTyVar_maybe ty1 = mkTyVarEqErr dflags ctxt report ct oriented tv1 ty2
- | Just tv2 <- tcGetTyVar_maybe ty2 = mkTyVarEqErr dflags ctxt report ct swapped tv2 ty1
- | otherwise = reportEqErr ctxt report ct oriented ty1 ty2
+ | Just (tv1, co1) <- tcGetCastedTyVar_maybe ty1
+ = mkTyVarEqErr dflags ctxt report ct oriented tv1 co1 ty2
+ | Just (tv2, co2) <- tcGetCastedTyVar_maybe ty2
+ = mkTyVarEqErr dflags ctxt report ct swapped tv2 co2 ty1
+ | otherwise
+ = reportEqErr ctxt report ct oriented ty1 ty2
where
swapped = fmap flipSwap oriented
@@ -1606,13 +1617,13 @@ reportEqErr ctxt report ct oriented ty1 ty2
mkTyVarEqErr, mkTyVarEqErr'
:: DynFlags -> ReportErrCtxt -> Report -> Ct
- -> Maybe SwapFlag -> TcTyVar -> TcType -> TcM ErrMsg
+ -> Maybe SwapFlag -> TcTyVar -> TcCoercionN -> TcType -> TcM ErrMsg
-- tv1 and ty2 are already tidied
-mkTyVarEqErr dflags ctxt report ct oriented tv1 ty2
- = do { traceTc "mkTyVarEqErr" (ppr ct $$ ppr tv1 $$ ppr ty2)
- ; mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2 }
+mkTyVarEqErr dflags ctxt report ct oriented tv1 co1 ty2
+ = do { traceTc "mkTyVarEqErr" (ppr ct $$ ppr tv1 $$ ppr co1 $$ ppr ty2)
+ ; mkTyVarEqErr' dflags ctxt report ct oriented tv1 co1 ty2 }
-mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2
+mkTyVarEqErr' dflags ctxt report ct oriented tv1 co1 ty2
| not insoluble_occurs_check -- See Note [Occurs check wins]
, isUserSkolem ctxt tv1 -- ty2 won't be a meta-tyvar, or else the thing would
-- be oriented the other way round;
@@ -1661,6 +1672,23 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2
-- to be helpful since this is just an unimplemented feature.
; mkErrorMsgFromCt ctxt ct $ report { report_important = [msg] } }
+ -- check for heterogeneous equality next; see Note [Equalities with incompatible kinds]
+ -- in TcCanonical
+ | not (k1 `tcEqType` k2)
+ = do { let main_msg = addArising (ctOrigin ct) $
+ vcat [ hang (text "Kind mismatch: cannot unify" <+>
+ parens (ppr tv1 <+> dcolon <+> ppr (tyVarKind tv1)) <+>
+ text "with:")
+ 2 (sep [ppr ty2, dcolon, ppr k2])
+ , text "Their kinds differ." ]
+ cast_msg
+ | isTcReflexiveCo co1 = empty
+ | otherwise = text "NB:" <+> ppr tv1 <+>
+ text "was casted to have kind" <+>
+ quotes (ppr k1)
+
+ ; mkErrorMsgFromCt ctxt ct (mconcat [important main_msg, important cast_msg, report]) }
+
-- If the immediately-enclosing implication has 'tv' a skolem, and
-- we know by now its an InferSkol kind of skolem, then presumably
-- it started life as a SigTv, else it'd have been unified, given
@@ -1706,7 +1734,7 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2
, Implic { ic_env = env, ic_given = given
, ic_tclvl = lvl, ic_info = skol_info } <- implic
= ASSERT2( not (isTouchableMetaTyVar lvl tv1)
- , ppr tv1 ) -- See Note [Error messages for untouchables]
+ , ppr tv1 $$ ppr lvl ) -- See Note [Error messages for untouchables]
do { let msg = important $ misMatchMsg ct oriented ty1 ty2
tclvl_extra = important $
nest 2 $
@@ -1725,6 +1753,9 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2
-- Consider an ambiguous top-level constraint (a ~ F a)
-- Not an occurs check, because F is a type function.
where
+ Pair _ k1 = tcCoercionKind co1
+ k2 = typeKind ty2
+
ty1 = mkTyVarTy tv1
occ_check_expand = occCheckForErrors dflags tv1 ty2
insoluble_occurs_check = isInsolubleOccursCheck (ctEqRel ct) tv1 ty2
@@ -1962,7 +1993,7 @@ mkExpectedActualMsg ty1 ty2 (TypeEqOrigin { uo_actual = act
-> empty
thing_msg = case maybe_thing of
- Just thing -> \_ -> quotes (ppr thing) <+> text "is"
+ Just thing -> \_ -> quotes thing <+> text "is"
Nothing -> \vowel -> text "got a" <>
if vowel then char 'n' else empty
msg2 = sep [ text "Expecting a lifted type, but"
@@ -1972,12 +2003,12 @@ mkExpectedActualMsg ty1 ty2 (TypeEqOrigin { uo_actual = act
msg4 = maybe_num_args_msg $$
sep [ text "Expected a type, but"
, maybe (text "found something with kind")
- (\thing -> quotes (ppr thing) <+> text "has kind")
+ (\thing -> quotes thing <+> text "has kind")
maybe_thing
, quotes (ppr act) ]
msg5 th = hang (text "Expected" <+> kind_desc <> comma)
- 2 (text "but" <+> quotes (ppr th) <+> text "has kind" <+>
+ 2 (text "but" <+> quotes th <+> text "has kind" <+>
quotes (ppr act))
where
kind_desc | isConstraintKind exp = text "a constraint"
@@ -1989,17 +2020,13 @@ mkExpectedActualMsg ty1 ty2 (TypeEqOrigin { uo_actual = act
-> let n_act = count_args act
n_exp = count_args exp in
case n_act - n_exp of
- n | n /= 0
+ n | n > 0 -- we don't know how many args there are, so don't
+ -- recommend removing args that aren't
, Just thing <- maybe_thing
- , case errorThingNumArgs_maybe thing of
- Nothing -> n > 0
- Just num_act_args -> num_act_args >= -n
- -- don't report to strip off args that aren't there
-> Just $ text "Expecting" <+> speakN (abs n) <+>
- more_or_fewer <+> quotes (ppr thing)
+ more <+> quotes thing
where
- more_or_fewer
- | n < 0 = text "fewer arguments to"
+ more
| n == 1 = text "more argument to"
| otherwise = text "more arguments to" -- n > 1
_ -> Nothing
diff --git a/compiler/typecheck/TcEvidence.hs b/compiler/typecheck/TcEvidence.hs
index eb809ab013..4f305c6920 100644
--- a/compiler/typecheck/TcEvidence.hs
+++ b/compiler/typecheck/TcEvidence.hs
@@ -33,7 +33,7 @@ module TcEvidence (
mkTcKindCo,
tcCoercionKind, coVarsOfTcCo,
mkTcCoVarCo,
- isTcReflCo,
+ isTcReflCo, isTcReflexiveCo,
tcCoercionRole,
unwrapIP, wrapIP
) where
@@ -115,6 +115,10 @@ tcCoercionRole :: TcCoercion -> Role
coVarsOfTcCo :: TcCoercion -> TcTyCoVarSet
isTcReflCo :: TcCoercion -> Bool
+-- | This version does a slow check, calculating the related types and seeing
+-- if they are equal.
+isTcReflexiveCo :: TcCoercion -> Bool
+
mkTcReflCo = mkReflCo
mkTcSymCo = mkSymCo
mkTcTransCo = mkTransCo
@@ -143,7 +147,7 @@ tcCoercionKind = coercionKind
tcCoercionRole = coercionRole
coVarsOfTcCo = coVarsOfCo
isTcReflCo = isReflCo
-
+isTcReflexiveCo = isReflexiveCo
{-
%************************************************************************
diff --git a/compiler/typecheck/TcExpr.hs b/compiler/typecheck/TcExpr.hs
index 0e1e8662bf..195ba0139e 100644
--- a/compiler/typecheck/TcExpr.hs
+++ b/compiler/typecheck/TcExpr.hs
@@ -166,8 +166,8 @@ NB: The res_ty is always deeply skolemised.
-}
tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId)
-tcExpr (HsVar (L _ name)) res_ty = tcCheckId name res_ty
-tcExpr (HsUnboundVar uv) res_ty = tcUnboundId uv res_ty
+tcExpr (HsVar (L _ name)) res_ty = tcCheckId name res_ty
+tcExpr e@(HsUnboundVar uv) res_ty = tcUnboundId e uv res_ty
tcExpr e@(HsApp {}) res_ty = tcApp1 e res_ty
tcExpr e@(HsAppType {}) res_ty = tcApp1 e res_ty
@@ -370,7 +370,7 @@ tcExpr expr@(OpApp arg1 op fix arg2) res_ty
; let doc = text "The first argument of ($) takes"
orig1 = lexprCtOrigin arg1
; (wrap_arg1, [arg2_sigma], op_res_ty) <-
- matchActualFunTys doc orig1 (Just arg1) 1 arg1_ty
+ matchActualFunTys doc orig1 (Just (unLoc arg1)) 1 arg1_ty
-- We have (arg1 $ arg2)
-- So: arg1_ty = arg2_ty -> op_res_ty
@@ -385,7 +385,7 @@ tcExpr expr@(OpApp arg1 op fix arg2) res_ty
--
-- The *result* type can have any kind (Trac #8739),
-- so we don't need to check anything for that
- ; _ <- unifyKind (Just arg2_sigma) (typeKind arg2_sigma) liftedTypeKind
+ ; _ <- unifyKind (Just (HsCoreTy arg2_sigma)) (typeKind arg2_sigma) liftedTypeKind
-- ignore the evidence. arg2_sigma must have type * or #,
-- because we know arg2_sigma -> or_res_ty is well-kinded
-- (because otherwise matchActualFunTys would fail)
@@ -434,7 +434,7 @@ tcExpr expr@(OpApp arg1 op fix arg2) res_ty
tcExpr expr@(SectionR op arg2) res_ty
= do { (op', op_ty) <- tcInferFun op
; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty)
- <- matchActualFunTys (mk_op_msg op) fn_orig (Just op) 2 op_ty
+ <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) 2 op_ty
; wrap_res <- tcSubTypeHR SectionOrigin (Just expr)
(mkFunTy arg1_ty op_res_ty) res_ty
; arg2' <- tcArg op arg2 arg2_ty 2
@@ -453,7 +453,7 @@ tcExpr expr@(SectionL arg1 op) res_ty
| otherwise = 2
; (wrap_fn, (arg1_ty:arg_tys), op_res_ty)
- <- matchActualFunTys (mk_op_msg op) fn_orig (Just op)
+ <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op))
n_reqd_args op_ty
; wrap_res <- tcSubTypeHR SectionOrigin (Just expr)
(mkFunTys arg_tys op_res_ty) res_ty
@@ -938,7 +938,7 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = rbnds }) res_ty
; wrap_res <- tcSubTypeHR (exprCtOrigin expr)
(Just expr) rec_res_ty res_ty
- ; co_scrut <- unifyType (Just record_expr) record_rho scrut_ty
+ ; co_scrut <- unifyType (Just (unLoc record_expr)) record_rho scrut_ty
-- NB: normal unification is OK here (as opposed to subsumption),
-- because for this to work out, both record_rho and scrut_ty have
-- to be normal datatypes -- no contravariant stuff can go on
@@ -974,8 +974,8 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = rbnds }) res_ty
, rupd_cons = relevant_cons, rupd_in_tys = scrut_inst_tys
, rupd_out_tys = result_inst_tys, rupd_wrap = req_wrap } }
-tcExpr (HsRecFld f) res_ty
- = tcCheckRecSelId f res_ty
+tcExpr e@(HsRecFld f) res_ty
+ = tcCheckRecSelId e f res_ty
{-
************************************************************************
@@ -1037,10 +1037,10 @@ tcExpr (HsSpliceE (HsSpliced mod_finalizers (HsSplicedExpr expr)))
tcExpr expr res_ty
tcExpr (HsSpliceE splice) res_ty
= tcSpliceExpr splice res_ty
-tcExpr (HsBracket brack) res_ty
- = tcTypedBracket brack res_ty
-tcExpr (HsRnBracketOut brack ps) res_ty
- = tcUntypedBracket brack ps res_ty
+tcExpr e@(HsBracket brack) res_ty
+ = tcTypedBracket e brack res_ty
+tcExpr e@(HsRnBracketOut brack ps) res_ty
+ = tcUntypedBracket e brack ps res_ty
{-
************************************************************************
@@ -1194,7 +1194,7 @@ tcApp m_herald orig_fun orig_args res_ty
-- up to call that function
; wrap_res <- addFunResCtxt True (unLoc fun) actual_res_ty res_ty $
tcSubTypeDS_NC_O orig GenSigCtxt
- (Just $ foldl mk_hs_app fun args)
+ (Just $ unLoc $ foldl mk_hs_app fun args)
actual_res_ty res_ty
; return (wrap_res, mkLHsWrap wrap_fun fun1, args1) }
@@ -1290,7 +1290,7 @@ tcArgs fun orig_fun_ty fun_orig orig_args herald
go acc_args n fun_ty (Left arg : args)
= do { (wrap, [arg_ty], res_ty)
- <- matchActualFunTysPart herald fun_orig (Just fun) 1 fun_ty
+ <- matchActualFunTysPart herald fun_orig (Just (unLoc fun)) 1 fun_ty
acc_args orig_arity
-- wrap :: fun_ty "->" arg_ty -> res_ty
; arg' <- tcArg fun arg arg_ty n
@@ -1449,7 +1449,7 @@ tcSynArgA :: CtOrigin
-- and a wrapper to be applied to the overall expression
tcSynArgA orig sigma_ty arg_shapes res_shape thing_inside
= do { (match_wrapper, arg_tys, res_ty)
- <- matchActualFunTys herald orig noThing (length arg_shapes) sigma_ty
+ <- matchActualFunTys herald orig Nothing (length arg_shapes) sigma_ty
-- match_wrapper :: sigma_ty "->" (arg_tys -> res_ty)
; ((result, res_wrapper), arg_wrappers)
<- tc_syn_args_e arg_tys arg_shapes $ \ arg_results ->
@@ -1561,7 +1561,7 @@ tcExprSig expr sig@(PartialSig { psig_name = name, sig_loc = loc })
= ApplyMR
| otherwise
= NoRestrictions
- ; (qtvs, givens, ev_binds)
+ ; (qtvs, givens, ev_binds, _)
<- simplifyInfer tclvl infer_mode [sig_inst] [(name, tau)] wanted
; tau <- zonkTcType tau
; let inferred_theta = map evVarPred givens
@@ -1623,18 +1623,18 @@ tcCheckId name res_ty
= do { (expr, actual_res_ty) <- tcInferId name
; traceTc "tcCheckId" (vcat [ppr name, ppr actual_res_ty, ppr res_ty])
; addFunResCtxt False (HsVar (noLoc name)) actual_res_ty res_ty $
- tcWrapResultO (OccurrenceOf name) expr actual_res_ty res_ty }
+ tcWrapResultO (OccurrenceOf name) (HsVar (noLoc name)) expr actual_res_ty res_ty }
-tcCheckRecSelId :: AmbiguousFieldOcc GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId)
-tcCheckRecSelId f@(Unambiguous (L _ lbl) _) res_ty
+tcCheckRecSelId :: HsExpr GhcRn -> AmbiguousFieldOcc GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId)
+tcCheckRecSelId rn_expr f@(Unambiguous (L _ lbl) _) res_ty
= do { (expr, actual_res_ty) <- tcInferRecSelId f
; addFunResCtxt False (HsRecFld f) actual_res_ty res_ty $
- tcWrapResultO (OccurrenceOfRecSel lbl) expr actual_res_ty res_ty }
-tcCheckRecSelId (Ambiguous lbl _) res_ty
+ tcWrapResultO (OccurrenceOfRecSel lbl) rn_expr expr actual_res_ty res_ty }
+tcCheckRecSelId rn_expr (Ambiguous lbl _) res_ty
= case tcSplitFunTy_maybe =<< checkingExpType_maybe res_ty of
Nothing -> ambiguousSelector lbl
Just (arg, _) -> do { sel_name <- disambiguateSelector lbl arg
- ; tcCheckRecSelId (Unambiguous lbl sel_name) res_ty }
+ ; tcCheckRecSelId rn_expr (Unambiguous lbl sel_name) res_ty }
------------------------
tcInferRecSelId :: AmbiguousFieldOcc GhcRn -> TcM (HsExpr GhcTcId, TcRhoType)
@@ -1724,7 +1724,7 @@ tc_infer_id lbl id_name
| otherwise = return ()
-tcUnboundId :: UnboundVar -> ExpRhoType -> TcM (HsExpr GhcTcId)
+tcUnboundId :: HsExpr GhcRn -> UnboundVar -> ExpRhoType -> TcM (HsExpr GhcTcId)
-- Typecheck an occurrence of an unbound Id
--
-- Some of these started life as a true expression hole "_".
@@ -1733,7 +1733,7 @@ tcUnboundId :: UnboundVar -> ExpRhoType -> TcM (HsExpr GhcTcId)
-- We turn all of them into HsVar, since HsUnboundVar can't contain an
-- Id; and indeed the evidence for the CHoleCan does bind it, so it's
-- not unbound any more!
-tcUnboundId unbound res_ty
+tcUnboundId rn_expr unbound res_ty
= do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (Trac #12531)
; let occ = unboundVarOcc unbound
; name <- newSysName occ
@@ -1745,7 +1745,7 @@ tcUnboundId unbound res_ty
, ctev_loc = loc}
, cc_hole = ExprHole unbound }
; emitInsoluble can
- ; tcWrapResultO (UnboundOccurrenceOf occ) (HsVar (noLoc ev)) ty res_ty }
+ ; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr (HsVar (noLoc ev)) ty res_ty }
{-
diff --git a/compiler/typecheck/TcFlatten.hs b/compiler/typecheck/TcFlatten.hs
index 1bb4a7165b..69f8357a1d 100644
--- a/compiler/typecheck/TcFlatten.hs
+++ b/compiler/typecheck/TcFlatten.hs
@@ -584,7 +584,7 @@ setMode new_mode thing_inside
else runFlatM thing_inside (env { fe_mode = new_mode })
-- | Use when flattening kinds/kind coercions. See
--- Note [No derived kind equalities] in TcCanonical
+-- Note [No derived kind equalities]
flattenKinds :: FlatM a -> FlatM a
flattenKinds thing_inside
= FlatM $ \env ->
@@ -717,6 +717,18 @@ soon throw out the phantoms when decomposing a TyConApp. (Or, the
canonicaliser will emit an insoluble, in which case the unflattened version
yields a better error message anyway.)
+Note [No derived kind equalities]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We call flattenKinds in two places: in flatten_co (Note [Flattening coercions])
+and in flattenTyVar. The latter case is easier to understand; flattenKinds is
+used to flatten the kind of a flat (i.e. inert) tyvar. Flattening a kind
+naturally produces a coercion. This coercion is then used in the flattened type.
+However, danger lurks if the flattening flavour (that is, the fe_flavour of the
+FlattenEnv) is Derived: the coercion might be bottom. (This can happen when
+looks up a kindvar in the inert set only to find a Derived equality, with
+no coercion.) The solution is simple: ensure that the fe_flavour is not derived
+when flattening a kind. This is what flattenKinds does.
+
-}
{- *********************************************************************
@@ -1326,10 +1338,9 @@ flattenTyVar tv
FTRNotFollowed -- Done
-> do { let orig_kind = tyVarKind tv
- ; (_new_kind, kind_co) <- setMode FM_SubstOnly $
- flattenKinds $
+ ; (_new_kind, kind_co) <- flattenKinds $
flatten_one orig_kind
- ; let Pair _ zonked_kind = coercionKind kind_co
+ ; let Pair _ zonked_kind = coercionKind kind_co
-- NB: kind_co :: _new_kind ~ zonked_kind
-- But zonked_kind is not necessarily the same as orig_kind
-- because that may have filled-in metavars.
@@ -1339,13 +1350,13 @@ flattenTyVar tv
-- See also Note [Flattening]
-- An alternative would to use (zonkTcType orig_kind),
-- but some simple measurements suggest that's a little slower
- ; let tv' = setTyVarKind tv zonked_kind
- tv_ty' = mkTyVarTy tv'
- ty' = tv_ty' `mkCastTy` mkSymCo kind_co
+ ; let tv' = setTyVarKind tv zonked_kind
+ tv_ty' = mkTyVarTy tv'
+ ty' = tv_ty' `mkCastTy` mkSymCo kind_co
- ; role <- getRole
- ; return (ty', mkReflCo role tv_ty'
- `mkCoherenceLeftCo` mkSymCo kind_co) } }
+ ; role <- getRole
+ ; return (ty', mkReflCo role tv_ty'
+ `mkCoherenceLeftCo` mkSymCo kind_co) } }
flatten_tyvar1 :: TcTyVar -> FlatM FlattenTvResult
-- "Flattening" a type variable means to apply the substitution to it
diff --git a/compiler/typecheck/TcGenDeriv.hs b/compiler/typecheck/TcGenDeriv.hs
index 7e79c12ed6..00ed9edc11 100644
--- a/compiler/typecheck/TcGenDeriv.hs
+++ b/compiler/typecheck/TcGenDeriv.hs
@@ -1679,7 +1679,7 @@ gen_Newtype_binds loc cls inst_tvs inst_tys rhs_ty
fam_tc rep_lhs_tys rep_rhs_ty
-- Check (c) from Note [GND and associated type families] in TcDeriv
checkValidTyFamEqn (Just (cls, cls_tvs, lhs_env)) fam_tc rep_tvs'
- rep_cvs' rep_lhs_tys rep_rhs_ty loc
+ rep_cvs' rep_lhs_tys rep_rhs_ty pp_lhs loc
newFamInst SynFamilyInst axiom
where
cls_tvs = classTyVars cls
@@ -1696,6 +1696,7 @@ gen_Newtype_binds loc cls inst_tvs inst_tys rhs_ty
(rep_tvs, rep_cvs) = partition isTyVar rep_tcvs
rep_tvs' = toposortTyVars rep_tvs
rep_cvs' = toposortTyVars rep_cvs
+ pp_lhs = ppr (mkTyConApp fam_tc rep_lhs_tys)
nlHsAppType :: LHsExpr GhcPs -> Type -> LHsExpr GhcPs
nlHsAppType e s = noLoc (e `HsAppType` hs_ty)
diff --git a/compiler/typecheck/TcHsSyn.hs b/compiler/typecheck/TcHsSyn.hs
index 93ed47040c..0713fabd18 100644
--- a/compiler/typecheck/TcHsSyn.hs
+++ b/compiler/typecheck/TcHsSyn.hs
@@ -34,7 +34,7 @@ module TcHsSyn (
emptyZonkEnv, mkEmptyZonkEnv,
zonkTcTypeToType, zonkTcTypeToTypes, zonkTyVarOcc,
zonkCoToCo, zonkSigType,
- zonkEvBinds,
+ zonkEvBinds, zonkTcEvBinds
) where
#include "HsVersions.h"
@@ -455,24 +455,44 @@ zonk_bind env bind@(FunBind { fun_id = L loc var, fun_matches = ms
zonk_bind env (AbsBinds { abs_tvsa = tyvars, abs_ev_varsa = evs
, abs_ev_binds = ev_binds
, abs_exports = exports
- , abs_binds = val_binds })
+ , abs_binds = val_binds
+ , abs_sig = has_sig })
= ASSERT( all isImmutableTyVar tyvars )
do { (env0, new_tyvars) <- zonkTyBndrsX env tyvars
; (env1, new_evs) <- zonkEvBndrsX env0 evs
; (env2, new_ev_binds) <- zonkTcEvBinds_s env1 ev_binds
; (new_val_bind, new_exports) <- fixM $ \ ~(new_val_binds, _) ->
- do { let env3 = extendIdZonkEnvRec env2
- (collectHsBindsBinders new_val_binds)
- ; new_val_binds <- zonkMonoBinds env3 val_binds
- ; new_exports <- mapM (zonkExport env3) exports
+ do { let env3 = extendIdZonkEnvRec env2 $
+ collectHsBindsBinders new_val_binds
+ ; new_val_binds <- mapBagM (zonk_val_bind env3) val_binds
+ ; new_exports <- mapM (zonk_export env3) exports
; return (new_val_binds, new_exports) }
; return (AbsBinds { abs_tvsa = new_tyvars, abs_ev_varsa = new_evs
, abs_ev_binds = new_ev_binds
- , abs_exports = new_exports, abs_binds = new_val_bind }) }
+ , abs_exports = new_exports, abs_binds = new_val_bind
+ , abs_sig = has_sig }) }
where
- zonkExport env (ABE{ abe_wrap = wrap
- , abe_poly = poly_id
- , abe_mono = mono_id, abe_prags = prags })
+ zonk_val_bind env lbind
+ | has_sig
+ , L loc bind@(FunBind { fun_id = L mloc mono_id
+ , fun_matches = ms
+ , fun_co_fn = co_fn }) <- lbind
+ = do { new_mono_id <- updateVarTypeM (zonkTcTypeToType env) mono_id
+ -- Specifically /not/ zonkIdBndr; we do not
+ -- want to complain about a levity-polymorphic binder
+ ; (env', new_co_fn) <- zonkCoFn env co_fn
+ ; new_ms <- zonkMatchGroup env' zonkLExpr ms
+ ; return $ L loc $
+ bind { fun_id = L mloc new_mono_id
+ , fun_matches = new_ms
+ , fun_co_fn = new_co_fn } }
+ | otherwise
+ = zonk_lbind env lbind -- The normal case
+
+ zonk_export env (ABE{ abe_wrap = wrap
+ , abe_poly = poly_id
+ , abe_mono = mono_id
+ , abe_prags = prags })
= do new_poly_id <- zonkIdBndr env poly_id
(_, new_wrap) <- zonkCoFn env wrap
new_prags <- zonkSpecPrags env prags
@@ -481,44 +501,6 @@ zonk_bind env (AbsBinds { abs_tvsa = tyvars, abs_ev_varsa = evs
, abe_mono = zonkIdOcc env mono_id
, abe_prags = new_prags })
-zonk_bind env outer_bind@(AbsBindsSig { abs_tvs = tyvars
- , abs_ev_vars = evs
- , abs_sig_export = poly
- , abs_sig_prags = prags
- , abs_sig_ev_bind = ev_bind
- , abs_sig_bind = lbind })
- | L bind_loc bind@(FunBind { fun_id = L loc local
- , fun_matches = ms
- , fun_co_fn = co_fn }) <- lbind
- = ASSERT( all isImmutableTyVar tyvars )
- do { (env0, new_tyvars) <- zonkTyBndrsX env tyvars
- ; (env1, new_evs) <- zonkEvBndrsX env0 evs
- ; (env2, new_ev_bind) <- zonkTcEvBinds env1 ev_bind
- -- Inline zonk_bind (FunBind ...) because we wish to skip
- -- the check for representation-polymorphic binders. The
- -- local binder in the FunBind in an AbsBindsSig is never actually
- -- bound in Core -- indeed, that's the whole point of AbsBindsSig.
- -- just calling zonk_bind causes #11405.
- ; new_local <- updateVarTypeM (zonkTcTypeToType env2) local
- ; (env3, new_co_fn) <- zonkCoFn env2 co_fn
- ; new_ms <- zonkMatchGroup env3 zonkLExpr ms
- -- If there is a representation polymorphism problem, it will
- -- be caught here:
- ; new_poly_id <- zonkIdBndr env2 poly
- ; new_prags <- zonkSpecPrags env2 prags
- ; let new_val_bind = L bind_loc (bind { fun_id = L loc new_local
- , fun_matches = new_ms
- , fun_co_fn = new_co_fn })
- ; return (AbsBindsSig { abs_tvs = new_tyvars
- , abs_ev_vars = new_evs
- , abs_sig_export = new_poly_id
- , abs_sig_prags = new_prags
- , abs_sig_ev_bind = new_ev_bind
- , abs_sig_bind = new_val_bind }) }
-
- | otherwise
- = pprPanic "zonk_bind" (ppr outer_bind)
-
zonk_bind env (PatSynBind bind@(PSB { psb_id = L loc id
, psb_args = details
, psb_def = lpat
@@ -583,10 +565,11 @@ zonkMatch :: ZonkEnv
-> (ZonkEnv -> Located (body (GHC GhcTcId)) -> TcM (Located (body (GHC GhcTc))))
-> LMatch GhcTcId (Located (body (GHC GhcTcId)))
-> TcM (LMatch GhcTc (Located (body (GHC GhcTc))))
-zonkMatch env zBody (L loc (Match mf pats _ grhss))
+zonkMatch env zBody (L loc match@(Match { m_pats = pats, m_grhss = grhss }))
= do { (env1, new_pats) <- zonkPats env pats
; new_grhss <- zonkGRHSs env1 zBody grhss
- ; return (L loc (Match mf new_pats Nothing new_grhss)) }
+ ; return (L loc (match { m_pats = new_pats, m_type = Nothing
+ , m_grhss = new_grhss })) }
-------------------------------------------------------------------------
zonkGRHSs :: ZonkEnv
diff --git a/compiler/typecheck/TcHsType.hs b/compiler/typecheck/TcHsType.hs
index 7c50888fc3..23eaee8bae 100644
--- a/compiler/typecheck/TcHsType.hs
+++ b/compiler/typecheck/TcHsType.hs
@@ -31,10 +31,12 @@ module TcHsType (
tcHsLiftedType, tcHsOpenType,
tcHsLiftedTypeNC, tcHsOpenTypeNC,
tcLHsType, tcCheckLHsType,
- tcHsContext, tcLHsPredType, tcInferApps, tcInferArgs,
+ tcHsContext, tcLHsPredType, tcInferApps, tcTyApps,
solveEqualities, -- useful re-export
- kindGeneralize,
+ typeLevelMode, kindLevelMode,
+
+ kindGeneralize, checkExpectedKindX, instantiateTyUntilN,
-- Sort-checking kinds
tcLHsKindSig,
@@ -270,11 +272,12 @@ tcHsClsInstType user_ctxt hs_inst_ty
-- Used for 'VECTORISE [SCALAR] instance' declarations
tcHsVectInst :: LHsSigType GhcRn -> TcM (Class, [Type])
tcHsVectInst ty
- | Just (L _ cls_name, tys) <- hsTyGetAppHead_maybe (hsSigType ty)
+ | let hs_cls_ty = hsSigType ty
+ , Just (L _ cls_name, tys) <- hsTyGetAppHead_maybe hs_cls_ty
-- Ignoring the binders looks pretty dodgy to me
= do { (cls, cls_kind) <- tcClass cls_name
; (applied_class, _res_kind)
- <- tcInferApps typeLevelMode cls_name (mkClassPred cls []) cls_kind tys
+ <- tcTyApps typeLevelMode hs_cls_ty (mkClassPred cls []) cls_kind tys
; case tcSplitTyConApp_maybe applied_class of
Just (_tc, args) -> ASSERT( _tc == classTyCon cls )
return (cls, args)
@@ -319,7 +322,7 @@ tcHsOpenTypeNC ty = do { ek <- newOpenTypeKind
tcHsLiftedTypeNC ty = tc_lhs_type typeLevelMode ty liftedTypeKind
-- Like tcHsType, but takes an expected kind
-tcCheckLHsType :: LHsType GhcRn -> Kind -> TcM Type
+tcCheckLHsType :: LHsType GhcRn -> Kind -> TcM TcType
tcCheckLHsType hs_ty exp_kind
= addTypeCtxt hs_ty $
tc_lhs_type typeLevelMode hs_ty exp_kind
@@ -468,13 +471,13 @@ tc_infer_hs_type mode (HsAppTy ty1 ty2)
= do { let (fun_ty, arg_tys) = splitHsAppTys ty1 [ty2]
; (fun_ty', fun_kind) <- tc_infer_lhs_type mode fun_ty
; fun_kind' <- zonkTcType fun_kind
- ; tcInferApps mode fun_ty fun_ty' fun_kind' arg_tys }
+ ; tcTyApps mode fun_ty fun_ty' fun_kind' arg_tys }
tc_infer_hs_type mode (HsParTy t) = tc_infer_lhs_type mode t
-tc_infer_hs_type mode (HsOpTy lhs (L _ op) rhs)
+tc_infer_hs_type mode (HsOpTy lhs (L loc_op op) rhs)
| not (op `hasKey` funTyConKey)
= do { (op', op_kind) <- tcTyVar mode op
; op_kind' <- zonkTcType op_kind
- ; tcInferApps mode op op' op_kind' [lhs, rhs] }
+ ; tcTyApps mode (noLoc $ HsTyVar NotPromoted (L loc_op op)) op' op_kind' [lhs, rhs] }
tc_infer_hs_type mode (HsKindSig ty sig)
= do { sig' <- tc_lhs_kind (kindLevel mode) sig
; ty' <- tc_lhs_type mode ty sig'
@@ -510,11 +513,11 @@ tc_fun_type mode ty1 ty2 exp_kind = case mode_level mode of
; res_k <- newOpenTypeKind
; ty1' <- tc_lhs_type mode ty1 arg_k
; ty2' <- tc_lhs_type mode ty2 res_k
- ; checkExpectedKind (mkFunTy ty1' ty2') liftedTypeKind exp_kind }
+ ; checkExpectedKind (HsFunTy ty1 ty2) (mkFunTy ty1' ty2') liftedTypeKind exp_kind }
KindLevel -> -- no representation polymorphism in kinds. yet.
do { ty1' <- tc_lhs_type mode ty1 liftedTypeKind
; ty2' <- tc_lhs_type mode ty2 liftedTypeKind
- ; checkExpectedKind (mkFunTy ty1' ty2') liftedTypeKind exp_kind }
+ ; checkExpectedKind (HsFunTy ty1 ty2) (mkFunTy ty1' ty2') liftedTypeKind exp_kind }
------------------------------------------
-- See also Note [Bidirectional type checking]
@@ -579,30 +582,30 @@ tc_hs_type mode (HsQualTy { hst_ctxt = ctxt, hst_bodyy = ty }) exp_kind
else do { ek <- newOpenTypeKind
-- The body kind (result of the function)
-- can be * or #, hence newOpenTypeKind
- ; ty <- tc_lhs_type mode ty ek
- ; checkExpectedKind ty liftedTypeKind exp_kind }
+ ; ty' <- tc_lhs_type mode ty ek
+ ; checkExpectedKind (unLoc ty) ty' liftedTypeKind exp_kind }
; return (mkPhiTy ctxt' ty') }
--------- Lists, arrays, and tuples
-tc_hs_type mode (HsListTy elt_ty) exp_kind
+tc_hs_type mode rn_ty@(HsListTy elt_ty) exp_kind
= do { tau_ty <- tc_lhs_type mode elt_ty liftedTypeKind
; checkWiredInTyCon listTyCon
- ; checkExpectedKind (mkListTy tau_ty) liftedTypeKind exp_kind }
+ ; checkExpectedKind rn_ty (mkListTy tau_ty) liftedTypeKind exp_kind }
-tc_hs_type mode (HsPArrTy elt_ty) exp_kind
+tc_hs_type mode rn_ty@(HsPArrTy elt_ty) exp_kind
= do { MASSERT( isTypeLevel (mode_level mode) )
; tau_ty <- tc_lhs_type mode elt_ty liftedTypeKind
; checkWiredInTyCon parrTyCon
- ; checkExpectedKind (mkPArrTy tau_ty) liftedTypeKind exp_kind }
+ ; checkExpectedKind rn_ty (mkPArrTy tau_ty) liftedTypeKind exp_kind }
-- See Note [Distinguishing tuple kinds] in HsTypes
-- See Note [Inferring tuple kinds]
-tc_hs_type mode (HsTupleTy HsBoxedOrConstraintTuple hs_tys) exp_kind
+tc_hs_type mode rn_ty@(HsTupleTy HsBoxedOrConstraintTuple hs_tys) exp_kind
-- (NB: not zonking before looking at exp_k, to avoid left-right bias)
| Just tup_sort <- tupKindSort_maybe exp_kind
= traceTc "tc_hs_type tuple" (ppr hs_tys) >>
- tc_tuple mode tup_sort hs_tys exp_kind
+ tc_tuple rn_ty mode tup_sort hs_tys exp_kind
| otherwise
= do { traceTc "tc_hs_type tuple 2" (ppr hs_tys)
; (tys, kinds) <- mapAndUnzipM (tc_infer_lhs_type mode) hs_tys
@@ -620,14 +623,14 @@ tc_hs_type mode (HsTupleTy HsBoxedOrConstraintTuple hs_tys) exp_kind
-- In the [] case, it's not clear what the kind is, so guess *
; tys' <- sequence [ setSrcSpan loc $
- checkExpectedKind ty kind arg_kind
- | ((L loc _),ty,kind) <- zip3 hs_tys tys kinds ]
+ checkExpectedKind hs_ty ty kind arg_kind
+ | ((L loc hs_ty),ty,kind) <- zip3 hs_tys tys kinds ]
- ; finish_tuple tup_sort tys' (map (const arg_kind) tys') exp_kind }
+ ; finish_tuple rn_ty tup_sort tys' (map (const arg_kind) tys') exp_kind }
-tc_hs_type mode (HsTupleTy hs_tup_sort tys) exp_kind
- = tc_tuple mode tup_sort tys exp_kind
+tc_hs_type mode rn_ty@(HsTupleTy hs_tup_sort tys) exp_kind
+ = tc_tuple rn_ty mode tup_sort tys exp_kind
where
tup_sort = case hs_tup_sort of -- Fourth case dealt with above
HsUnboxedTuple -> UnboxedTuple
@@ -635,28 +638,29 @@ tc_hs_type mode (HsTupleTy hs_tup_sort tys) exp_kind
HsConstraintTuple -> ConstraintTuple
_ -> panic "tc_hs_type HsTupleTy"
-tc_hs_type mode (HsSumTy hs_tys) exp_kind
+tc_hs_type mode rn_ty@(HsSumTy hs_tys) exp_kind
= do { let arity = length hs_tys
; arg_kinds <- mapM (\_ -> newOpenTypeKind) hs_tys
; tau_tys <- zipWithM (tc_lhs_type mode) hs_tys arg_kinds
; let arg_reps = map (getRuntimeRepFromKind "tc_hs_type HsSumTy") arg_kinds
arg_tys = arg_reps ++ tau_tys
- ; checkExpectedKind (mkTyConApp (sumTyCon arity) arg_tys)
+ ; checkExpectedKind rn_ty
+ (mkTyConApp (sumTyCon arity) arg_tys)
(unboxedSumKind arg_reps)
exp_kind
}
--------- Promoted lists and tuples
-tc_hs_type mode (HsExplicitListTy _ _k tys) exp_kind
+tc_hs_type mode rn_ty@(HsExplicitListTy _ _k tys) exp_kind
= do { tks <- mapM (tc_infer_lhs_type mode) tys
- ; (taus', kind) <- unifyKinds tks
+ ; (taus', kind) <- unifyKinds tys tks
; let ty = (foldr (mk_cons kind) (mk_nil kind) taus')
- ; checkExpectedKind ty (mkListTy kind) exp_kind }
+ ; checkExpectedKind rn_ty ty (mkListTy kind) exp_kind }
where
mk_cons k a b = mkTyConApp (promoteDataCon consDataCon) [k, a, b]
mk_nil k = mkTyConApp (promoteDataCon nilDataCon) [k]
-tc_hs_type mode (HsExplicitTupleTy _ tys) exp_kind
+tc_hs_type mode rn_ty@(HsExplicitTupleTy _ tys) exp_kind
-- using newMetaKindVar means that we force instantiations of any polykinded
-- types. At first, I just used tc_infer_lhs_type, but that led to #11255.
= do { ks <- replicateM arity newMetaKindVar
@@ -664,35 +668,35 @@ tc_hs_type mode (HsExplicitTupleTy _ tys) exp_kind
; let kind_con = tupleTyCon Boxed arity
ty_con = promotedTupleDataCon Boxed arity
tup_k = mkTyConApp kind_con ks
- ; checkExpectedKind (mkTyConApp ty_con (ks ++ taus)) tup_k exp_kind }
+ ; checkExpectedKind rn_ty (mkTyConApp ty_con (ks ++ taus)) tup_k exp_kind }
where
arity = length tys
--------- Constraint types
-tc_hs_type mode (HsIParamTy (L _ n) ty) exp_kind
+tc_hs_type mode rn_ty@(HsIParamTy (L _ n) ty) exp_kind
= do { MASSERT( isTypeLevel (mode_level mode) )
; ty' <- tc_lhs_type mode ty liftedTypeKind
; let n' = mkStrLitTy $ hsIPNameFS n
; ipClass <- tcLookupClass ipClassName
- ; checkExpectedKind (mkClassPred ipClass [n',ty'])
+ ; checkExpectedKind rn_ty (mkClassPred ipClass [n',ty'])
constraintKind exp_kind }
-tc_hs_type mode (HsEqTy ty1 ty2) exp_kind
+tc_hs_type mode rn_ty@(HsEqTy ty1 ty2) exp_kind
= do { (ty1', kind1) <- tc_infer_lhs_type mode ty1
; (ty2', kind2) <- tc_infer_lhs_type mode ty2
- ; ty2'' <- checkExpectedKind ty2' kind2 kind1
+ ; ty2'' <- checkExpectedKind (unLoc ty2) ty2' kind2 kind1
; eq_tc <- tcLookupTyCon eqTyConName
; let ty' = mkNakedTyConApp eq_tc [kind1, ty1', ty2'']
- ; checkExpectedKind ty' constraintKind exp_kind }
+ ; checkExpectedKind rn_ty ty' constraintKind exp_kind }
--------- Literals
-tc_hs_type _ (HsTyLit (HsNumTy _ n)) exp_kind
+tc_hs_type _ rn_ty@(HsTyLit (HsNumTy _ n)) exp_kind
= do { checkWiredInTyCon typeNatKindCon
- ; checkExpectedKind (mkNumLitTy n) typeNatKind exp_kind }
+ ; checkExpectedKind rn_ty (mkNumLitTy n) typeNatKind exp_kind }
-tc_hs_type _ (HsTyLit (HsStrTy _ s)) exp_kind
+tc_hs_type _ rn_ty@(HsTyLit (HsStrTy _ s)) exp_kind
= do { checkWiredInTyCon typeSymbolKindCon
- ; checkExpectedKind (mkStrLitTy s) typeSymbolKind exp_kind }
+ ; checkExpectedKind rn_ty (mkStrLitTy s) typeSymbolKind exp_kind }
--------- Potentially kind-polymorphic types: call the "up" checker
-- See Note [Future-proofing the type checker]
@@ -723,7 +727,7 @@ tcWildCardOcc wc_info exp_kind
tc_infer_hs_type_ek :: TcTyMode -> HsType GhcRn -> TcKind -> TcM TcType
tc_infer_hs_type_ek mode ty ek
= do { (ty', k) <- tc_infer_hs_type mode ty
- ; checkExpectedKind ty' k ek }
+ ; checkExpectedKind ty ty' k ek }
---------------------------
tupKindSort_maybe :: TcKind -> Maybe TupleSort
@@ -734,23 +738,24 @@ tupKindSort_maybe k
| isLiftedTypeKind k = Just BoxedTuple
| otherwise = Nothing
-tc_tuple :: TcTyMode -> TupleSort -> [LHsType GhcRn] -> TcKind -> TcM TcType
-tc_tuple mode tup_sort tys exp_kind
+tc_tuple :: HsType GhcRn -> TcTyMode -> TupleSort -> [LHsType GhcRn] -> TcKind -> TcM TcType
+tc_tuple rn_ty mode tup_sort tys exp_kind
= do { arg_kinds <- case tup_sort of
BoxedTuple -> return (nOfThem arity liftedTypeKind)
UnboxedTuple -> mapM (\_ -> newOpenTypeKind) tys
ConstraintTuple -> return (nOfThem arity constraintKind)
; tau_tys <- zipWithM (tc_lhs_type mode) tys arg_kinds
- ; finish_tuple tup_sort tau_tys arg_kinds exp_kind }
+ ; finish_tuple rn_ty tup_sort tau_tys arg_kinds exp_kind }
where
arity = length tys
-finish_tuple :: TupleSort
+finish_tuple :: HsType GhcRn
+ -> TupleSort
-> [TcType] -- ^ argument types
-> [TcKind] -- ^ of these kinds
-> TcKind -- ^ expected kind of the whole tuple
-> TcM TcType
-finish_tuple tup_sort tau_tys tau_kinds exp_kind
+finish_tuple rn_ty tup_sort tau_tys tau_kinds exp_kind
= do { traceTc "finish_tuple" (ppr res_kind $$ ppr tau_kinds $$ ppr exp_kind)
; let arg_tys = case tup_sort of
-- See also Note [Unboxed tuple RuntimeRep vars] in TyCon
@@ -766,7 +771,7 @@ finish_tuple tup_sort tau_tys tau_kinds exp_kind
; checkWiredInTyCon tc
; return tc }
UnboxedTuple -> return (tupleTyCon Unboxed arity)
- ; checkExpectedKind (mkTyConApp tycon arg_tys) res_kind exp_kind }
+ ; checkExpectedKind rn_ty (mkTyConApp tycon arg_tys) res_kind exp_kind }
where
arity = length tau_tys
tau_reps = map (getRuntimeRepFromKind "finish_tuple") tau_kinds
@@ -783,128 +788,125 @@ bigConstraintTuple arity
---------------------------
-- | Apply a type of a given kind to a list of arguments. This instantiates
--- invisible parameters as necessary. However, it does *not* necessarily
--- apply all the arguments, if the kind runs out of binders.
--- Never calls 'matchExpectedFunKind'; when the kind runs out of binders,
--- this stops processing.
+-- invisible parameters as necessary. Always consumes all the arguments,
+-- using matchExpectedFunKind as necessary.
-- This takes an optional @VarEnv Kind@ which maps kind variables to kinds.
-- These kinds should be used to instantiate invisible kind variables;
-- they come from an enclosing class for an associated type/data family.
--- This version will instantiate all invisible arguments left over after
--- the visible ones. Used only when typechecking type/data family patterns
--- (where we need to instantiate all remaining invisible parameters; for
--- example, consider @type family F :: k where F = Int; F = Maybe@. We
--- need to instantiate the @k@.)
-tcInferArgs :: Outputable fun
- => fun -- ^ the function
- -> [TyConBinder] -- ^ function kind's binders
- -> Maybe (VarEnv Kind) -- ^ possibly, kind info (see above)
- -> [LHsType GhcRn] -- ^ args
- -> TcM (TCvSubst, [TyBinder], [TcType], [LHsType GhcRn], Int)
- -- ^ (instantiating subst, un-insted leftover binders,
- -- typechecked args, untypechecked args, n)
-tcInferArgs fun tc_binders mb_kind_info args
- = do { let binders = tyConBindersTyBinders tc_binders -- UGH!
- ; (subst, leftover_binders, args', leftovers, n)
- <- tc_infer_args typeLevelMode fun binders mb_kind_info args 1
- -- now, we need to instantiate any remaining invisible arguments
- ; let (invis_bndrs, other_binders) = break isVisibleBinder leftover_binders
- ; (subst', invis_args)
- <- tcInstBinders subst mb_kind_info invis_bndrs
- ; return ( subst'
- , other_binders
- , args' `chkAppend` invis_args
- , leftovers, n ) }
-
--- | See comments for 'tcInferArgs'. But this version does not instantiate
--- any remaining invisible arguments.
-tc_infer_args :: Outputable fun
- => TcTyMode
- -> fun -- ^ the function
- -> [TyBinder] -- ^ function kind's binders (zonked)
- -> Maybe (VarEnv Kind) -- ^ possibly, kind info (see above)
- -> [LHsType GhcRn] -- ^ args
- -> Int -- ^ number to start arg counter at
- -> TcM (TCvSubst, [TyBinder], [TcType], [LHsType GhcRn], Int)
-tc_infer_args mode orig_ty binders mb_kind_info orig_args n0
- = go emptyTCvSubst binders orig_args n0 []
+tcInferApps :: TcTyMode
+ -> Maybe (VarEnv Kind) -- ^ Possibly, kind info (see above)
+ -> LHsType GhcRn -- ^ Function (for printing only)
+ -> TcType -- ^ Function (could be knot-tied)
+ -> TcKind -- ^ Function kind (zonked)
+ -> [LHsType GhcRn] -- ^ Args
+ -> TcM (TcType, [TcType], TcKind) -- ^ (f args, args, result kind)
+tcInferApps mode mb_kind_info orig_ty ty ki args
+ = do { traceTc "tcInferApps" (ppr orig_ty $$ ppr args $$ ppr ki)
+ ; go [] [] orig_subst ty orig_ki_binders orig_inner_ki args 1 }
where
- go subst binders [] n acc
- = return ( subst, binders, reverse acc, [], n )
- -- when we call this when checking type family patterns, we really
- -- do want to instantiate all invisible arguments. During other
- -- typechecking, we don't.
-
- go subst (binder:binders) all_args@(arg:args) n acc
- | isInvisibleBinder binder
- = do { traceTc "tc_infer_args (invis)" (ppr binder)
- ; (subst', arg') <- tcInstBinder mb_kind_info subst binder
- ; go subst' binders all_args n (arg' : acc) }
+ orig_subst = mkEmptyTCvSubst $ mkInScopeSet $ tyCoVarsOfType ki
+ (orig_ki_binders, orig_inner_ki) = tcSplitPiTys ki
+
+ go :: [LHsType GhcRn] -- already type-checked args, in reverse order, for errors
+ -> [TcType] -- already type-checked args, in reverse order
+ -> TCvSubst -- instantiating substitution
+ -> TcType -- function applied to some args, could be knot-tied
+ -> [TyBinder] -- binders in function kind (both vis. and invis.)
+ -> TcKind -- function kind body (not a Pi-type)
+ -> [LHsType GhcRn] -- un-type-checked args
+ -> Int -- the # of the next argument
+ -> TcM (TcType, [TcType], TcKind) -- same as overall return type
+
+ -- no user-written args left. We're done!
+ go _acc_hs_args acc_args subst fun ki_binders inner_ki [] _
+ = return (fun, reverse acc_args, substTy subst $ mkPiTys ki_binders inner_ki)
+
+ -- The function's kind has a binder. Is it visible or invisible?
+ go acc_hs_args acc_args subst fun (ki_binder:ki_binders) inner_ki
+ all_args@(arg:args) n
+ | isInvisibleBinder ki_binder
+ -- It's invisible. Instantiate.
+ = do { traceTc "tcInferApps (invis)" (ppr ki_binder $$ ppr subst)
+ ; (subst', arg') <- tcInstBinder mb_kind_info subst ki_binder
+ ; go acc_hs_args (arg' : acc_args) subst' (mkNakedAppTy fun arg')
+ ki_binders inner_ki all_args n }
| otherwise
- = do { traceTc "tc_infer_args (vis)" (ppr binder $$ ppr arg)
+ -- It's visible. Check the next user-written argument
+ = do { traceTc "tcInferApps (vis)" (ppr ki_binder $$ ppr arg $$ ppr subst)
; arg' <- addErrCtxt (funAppCtxt orig_ty arg n) $
- tc_lhs_type mode arg (substTyUnchecked subst $
- tyBinderType binder)
- ; let subst' = extendTvSubstBinder subst binder arg'
- ; go subst' binders args (n+1) (arg' : acc) }
+ tc_lhs_type mode arg (substTy subst $ tyBinderType ki_binder)
+ ; let subst' = extendTvSubstBinderAndInScope subst ki_binder arg'
+ ; go (arg : acc_hs_args) (arg' : acc_args) subst' (mkNakedAppTy fun arg')
+ ki_binders inner_ki args (n+1) }
- go subst [] all_args n acc
- = return (subst, [], reverse acc, all_args, n)
+ -- We've run out of known binders in the functions's kind.
+ go acc_hs_args acc_args subst fun [] inner_ki all_args n
+ | not (null new_ki_binders)
+ -- But, after substituting, we have more binders.
+ = go acc_hs_args acc_args zapped_subst fun new_ki_binders new_inner_ki all_args n
+
+ | otherwise
+ -- Even after substituting, still no binders. Use matchExpectedFunKind
+ = do { traceTc "tcInferApps (no binder)" (ppr new_inner_ki $$ ppr zapped_subst)
+ ; (co, arg_k, res_k)
+ <- matchExpectedFunKind (mkHsAppTys orig_ty (reverse acc_hs_args))
+ substed_inner_ki
+ ; let subst' = zapped_subst `extendTCvInScopeSet` tyCoVarsOfTypes [arg_k, res_k]
+ ; go acc_hs_args acc_args subst' (fun `mkNakedCastTy` co)
+ [mkAnonBinder arg_k] res_k all_args n }
+ where
+ substed_inner_ki = substTy subst inner_ki
+ (new_ki_binders, new_inner_ki) = tcSplitPiTys substed_inner_ki
+ zapped_subst = zapTCvSubst subst
-- | Applies a type to a list of arguments.
-- Always consumes all the arguments, using 'matchExpectedFunKind' as
-- necessary. If you wish to apply a type to a list of HsTypes, this is
-- your function.
-- Used for type-checking types only.
-tcInferApps :: Outputable fun
- => TcTyMode
- -> fun -- ^ Function (for printing only)
- -> TcType -- ^ Function (could be knot-tied)
- -> TcKind -- ^ Function kind (zonked)
- -> [LHsType GhcRn] -- ^ Args
- -> TcM (TcType, TcKind) -- ^ (f args, result kind)
-tcInferApps mode orig_ty ty ki args = go ty ki args 1
- where
- go fun fun_kind [] _ = return (fun, fun_kind)
- go fun fun_kind args n
- | let (binders, res_kind) = splitPiTys fun_kind
- , not (null binders)
- = do { (subst, leftover_binders, args', leftover_args, n')
- <- tc_infer_args mode orig_ty binders Nothing args n
- ; let fun_kind' = substTyUnchecked subst $
- mkPiTys leftover_binders res_kind
- ; go (mkNakedAppTys fun args') fun_kind' leftover_args n' }
-
- go fun fun_kind all_args@(arg:args) n
- = do { (co, arg_k, res_k) <- matchExpectedFunKind (length all_args)
- fun fun_kind
- ; arg' <- addErrCtxt (funAppCtxt orig_ty arg n) $
- tc_lhs_type mode arg arg_k
- ; go (mkNakedAppTy (fun `mkNakedCastTy` co) arg')
- res_k args (n+1) }
+tcTyApps :: TcTyMode
+ -> LHsType GhcRn -- ^ Function (for printing only)
+ -> TcType -- ^ Function (could be knot-tied)
+ -> TcKind -- ^ Function kind (zonked)
+ -> [LHsType GhcRn] -- ^ Args
+ -> TcM (TcType, TcKind) -- ^ (f args, result kind)
+tcTyApps mode orig_ty ty ki args
+ = do { (ty', _args, ki') <- tcInferApps mode Nothing orig_ty ty ki args
+ ; return (ty', ki') }
--------------------------
-checkExpectedKind :: TcType -- the type whose kind we're checking
- -> TcKind -- the known kind of that type, k
- -> TcKind -- the expected kind, exp_kind
- -> TcM TcType -- a possibly-inst'ed, casted type :: exp_kind
+-- like checkExpectedKindX, but returns only the final type; convenient wrapper
+checkExpectedKind :: HsType GhcRn
+ -> TcType
+ -> TcKind
+ -> TcKind
+ -> TcM TcType
+checkExpectedKind hs_ty ty act exp = fstOf3 <$> checkExpectedKindX Nothing (ppr hs_ty) ty act exp
+
+checkExpectedKindX :: Maybe (VarEnv Kind) -- Possibly, instantiations for kind vars
+ -> SDoc -- HsType whose kind we're checking
+ -> TcType -- the type whose kind we're checking
+ -> TcKind -- the known kind of that type, k
+ -> TcKind -- the expected kind, exp_kind
+ -> TcM (TcType, [TcType], TcCoercionN)
+ -- (an possibly-inst'ed, casted type :: exp_kind, the new args, the coercion)
-- Instantiate a kind (if necessary) and then call unifyType
-- (checkExpectedKind ty act_kind exp_kind)
-- checks that the actual kind act_kind is compatible
-- with the expected kind exp_kind
-checkExpectedKind ty act_kind exp_kind
- = do { (ty', act_kind') <- instantiate ty act_kind exp_kind
+checkExpectedKindX mb_kind_env pp_hs_ty ty act_kind exp_kind
+ = do { (ty', new_args, act_kind') <- instantiate ty act_kind exp_kind
; let origin = TypeEqOrigin { uo_actual = act_kind'
, uo_expected = exp_kind
- , uo_thing = Just $ mkTypeErrorThing ty'
- }
- ; co_k <- uType origin KindLevel act_kind' exp_kind
+ , uo_thing = Just pp_hs_ty
+ , uo_visible = True } -- the hs_ty is visible
+ ; co_k <- uType KindLevel origin act_kind' exp_kind
; traceTc "checkExpectedKind" (vcat [ ppr act_kind
, ppr exp_kind
, ppr co_k ])
; let result_ty = ty' `mkNakedCastTy` co_k
- ; return result_ty }
+ ; return (result_ty, new_args, co_k) }
where
-- we need to make sure that both kinds have the same number of implicit
-- foralls out front. If the actual kind has more, instantiate accordingly.
@@ -914,32 +916,50 @@ checkExpectedKind ty act_kind exp_kind
-> TcKind -- of this kind
-> TcKind -- but expected to be of this one
-> TcM ( TcType -- the inst'ed type
+ , [TcType] -- the new args
, TcKind ) -- its new kind
instantiate ty act_ki exp_ki
= let (exp_bndrs, _) = splitPiTysInvisible exp_ki in
- instantiateTyN (length exp_bndrs) ty act_ki
-
--- | Instantiate a type to have at most @n@ invisible arguments.
-instantiateTyN :: Int -- ^ @n@
- -> TcType -- ^ the type
- -> TcKind -- ^ its kind
- -> TcM (TcType, TcKind) -- ^ The inst'ed type with kind
-instantiateTyN n ty ki
- = let (bndrs, inner_ki) = splitPiTysInvisible ki
- num_to_inst = length bndrs - n
- -- NB: splitAt is forgiving with invalid numbers
- (inst_bndrs, leftover_bndrs) = splitAt num_to_inst bndrs
+ instantiateTyUntilN mb_kind_env (length exp_bndrs) ty act_ki
+
+-- | Instantiate @n@ invisible arguments to a type. If @n <= 0@, no instantiation
+-- occurs. If @n@ is too big, then all available invisible arguments are instantiated.
+-- (In other words, this function is very forgiving about bad values of @n@.)
+instantiateTyN :: Maybe (VarEnv Kind) -- ^ Predetermined instantiations
+ -- (for assoc. type patterns)
+ -> Int -- ^ @n@
+ -> TcType -- ^ the type
+ -> [TyBinder] -> TcKind -- ^ its kind
+ -> TcM (TcType, [TcType], TcKind) -- ^ The inst'ed type, new args, kind
+instantiateTyN mb_kind_env n ty bndrs inner_ki
+ = let -- NB: splitAt is forgiving with invalid numbers
+ (inst_bndrs, leftover_bndrs) = splitAt n bndrs
+ ki = mkPiTys bndrs inner_ki
empty_subst = mkEmptyTCvSubst (mkInScopeSet (tyCoVarsOfType ki))
in
- if num_to_inst <= 0 then return (ty, ki) else
- do { (subst, inst_args) <- tcInstBinders empty_subst Nothing inst_bndrs
+ if n <= 0 then return (ty, [], ki) else
+ do { (subst, inst_args) <- tcInstBinders empty_subst mb_kind_env inst_bndrs
; let rebuilt_ki = mkPiTys leftover_bndrs inner_ki
ki' = substTy subst rebuilt_ki
- ; traceTc "instantiateTyN" (vcat [ ppr ty <+> dcolon <+> ppr ki
+ ; traceTc "instantiateTyN" (vcat [ ppr ki
+ , ppr n
, ppr subst
, ppr rebuilt_ki
, ppr ki' ])
- ; return (mkNakedAppTys ty inst_args, ki') }
+ ; return (mkNakedAppTys ty inst_args, inst_args, ki') }
+
+-- | Instantiate a type to have at most @n@ invisible arguments.
+instantiateTyUntilN :: Maybe (VarEnv Kind) -- ^ Possibly, instantiations for vars
+ -> Int -- ^ @n@
+ -> TcType -- ^ the type
+ -> TcKind -- ^ its kind
+ -> TcM (TcType, [TcType], TcKind) -- ^ The inst'ed type, new args,
+ -- final kind
+instantiateTyUntilN mb_kind_env n ty ki
+ = let (bndrs, inner_ki) = splitPiTysInvisible ki
+ num_to_inst = length bndrs - n
+ in
+ instantiateTyN mb_kind_env num_to_inst ty bndrs inner_ki
---------------------------
tcHsContext :: LHsContext GhcRn -> TcM [PredType]
@@ -1012,8 +1032,8 @@ tcTyVar mode name -- Could be a tyvar, a tycon, or a datacon
-- if we are type-checking a type family tycon, we must instantiate
-- any invisible arguments right away. Otherwise, we get #11246
- handle_tyfams :: TyCon -- the tycon to instantiate (might be loopy)
- -> TyCon -- a non-loopy version of the tycon
+ handle_tyfams :: TyCon -- the tycon to instantiate (might be loopy)
+ -> TcTyCon -- a non-loopy version of the tycon
-> TcM (TcType, TcKind)
handle_tyfams tc tc_tc
| mightBeUnsaturatedTyCon tc_tc
@@ -1021,7 +1041,8 @@ tcTyVar mode name -- Could be a tyvar, a tycon, or a datacon
; return (ty, tc_kind) }
| otherwise
- = do { (tc_ty, kind) <- instantiateTyN 0 ty tc_kind
+ = do { (tc_ty, _, kind) <- instantiateTyN Nothing (length (tyConBinders tc_tc))
+ ty tc_kind_bndrs tc_inner_ki
-- tc and tc_ty must not be traced here, because that would
-- force the evaluation of a potentially knot-tied variable (tc),
-- and the typechecker would hang, as per #11708
@@ -1029,8 +1050,9 @@ tcTyVar mode name -- Could be a tyvar, a tycon, or a datacon
, ppr kind ])
; return (tc_ty, kind) }
where
- ty = mkNakedTyConApp tc []
- tc_kind = tyConKind tc_tc
+ ty = mkNakedTyConApp tc []
+ tc_kind = tyConKind tc_tc
+ (tc_kind_bndrs, tc_inner_ki) = splitPiTysInvisible tc_kind
get_loopy_tc :: Name -> TyCon -> TcM TyCon
-- Return the knot-tied global TyCon if there is one
@@ -1232,7 +1254,7 @@ Help functions for type applications
addTypeCtxt :: LHsType GhcRn -> TcM a -> TcM a
-- Wrap a context around only if we want to show that contexts.
- -- Omit invisble ones and ones user's won't grok
+ -- Omit invisible ones and ones user's won't grok
addTypeCtxt (L _ ty) thing
= addErrCtxt doc thing
where
@@ -1418,13 +1440,13 @@ kcHsTyVarBndrs name flav cusk all_kind_vars
= tcExtendTyVarEnv [tv] thing_inside
kc_hs_tv :: HsTyVarBndr GhcRn -> TcM (TcTyVar, Bool)
- kc_hs_tv (UserTyVar (L _ name))
+ kc_hs_tv (UserTyVar lname@(L _ name))
= do { tv_pair@(tv, scoped) <- tcHsTyVarName Nothing name
-- Open type/data families default their variables to kind *.
; when (open_fam && not scoped) $ -- (don't default class tyvars)
- discardResult $ unifyKind (Just (mkTyVarTy tv)) liftedTypeKind
- (tyVarKind tv)
+ discardResult $ unifyKind (Just (HsTyVar NotPromoted lname)) liftedTypeKind
+ (tyVarKind tv)
; return tv_pair }
@@ -1578,7 +1600,7 @@ tcHsTyVarName m_kind name
Just (ATyVar _ tv)
-> do { whenIsJust m_kind $ \ kind ->
discardResult $
- unifyKind (Just (mkTyVarTy tv)) kind (tyVarKind tv)
+ unifyKind (Just (HsTyVar NotPromoted (noLoc name))) kind (tyVarKind tv)
; return (tv, True) }
_ -> do { kind <- case m_kind of
Just kind -> return kind
@@ -1751,17 +1773,22 @@ tcTyClTyVars tycon_name thing_inside
thing_inside binders res_kind }
-----------------------------------
-tcDataKindSig :: Kind -> TcM ([TyConBinder], Kind)
+tcDataKindSig :: Bool -- ^ Do we require the result to be *?
+ -> Kind -> TcM ([TyConBinder], Kind)
-- GADT decls can have a (perhaps partial) kind signature
-- e.g. data T :: * -> * -> * where ...
-- This function makes up suitable (kinded) type variables for
--- the argument kinds, and checks that the result kind is indeed *.
+-- the argument kinds, and checks that the result kind is indeed * if requested.
+-- (Otherwise, checks to make sure that the result kind is either * or a type variable.)
+-- See Note [Arity of data families] in FamInstEnv for more info.
-- We use it also to make up argument type variables for for data instances.
-- Never emits constraints.
-- Returns the new TyVars, the extracted TyBinders, and the new, reduced
-- result kind (which should always be Type or a synonym thereof)
-tcDataKindSig kind
- = do { checkTc (isLiftedTypeKind res_kind) (badKindSig kind)
+tcDataKindSig check_for_type kind
+ = do { checkTc (isLiftedTypeKind res_kind || (not check_for_type &&
+ isJust (tcGetCastedTyVar_maybe res_kind)))
+ (badKindSig check_for_type kind)
; span <- getSrcSpanM
; us <- newUniqueSupply
; rdr_env <- getLocalRdrEnv
@@ -1781,9 +1808,11 @@ tcDataKindSig kind
where
(tv_bndrs, res_kind) = splitPiTys kind
-badKindSig :: Kind -> SDoc
-badKindSig kind
- = hang (text "Kind signature on data type declaration has non-* return kind")
+badKindSig :: Bool -> Kind -> SDoc
+badKindSig check_for_type kind
+ = hang (sep [ text "Kind signature on data type declaration has non-*"
+ , (if check_for_type then empty else text "and non-variable") <+>
+ text "return kind" ])
2 (ppr kind)
{-
@@ -2050,11 +2079,11 @@ in-scope variables that it should not unify with, but it's fiddly.
-}
-unifyKinds :: [(TcType, TcKind)] -> TcM ([TcType], TcKind)
-unifyKinds act_kinds
+unifyKinds :: [LHsType GhcRn] -> [(TcType, TcKind)] -> TcM ([TcType], TcKind)
+unifyKinds rn_tys act_kinds
= do { kind <- newMetaKindVar
- ; let check (ty, act_kind) = checkExpectedKind ty act_kind kind
- ; tys' <- mapM check act_kinds
+ ; let check rn_ty (ty, act_kind) = checkExpectedKind (unLoc rn_ty) ty act_kind kind
+ ; tys' <- zipWithM check rn_tys act_kinds
; return (tys', kind) }
{-
diff --git a/compiler/typecheck/TcInstDcls.hs b/compiler/typecheck/TcInstDcls.hs
index 12fa7e75c3..3b433052ef 100644
--- a/compiler/typecheck/TcInstDcls.hs
+++ b/compiler/typecheck/TcInstDcls.hs
@@ -488,7 +488,7 @@ tcClsInstDecl (L loc (ClsInstDecl { cid_poly_ty = poly_ty, cid_binds = binds
; let defined_ats = mkNameSet (map (tyFamInstDeclName . unLoc) ats)
`unionNameSet`
mkNameSet (map (unLoc . dfid_tycon . unLoc) adts)
- ; tyfam_insts1 <- mapM (tcATDefault True loc mini_subst defined_ats)
+ ; tyfam_insts1 <- mapM (tcATDefault loc mini_subst defined_ats)
(classATItems clas)
-- Finally, construct the Core representation of the instance.
@@ -626,9 +626,10 @@ tcDataFamInstDecl mb_clsinfo
(L loc decl@(DataFamInstDecl
{ dfid_pats = pats
, dfid_tycon = fam_tc_name
- , dfid_defn = defn@HsDataDefn { dd_ND = new_or_data, dd_cType = cType
- , dd_ctxt = ctxt, dd_cons = cons
- , dd_derivs = derivs } }))
+ , dfid_fixity = fixity
+ , dfid_defn = HsDataDefn { dd_ND = new_or_data, dd_cType = cType
+ , dd_ctxt = ctxt, dd_cons = cons
+ , dd_kindSig = m_ksig, dd_derivs = derivs } }))
= setSrcSpan loc $
tcAddDataFamInstCtxt decl $
do { fam_tc <- tcFamInstDeclCombined mb_clsinfo fam_tc_name
@@ -638,8 +639,9 @@ tcDataFamInstDecl mb_clsinfo
; checkTc (isDataFamilyTyCon fam_tc) (wrongKindOfFamily fam_tc)
-- Kind check type patterns
+ ; let mb_kind_env = thdOf3 <$> mb_clsinfo
; tcFamTyPats (famTyConShape fam_tc) mb_clsinfo pats
- (kcDataDefn (unLoc fam_tc_name) pats defn) $
+ (kcDataDefn mb_kind_env decl) $
\tvs pats res_kind ->
do { stupid_theta <- solveEqualities $ tcHsContext ctxt
@@ -655,17 +657,27 @@ tcDataFamInstDecl mb_clsinfo
; rep_tc_name <- newFamInstTyConName fam_tc_name pats'
; axiom_name <- newFamInstAxiomName fam_tc_name [pats']
+ -- Deal with any kind signature.
+ -- See also Note [Arity of data families] in FamInstEnv
+ ; (extra_tcbs, final_res_kind) <- tcDataKindSig True res_kind'
+
; let (eta_pats, etad_tvs) = eta_reduce pats'
eta_tvs = filterOut (`elem` etad_tvs) tvs'
+ -- NB: the "extra" tvs from tcDataKindSig would always be eta-reduced
+
full_tvs = eta_tvs ++ etad_tvs
-- Put the eta-removed tyvars at the end
-- Remember, tvs' is in arbitrary order (except kind vars are
-- first, so there is no reason to suppose that the etad_tvs
-- (obtained from the pats) are at the end (Trac #11148)
- orig_res_ty = mkTyConApp fam_tc pats'
+
+ extra_pats = map (mkTyVarTy . binderVar) extra_tcbs
+ all_pats = pats' `chkAppend` extra_pats
+ orig_res_ty = mkTyConApp fam_tc all_pats
; (rep_tc, axiom) <- fixM $ \ ~(rec_rep_tc, _) ->
- do { let ty_binders = mkTyConBindersPreferAnon full_tvs liftedTypeKind
+ do { let ty_binders = mkTyConBindersPreferAnon full_tvs res_kind'
+ `chkAppend` extra_tcbs
; data_cons <- tcConDecls rec_rep_tc
(ty_binders, orig_res_ty) cons
; tc_rhs <- case new_or_data of
@@ -676,14 +688,14 @@ tcDataFamInstDecl mb_clsinfo
; let axiom = mkSingleCoAxiom Representational
axiom_name eta_tvs [] fam_tc eta_pats
(mkTyConApp rep_tc (mkTyVarTys eta_tvs))
- parent = DataFamInstTyCon axiom fam_tc pats'
+ parent = DataFamInstTyCon axiom fam_tc all_pats
- -- NB: Use the full_tvs from the pats. See bullet toward
+ -- NB: Use the full ty_binders from the pats. See bullet toward
-- the end of Note [Data type families] in TyCon
rep_tc = mkAlgTyCon rep_tc_name
ty_binders liftedTypeKind
- (map (const Nominal) full_tvs)
+ (map (const Nominal) ty_binders)
(fmap unLoc cType) stupid_theta
tc_rhs parent
gadt_syntax
@@ -697,10 +709,10 @@ tcDataFamInstDecl mb_clsinfo
-- Remember to check validity; no recursion to worry about here
-- Check that left-hand sides are ok (mono-types, no type families,
-- consistent instantiations, etc)
- ; checkValidFamPats mb_clsinfo fam_tc tvs' [] pats'
+ ; checkValidFamPats mb_clsinfo fam_tc tvs' [] pats' extra_pats pp_hs_pats
-- Result kind must be '*' (otherwise, we have too few patterns)
- ; checkTc (isLiftedTypeKind res_kind') $
+ ; checkTc (isLiftedTypeKind final_res_kind) $
tooFewParmsErr (tyConArity fam_tc)
; checkValidTyCon rep_tc
@@ -730,6 +742,7 @@ tcDataFamInstDecl mb_clsinfo
= go pats (tv : etad_tvs)
go pats etad_tvs = (reverse pats, etad_tvs)
+ pp_hs_pats = pprFamInstLHS fam_tc_name pats fixity (unLoc ctxt) m_ksig
{- *********************************************************************
* *
@@ -876,7 +889,8 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds })
, abs_ev_varsa = dfun_ev_vars
, abs_exports = [export]
, abs_ev_binds = []
- , abs_binds = unitBag dict_bind }
+ , abs_binds = unitBag dict_bind
+ , abs_sig = True }
; return (unitBag (L loc main_bind) `unionBags` sc_meth_binds)
}
@@ -1024,7 +1038,8 @@ tcSuperClasses dfun_id cls tyvars dfun_evs inst_tys dfun_ev_binds sc_theta
, abs_ev_varsa = dfun_evs
, abs_exports = [export]
, abs_ev_binds = [dfun_ev_binds, local_ev_binds]
- , abs_binds = emptyBag }
+ , abs_binds = emptyBag
+ , abs_sig = False }
; return (sc_top_id, L loc bind, sc_implic) }
-------------------
@@ -1361,17 +1376,18 @@ tcMethodBody clas tyvars dfun_ev_vars inst_tys
; spec_prags <- tcSpecPrags global_meth_id prags
; let specs = mk_meth_spec_prags global_meth_id spec_inst_prags spec_prags
- export = ABE { abe_poly = global_meth_id
- , abe_mono = local_meth_id
- , abe_wrap = idHsWrapper
- , abe_prags = specs }
+ export = ABE { abe_poly = global_meth_id
+ , abe_mono = local_meth_id
+ , abe_wrap = idHsWrapper
+ , abe_prags = specs }
local_ev_binds = TcEvBinds ev_binds_var
full_bind = AbsBinds { abs_tvsa = tyvars
, abs_ev_varsa = dfun_ev_vars
, abs_exports = [export]
, abs_ev_binds = [dfun_ev_binds, local_ev_binds]
- , abs_binds = tc_bind }
+ , abs_binds = tc_bind
+ , abs_sig = True }
; return (global_meth_id, L bind_loc full_bind, Just meth_implic) }
where
@@ -1416,7 +1432,8 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind
; return (unitBag $ L (getLoc meth_bind) $
AbsBinds { abs_tvsa = [], abs_ev_varsa = []
, abs_exports = [export]
- , abs_binds = tc_bind, abs_ev_binds = [] }) }
+ , abs_binds = tc_bind, abs_ev_binds = []
+ , abs_sig = True }) }
| otherwise -- No instance signature
= do { let ctxt = FunSigCtxt sel_name False
diff --git a/compiler/typecheck/TcInteract.hs b/compiler/typecheck/TcInteract.hs
index e1550256c2..ed473fe7eb 100644
--- a/compiler/typecheck/TcInteract.hs
+++ b/compiler/typecheck/TcInteract.hs
@@ -528,7 +528,8 @@ solveOneFromTheOther ev_i ev_w
| CtWanted { ctev_loc = loc_w } <- ev_w
, prohibitedSuperClassSolve (ctEvLoc ev_i) loc_w
- = return (IRDelete, False)
+ = do { traceTcS "prohibitedClassSolve1" (ppr ev_i $$ ppr ev_w)
+ ; return (IRDelete, False) }
| CtWanted { ctev_dest = dest } <- ev_w
-- Inert is Given or Wanted
@@ -537,9 +538,10 @@ solveOneFromTheOther ev_i ev_w
| CtWanted { ctev_loc = loc_i } <- ev_i -- Work item is Given
, prohibitedSuperClassSolve (ctEvLoc ev_w) loc_i
- = return (IRKeep, False) -- Just discard the un-usable Given
- -- This never actually happens because
- -- Givens get processed first
+ = do { traceTcS "prohibitedClassSolve2" (ppr ev_i $$ ppr ev_w)
+ ; return (IRKeep, False) } -- Just discard the un-usable Given
+ -- This never actually happens because
+ -- Givens get processed first
| CtWanted { ctev_dest = dest } <- ev_i
= do { setWantedEvTerm dest (ctEvTerm ev_w)
@@ -878,6 +880,7 @@ interactDict inerts workItem@(CDictCan { cc_ev = ev_w, cc_class = cls, cc_tyargs
-- we solve it from the solution in the inerts we just retrieved.
Nothing -> do
{ (inert_effect, stop_now) <- solveOneFromTheOther ctev_i ev_w
+ ; traceTcS "lookupInertDict" (ppr inert_effect <+> ppr stop_now)
; case inert_effect of
IRKeep -> return ()
IRDelete -> updInertDicts $ \ ds -> delDict ds cls tys
diff --git a/compiler/typecheck/TcMType.hs b/compiler/typecheck/TcMType.hs
index 0a1de443b3..19b0381d2d 100644
--- a/compiler/typecheck/TcMType.hs
+++ b/compiler/typecheck/TcMType.hs
@@ -66,7 +66,6 @@ module TcMType (
--------------------------------
-- Zonking and tidying
zonkTidyTcType, zonkTidyOrigin,
- mkTypeErrorThing, mkTypeErrorThingArgs,
tidyEvVar, tidyCt, tidySkolemInfo,
skolemiseRuntimeUnk,
zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar,
@@ -1526,32 +1525,17 @@ zonkTidyTcType :: TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType env ty = do { ty' <- zonkTcType ty
; return (tidyOpenType env ty') }
--- | Make an 'ErrorThing' storing a type.
-mkTypeErrorThing :: TcType -> ErrorThing
-mkTypeErrorThing ty = ErrorThing ty (Just $ length $ snd $ repSplitAppTys ty)
- zonkTidyTcType
- -- NB: Use *rep*splitAppTys, else we get #11313
-
--- | Make an 'ErrorThing' storing a type, with some extra args known about
-mkTypeErrorThingArgs :: TcType -> Int -> ErrorThing
-mkTypeErrorThingArgs ty num_args
- = ErrorThing ty (Just $ (length $ snd $ repSplitAppTys ty) + num_args)
- zonkTidyTcType
-
zonkTidyOrigin :: TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
zonkTidyOrigin env (GivenOrigin skol_info)
= do { skol_info1 <- zonkSkolemInfo skol_info
; let skol_info2 = tidySkolemInfo env skol_info1
; return (env, GivenOrigin skol_info2) }
zonkTidyOrigin env orig@(TypeEqOrigin { uo_actual = act
- , uo_expected = exp
- , uo_thing = m_thing })
+ , uo_expected = exp })
= do { (env1, act') <- zonkTidyTcType env act
; (env2, exp') <- zonkTidyTcType env1 exp
- ; (env3, m_thing') <- zonkTidyErrorThing env2 m_thing
- ; return ( env3, orig { uo_actual = act'
- , uo_expected = exp'
- , uo_thing = m_thing' }) }
+ ; return ( env2, orig { uo_actual = act'
+ , uo_expected = exp' }) }
zonkTidyOrigin env (KindEqOrigin ty1 m_ty2 orig t_or_k)
= do { (env1, ty1') <- zonkTidyTcType env ty1
; (env2, m_ty2') <- case m_ty2 of
@@ -1570,14 +1554,6 @@ zonkTidyOrigin env (FunDepOrigin2 p1 o1 p2 l2)
; return (env3, FunDepOrigin2 p1' o1' p2' l2) }
zonkTidyOrigin env orig = return (env, orig)
-zonkTidyErrorThing :: TidyEnv -> Maybe ErrorThing
- -> TcM (TidyEnv, Maybe ErrorThing)
-zonkTidyErrorThing env (Just (ErrorThing thing n_args zonker))
- = do { (env', thing') <- zonker env thing
- ; return (env', Just $ ErrorThing thing' n_args zonker) }
-zonkTidyErrorThing env Nothing
- = return (env, Nothing)
-
----------------
tidyCt :: TidyEnv -> Ct -> Ct
-- Used only in error reporting
diff --git a/compiler/typecheck/TcMatches.hs b/compiler/typecheck/TcMatches.hs
index d8ee608436..185bace9f4 100644
--- a/compiler/typecheck/TcMatches.hs
+++ b/compiler/typecheck/TcMatches.hs
@@ -99,10 +99,11 @@ tcMatchesFun fn@(L _ fun_name) matches exp_ty
arity = matchGroupArity matches
herald = text "The equation(s) for"
<+> quotes (ppr fun_name) <+> text "have"
- match_ctxt = MC { mc_what = FunRhs fn Prefix strictness, mc_body = tcBody }
+ what = FunRhs { mc_fun = fn, mc_fixity = Prefix, mc_strictness = strictness }
+ match_ctxt = MC { mc_what = what, mc_body = tcBody }
strictness
| [L _ match] <- unLoc $ mg_alts matches
- , FunRhs{mc_strictness = SrcStrict} <- m_ctxt match
+ , FunRhs{ mc_strictness = SrcStrict } <- m_ctxt match
= SrcStrict
| otherwise
= NoSrcStrict
@@ -231,11 +232,13 @@ tcMatch :: (Outputable (body (GHC GhcRn))) => TcMatchCtxt body
tcMatch ctxt pat_tys rhs_ty match
= wrapLocM (tc_match ctxt pat_tys rhs_ty) match
where
- tc_match ctxt pat_tys rhs_ty match@(Match _ pats maybe_rhs_sig grhss)
+ tc_match ctxt pat_tys rhs_ty
+ match@(Match { m_pats = pats, m_type = maybe_rhs_sig, m_grhss = grhss })
= add_match_ctxt match $
do { (pats', grhss') <- tcPats (mc_what ctxt) pats pat_tys $
tc_grhss ctxt maybe_rhs_sig grhss rhs_ty
- ; return (Match (mc_what ctxt) pats' Nothing grhss') }
+ ; return (Match { m_ctxt = mc_what ctxt, m_pats = pats'
+ , m_type = Nothing, m_grhss = grhss' }) }
tc_grhss ctxt Nothing grhss rhs_ty
= tcGRHSs ctxt grhss rhs_ty -- No result signature
@@ -1134,4 +1137,4 @@ checkArgs fun (MG { mg_alts = L _ (match1:matches) })
bad_matches = [m | m <- matches, args_in_match m /= n_args1]
args_in_match :: LMatch GhcRn body -> Int
- args_in_match (L _ (Match _ pats _ _)) = length pats
+ args_in_match (L _ (Match { m_pats = pats })) = length pats
diff --git a/compiler/typecheck/TcPat.hs b/compiler/typecheck/TcPat.hs
index 0d0e16a346..18b148d8b6 100644
--- a/compiler/typecheck/TcPat.hs
+++ b/compiler/typecheck/TcPat.hs
@@ -348,7 +348,7 @@ tc_pat penv (LazyPat pat) pat_ty thing_inside
-- Check that the expected pattern type is itself lifted
; pat_ty <- readExpType pat_ty
- ; _ <- unifyType noThing (typeKind pat_ty) liftedTypeKind
+ ; _ <- unifyType Nothing (typeKind pat_ty) liftedTypeKind
; return (LazyPat pat', res) }
@@ -382,7 +382,7 @@ tc_pat penv (ViewPat expr pat _) overall_pat_ty thing_inside
; let expr_orig = lexprCtOrigin expr
herald = text "A view pattern expression expects"
; (expr_wrap1, [inf_arg_ty], inf_res_ty)
- <- matchActualFunTys herald expr_orig (Just expr) 1 expr'_inferred
+ <- matchActualFunTys herald expr_orig (Just (unLoc expr)) 1 expr'_inferred
-- expr_wrap1 :: expr'_inferred "->" (inf_arg_ty -> inf_res_ty)
-- check that overall pattern is more polymorphic than arg type
@@ -896,7 +896,7 @@ matchExpectedConTy (PE { pe_orig = orig }) data_tc exp_pat_ty
ppr exp_pat_ty,
ppr pat_ty,
ppr pat_rho, ppr wrap])
- ; co1 <- unifyType noThing (mkTyConApp fam_tc (substTys subst fam_args)) pat_rho
+ ; co1 <- unifyType Nothing (mkTyConApp fam_tc (substTys subst fam_args)) pat_rho
-- co1 : T (ty1,ty2) ~N pat_rho
-- could use tcSubType here... but it's the wrong way round
-- for actual vs. expected in error messages.
diff --git a/compiler/typecheck/TcPatSyn.hs b/compiler/typecheck/TcPatSyn.hs
index 95161816af..0004bee119 100644
--- a/compiler/typecheck/TcPatSyn.hs
+++ b/compiler/typecheck/TcPatSyn.hs
@@ -15,8 +15,7 @@ module TcPatSyn ( tcInferPatSynDecl, tcCheckPatSynDecl
import HsSyn
import TcPat
-import Type( mkTyVarBinders, mkEmptyTCvSubst
- , tidyTyVarBinders, tidyTypes, tidyType )
+import Type( mkEmptyTCvSubst, tidyTyVarBinders, tidyTypes, tidyType )
import TcRnMonad
import TcSigs( emptyPragEnv, completeSigFromId )
import TcEnv
@@ -81,8 +80,8 @@ tcInferPatSynDecl PSB{ psb_id = lname@(L _ name), psb_args = details,
; let named_taus = (name, pat_ty) : map (\arg -> (getName arg, varType arg)) args
- ; (qtvs, req_dicts, ev_binds) <- simplifyInfer tclvl NoRestrictions []
- named_taus wanted
+ ; (qtvs, req_dicts, ev_binds, _) <- simplifyInfer tclvl NoRestrictions []
+ named_taus wanted
; let (ex_tvs, prov_dicts) = tcCollectEx lpat'
ex_tv_set = mkVarSet ex_tvs
diff --git a/compiler/typecheck/TcRnDriver.hs b/compiler/typecheck/TcRnDriver.hs
index 9e7a560ba8..289c1516fd 100644
--- a/compiler/typecheck/TcRnDriver.hs
+++ b/compiler/typecheck/TcRnDriver.hs
@@ -2191,9 +2191,9 @@ tcRnExpr hsc_env mode rdr_expr
else return expr_ty } ;
-- Generalise
- ((qtvs, dicts, _), lie_top) <- captureTopConstraints $
- {-# SCC "simplifyInfer" #-}
- simplifyInfer tclvl
+ ((qtvs, dicts, _, _), lie_top) <- captureTopConstraints $
+ {-# SCC "simplifyInfer" #-}
+ simplifyInfer tclvl
infer_mode
[] {- No sig vars -}
[(fresh_it, res_ty)]
diff --git a/compiler/typecheck/TcRnTypes.hs b/compiler/typecheck/TcRnTypes.hs
index 6383b57c28..381710b938 100644
--- a/compiler/typecheck/TcRnTypes.hs
+++ b/compiler/typecheck/TcRnTypes.hs
@@ -95,9 +95,9 @@ module TcRnTypes(
CtLoc(..), ctLocSpan, ctLocEnv, ctLocLevel, ctLocOrigin,
ctLocTypeOrKind_maybe,
ctLocDepth, bumpCtLocDepth,
- setCtLocOrigin, setCtLocEnv, setCtLocSpan,
+ setCtLocOrigin, updateCtLocOrigin, setCtLocEnv, setCtLocSpan,
CtOrigin(..), exprCtOrigin, lexprCtOrigin, matchesCtOrigin, grhssCtOrigin,
- ErrorThing(..), mkErrorThing, errorThingNumArgs_maybe,
+ isVisibleOrigin, toInvisibleOrigin,
TypeOrKind(..), isTypeLevel, isKindLevel,
pprCtOrigin, pprCtLoc,
pushErrCtxt, pushErrCtxtSameOrigin,
@@ -106,7 +106,7 @@ module TcRnTypes(
termEvidenceAllowed,
CtEvidence(..), TcEvDest(..),
- mkGivenLoc, mkKindLoc, toKindLoc,
+ mkKindLoc, toKindLoc, mkGivenLoc,
isWanted, isGiven, isDerived, isGivenOrWDeriv,
ctEvRole,
@@ -183,9 +183,7 @@ import Util
import PrelNames ( isUnboundName )
import Control.Monad (ap, liftM, msum)
-#if __GLASGOW_HASKELL__ > 710
import qualified Control.Monad.Fail as MonadFail
-#endif
import Data.Set ( Set )
import qualified Data.Set as S
@@ -1083,7 +1081,7 @@ data PromotionErr
-- See Note [Don't promote pattern synonyms] in TcEnv
| RecDataConPE -- Data constructor in a recursive loop
- -- See Note [ARecDataCon: recusion and promoting data constructors] in TcTyClsDecls
+ -- See Note [Recursion and promoting data constructors] in TcTyClsDecls
| NoDataKindsTC -- -XDataKinds not enabled (for a tycon)
| NoDataKindsDC -- -XDataKinds not enabled (for a datacon)
| NoTypeInTypeTC -- -XTypeInType not enabled (for a tycon)
@@ -1617,7 +1615,7 @@ data Ct
-- * tv not in tvs(rhs) (occurs check)
-- * If tv is a TauTv, then rhs has no foralls
-- (this avoids substituting a forall for the tyvar in other types)
- -- * typeKind ty `tcEqKind` typeKind tv
+ -- * typeKind ty `tcEqKind` typeKind tv; Note [Ct kind invariant]
-- * rhs may have at most one top-level cast
-- * rhs (perhaps under the one cast) is not necessarily function-free,
-- but it has no top-level function.
@@ -1640,7 +1638,7 @@ data Ct
| CFunEqCan { -- F xis ~ fsk
-- Invariants:
-- * isTypeFamilyTyCon cc_fun
- -- * typeKind (F xis) = tyVarKind fsk
+ -- * typeKind (F xis) = tyVarKind fsk; Note [Ct kind invariant]
-- * always Nominal role
cc_ev :: CtEvidence, -- See Note [Ct/evidence invariant]
cc_fun :: TyCon, -- A type function
@@ -1717,6 +1715,14 @@ built (in TcCanonical).
In contrast, the type of the evidence *term* (ctev_dest / ctev_evar) in
the evidence may *not* be fully zonked; we are careful not to look at it
during constraint solving. See Note [Evidence field of CtEvidence].
+
+Note [Ct kind invariant]
+~~~~~~~~~~~~~~~~~~~~~~~~
+CTyEqCan and CFunEqCan both require that the kind of the lhs matches the kind
+of the rhs. This is necessary because both constraints are used for substitutions
+during solving. If the kinds differed, then the substitution would take a well-kinded
+type to an ill-kinded one.
+
-}
mkNonCanonical :: CtEvidence -> Ct
@@ -2246,7 +2252,13 @@ getInsolubles = wc_insol
insolublesOnly :: WantedConstraints -> WantedConstraints
-- Keep only the insolubles
-insolublesOnly wc = wc { wc_simple = emptyBag, wc_impl = emptyBag }
+insolublesOnly (WC { wc_insol = insols, wc_impl = implics })
+ = WC { wc_simple = emptyBag
+ , wc_insol = insols
+ , wc_impl = mapBag implic_insols_only implics }
+ where
+ implic_insols_only implic
+ = implic { ic_wanted = insolublesOnly (ic_wanted implic) }
dropDerivedWC :: WantedConstraints -> WantedConstraints
-- See Note [Dropping derived constraints]
@@ -2904,25 +2916,20 @@ The 'CtLoc' gives information about where a constraint came from.
This is important for decent error message reporting because
dictionaries don't appear in the original source code.
type will evolve...
+
-}
data CtLoc = CtLoc { ctl_origin :: CtOrigin
, ctl_env :: TcLclEnv
, ctl_t_or_k :: Maybe TypeOrKind -- OK if we're not sure
, ctl_depth :: !SubGoalDepth }
+
-- The TcLclEnv includes particularly
-- source location: tcl_loc :: RealSrcSpan
-- context: tcl_ctxt :: [ErrCtxt]
-- binder stack: tcl_bndrs :: TcIdBinderStack
-- level: tcl_tclvl :: TcLevel
-mkGivenLoc :: TcLevel -> SkolemInfo -> TcLclEnv -> CtLoc
-mkGivenLoc tclvl skol_info env
- = CtLoc { ctl_origin = GivenOrigin skol_info
- , ctl_env = env { tcl_tclvl = tclvl }
- , ctl_t_or_k = Nothing -- this only matters for error msgs
- , ctl_depth = initialSubGoalDepth }
-
mkKindLoc :: TcType -> TcType -- original *types* being compared
-> CtLoc -> CtLoc
mkKindLoc s1 s2 loc = setCtLocOrigin (toKindLoc loc)
@@ -2933,6 +2940,13 @@ mkKindLoc s1 s2 loc = setCtLocOrigin (toKindLoc loc)
toKindLoc :: CtLoc -> CtLoc
toKindLoc loc = loc { ctl_t_or_k = Just KindLevel }
+mkGivenLoc :: TcLevel -> SkolemInfo -> TcLclEnv -> CtLoc
+mkGivenLoc tclvl skol_info env
+ = CtLoc { ctl_origin = GivenOrigin skol_info
+ , ctl_env = env { tcl_tclvl = tclvl }
+ , ctl_t_or_k = Nothing -- this only matters for error msgs
+ , ctl_depth = initialSubGoalDepth }
+
ctLocEnv :: CtLoc -> TcLclEnv
ctLocEnv = ctl_env
@@ -2960,6 +2974,10 @@ bumpCtLocDepth loc@(CtLoc { ctl_depth = d }) = loc { ctl_depth = bumpSubGoalDept
setCtLocOrigin :: CtLoc -> CtOrigin -> CtLoc
setCtLocOrigin ctl orig = ctl { ctl_origin = orig }
+updateCtLocOrigin :: CtLoc -> (CtOrigin -> CtOrigin) -> CtLoc
+updateCtLocOrigin ctl@(CtLoc { ctl_origin = orig }) upd
+ = ctl { ctl_origin = upd orig }
+
setCtLocEnv :: CtLoc -> TcLclEnv -> CtLoc
setCtLocEnv ctl env = ctl { ctl_env = env }
@@ -3150,8 +3168,12 @@ data CtOrigin
| TypeEqOrigin { uo_actual :: TcType
, uo_expected :: TcType
- , uo_thing :: Maybe ErrorThing
- -- ^ The thing that has type "actual"
+ , uo_thing :: Maybe SDoc
+ -- ^ The thing that has type "actual"
+ , uo_visible :: Bool
+ -- ^ Is at least one of the three elements above visible?
+ -- (Errors from the polymorphic subsumption check are considered
+ -- visible.) Only used for prioritizing error messages.
}
| KindEqOrigin
@@ -3227,13 +3249,6 @@ data CtOrigin
-- Skolem variable arose when we were testing if an instance
-- is solvable or not.
--- | A thing that can be stored for error message generation only.
--- It is stored with a function to zonk and tidy the thing.
-data ErrorThing
- = forall a. Outputable a => ErrorThing a
- (Maybe Arity) -- # of args, if known
- (TidyEnv -> a -> TcM (TidyEnv, a))
-
-- | Flag to see whether we're type-checking terms or kind-checking types
data TypeOrKind = TypeLevel | KindLevel
deriving Eq
@@ -3250,20 +3265,24 @@ isKindLevel :: TypeOrKind -> Bool
isKindLevel TypeLevel = False
isKindLevel KindLevel = True
--- | Make an 'ErrorThing' that doesn't need tidying or zonking
-mkErrorThing :: Outputable a => a -> ErrorThing
-mkErrorThing thing = ErrorThing thing Nothing (\env x -> return (env, x))
-
--- | Retrieve the # of arguments in the error thing, if known
-errorThingNumArgs_maybe :: ErrorThing -> Maybe Arity
-errorThingNumArgs_maybe (ErrorThing _ args _) = args
+-- An origin is visible if the place where the constraint arises is manifest
+-- in user code. Currently, all origins are visible except for invisible
+-- TypeEqOrigins. This is used when choosing which error of
+-- several to report
+isVisibleOrigin :: CtOrigin -> Bool
+isVisibleOrigin (TypeEqOrigin { uo_visible = vis }) = vis
+isVisibleOrigin (KindEqOrigin _ _ sub_orig _) = isVisibleOrigin sub_orig
+isVisibleOrigin _ = True
+
+-- Converts a visible origin to an invisible one, if possible. Currently,
+-- this works only for TypeEqOrigin
+toInvisibleOrigin :: CtOrigin -> CtOrigin
+toInvisibleOrigin orig@(TypeEqOrigin {}) = orig { uo_visible = False }
+toInvisibleOrigin orig = orig
instance Outputable CtOrigin where
ppr = pprCtOrigin
-instance Outputable ErrorThing where
- ppr (ErrorThing thing _ _) = ppr thing
-
ctoHerald :: SDoc
ctoHerald = text "arising from"
@@ -3460,7 +3479,7 @@ pprCtO DefaultOrigin = text "a 'default' declaration"
pprCtO DoOrigin = text "a do statement"
pprCtO MCompOrigin = text "a statement in a monad comprehension"
pprCtO ProcOrigin = text "a proc expression"
-pprCtO (TypeEqOrigin t1 t2 _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2]
+pprCtO (TypeEqOrigin t1 t2 _ _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2]
pprCtO AnnOrigin = text "an annotation"
pprCtO HoleOrigin = text "a use of" <+> quotes (text "_")
pprCtO ListOrigin = text "an overloaded list"
@@ -3492,10 +3511,8 @@ instance Monad TcPluginM where
TcPluginM (\ ev -> do a <- m ev
runTcPluginM (k a) ev)
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail.MonadFail TcPluginM where
fail x = TcPluginM (const $ fail x)
-#endif
runTcPluginM :: TcPluginM a -> EvBindsVar -> TcM a
runTcPluginM (TcPluginM m) = m
diff --git a/compiler/typecheck/TcSMonad.hs b/compiler/typecheck/TcSMonad.hs
index b5f6554766..eaa84d6d13 100644
--- a/compiler/typecheck/TcSMonad.hs
+++ b/compiler/typecheck/TcSMonad.hs
@@ -160,9 +160,7 @@ import Maybes
import TrieMap
import Control.Monad
-#if __GLASGOW_HASKELL__ > 710
import qualified Control.Monad.Fail as MonadFail
-#endif
import MonadUtils
import Data.IORef
import Data.List ( foldl', partition )
@@ -2067,7 +2065,7 @@ solvable from the other. So, we do lookup in the inert set using
loose types, which omit the kind-check.
We must be careful when using the result of a lookup because it may
-not match the requsted info exactly!
+not match the requested info exactly!
-}
@@ -2298,10 +2296,8 @@ instance Monad TcS where
fail err = TcS (\_ -> fail err)
m >>= k = TcS (\ebs -> unTcS m ebs >>= \r -> unTcS (k r) ebs)
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail.MonadFail TcS where
fail err = TcS (\_ -> fail err)
-#endif
instance MonadUnique TcS where
getUniqueSupplyM = wrapTcS getUniqueSupplyM
diff --git a/compiler/typecheck/TcSigs.hs b/compiler/typecheck/TcSigs.hs
index c898fd96bd..3ff93b6bfa 100644
--- a/compiler/typecheck/TcSigs.hs
+++ b/compiler/typecheck/TcSigs.hs
@@ -32,7 +32,7 @@ import TcRnMonad
import TcType
import TcMType
import TcValidity ( checkValidType )
-import TcUnify( tcSkolemise, unifyType, noThing )
+import TcUnify( tcSkolemise, unifyType )
import Inst( topInstantiate )
import TcEnv( tcLookupId )
import TcEvidence( HsWrapper, (<.>) )
@@ -722,7 +722,7 @@ tcSpecWrapper ctxt poly_ty spec_ty
= do { (sk_wrap, inst_wrap)
<- tcSkolemise ctxt spec_ty $ \ _ spec_tau ->
do { (inst_wrap, tau) <- topInstantiate orig poly_ty
- ; _ <- unifyType noThing spec_tau tau
+ ; _ <- unifyType Nothing spec_tau tau
-- Deliberately ignore the evidence
-- See Note [Handling SPECIALISE pragmas],
-- wrinkle (2)
diff --git a/compiler/typecheck/TcSimplify.hs b/compiler/typecheck/TcSimplify.hs
index 42c113610b..1d28eeee4c 100644
--- a/compiler/typecheck/TcSimplify.hs
+++ b/compiler/typecheck/TcSimplify.hs
@@ -22,6 +22,7 @@ import Class ( Class, classKey, classTyCon )
import DynFlags ( WarningFlag ( Opt_WarnMonomorphism )
, WarnReason ( Reason )
, DynFlags( solverIterations ) )
+import Id ( idType )
import Inst
import ListSetOps
import Maybes
@@ -50,7 +51,9 @@ import ErrUtils ( emptyMessages )
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
-import Data.List ( partition )
+import Data.Foldable ( toList )
+import Data.List ( partition )
+import Data.List.NonEmpty ( NonEmpty(..) )
{-
*********************************************************************************
@@ -576,14 +579,16 @@ simplifyInfer :: TcLevel -- Used when generating the constraints
-> WantedConstraints
-> TcM ([TcTyVar], -- Quantify over these type variables
[EvVar], -- ... and these constraints (fully zonked)
- TcEvBinds) -- ... binding these evidence variables
+ TcEvBinds, -- ... binding these evidence variables
+ Bool) -- True <=> there was an insoluble type error
+ -- in these bindings
simplifyInfer rhs_tclvl infer_mode sigs name_taus wanteds
| isEmptyWC wanteds
= do { gbl_tvs <- tcGetGlobalTyCoVars
; dep_vars <- zonkTcTypesAndSplitDepVars (map snd name_taus)
; qtkvs <- quantifyTyVars gbl_tvs dep_vars
; traceTc "simplifyInfer: empty WC" (ppr name_taus $$ ppr qtkvs)
- ; return (qtkvs, [], emptyTcEvBinds) }
+ ; return (qtkvs, [], emptyTcEvBinds, False) }
| otherwise
= do { traceTc "simplifyInfer {" $ vcat
@@ -611,33 +616,31 @@ simplifyInfer rhs_tclvl infer_mode sigs name_taus wanteds
; wanted_transformed_incl_derivs
<- setTcLevel rhs_tclvl $
runTcSWithEvBinds ev_binds_var $
- do { let loc = mkGivenLoc rhs_tclvl UnkSkol tc_lcl_env
+ do { let loc = mkGivenLoc rhs_tclvl UnkSkol tc_lcl_env
psig_givens = mkGivens loc psig_theta_vars
; _ <- solveSimpleGivens psig_givens
-- See Note [Add signature contexts as givens]
; wanteds' <- solveWanteds wanteds
; TcS.zonkWC wanteds' }
+
-- Find quant_pred_candidates, the predicates that
-- we'll consider quantifying over
-- NB1: wanted_transformed does not include anything provable from
-- the psig_theta; it's just the extra bit
-- NB2: We do not do any defaulting when inferring a type, this can lead
-- to less polymorphic types, see Note [Default while Inferring]
-
- ; let wanted_transformed = dropDerivedWC wanted_transformed_incl_derivs
- quant_pred_candidates -- Fully zonked
- | insolubleWC wanted_transformed_incl_derivs
- = [] -- See Note [Quantification with errors]
- -- NB: must include derived errors in this test,
- -- hence "incl_derivs"
-
- | otherwise
- = ctsPreds (approximateWC False wanted_transformed)
-
- -- NB: quant_pred_candidates is already fully zonked
+ ; let definite_error = insolubleWC wanted_transformed_incl_derivs
+ -- See Note [Quantification with errors]
+ -- NB: must include derived errors in this test,
+ -- hence "incl_derivs"
+ wanted_transformed = dropDerivedWC wanted_transformed_incl_derivs
+ quant_pred_candidates
+ | definite_error = []
+ | otherwise = ctsPreds (approximateWC False wanted_transformed)
-- Decide what type variables and constraints to quantify
+ -- NB: quant_pred_candidates is already fully zonked
-- NB: bound_theta are constraints we want to quantify over,
-- /apart from/ the psig_theta, which we always quantify over
; (qtvs, bound_theta) <- decideQuantification infer_mode rhs_tclvl
@@ -648,41 +651,58 @@ simplifyInfer rhs_tclvl infer_mode sigs name_taus wanteds
-- remaining constraints from the RHS.
-- We must retain the psig_theta_vars, because we've used them in
-- evidence bindings constructed by solveWanteds earlier
- ; psig_theta_vars <- mapM zonkId psig_theta_vars
+ ; psig_theta_vars <- mapM zonkId psig_theta_vars
; bound_theta_vars <- mapM TcM.newEvVar bound_theta
- ; let full_theta = psig_theta ++ bound_theta
- full_theta_vars = psig_theta_vars ++ bound_theta_vars
- skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty)
- | (name, ty) <- name_taus ]
- -- Don't add the quantified variables here, because
- -- they are also bound in ic_skols and we want them
- -- to be tidied uniformly
+ ; let full_theta_vars = psig_theta_vars ++ bound_theta_vars
- implic = Implic { ic_tclvl = rhs_tclvl
- , ic_skols = qtvs
- , ic_no_eqs = False
- , ic_given = full_theta_vars
- , ic_wanted = wanted_transformed
- , ic_status = IC_Unsolved
- , ic_binds = ev_binds_var
- , ic_info = skol_info
- , ic_needed = emptyVarSet
- , ic_env = tc_lcl_env }
- ; emitImplication implic
+ ; emitResidualImplication rhs_tclvl tc_lcl_env ev_binds_var
+ name_taus qtvs full_theta_vars
+ wanted_transformed
-- All done!
; traceTc "} simplifyInfer/produced residual implication for quantification" $
vcat [ text "quant_pred_candidates =" <+> ppr quant_pred_candidates
, text "psig_theta =" <+> ppr psig_theta
, text "bound_theta =" <+> ppr bound_theta
- , text "full_theta =" <+> ppr full_theta
+ , text "full_theta =" <+> ppr (map idType full_theta_vars)
, text "qtvs =" <+> ppr qtvs
- , text "implic =" <+> ppr implic ]
+ , text "definite_error =" <+> ppr definite_error ]
- ; return ( qtvs, full_theta_vars, TcEvBinds ev_binds_var ) }
+ ; return ( qtvs, full_theta_vars, TcEvBinds ev_binds_var, definite_error ) }
-- NB: full_theta_vars must be fully zonked
+--------------------
+emitResidualImplication :: TcLevel -> TcLclEnv -> EvBindsVar
+ -> [(Name, TcTauType)] -> [TcTyVar] -> [EvVar]
+ -> WantedConstraints -> TcM ()
+emitResidualImplication rhs_tclvl tc_lcl_env ev_binds_var
+ name_taus qtvs full_theta_vars wanteds
+ | isEmptyWC wanteds
+ = return ()
+ | otherwise
+ = do { traceTc "emitResidualImplication" (ppr implic)
+ ; emitImplication implic }
+ where
+ implic = Implic { ic_tclvl = rhs_tclvl
+ , ic_skols = qtvs
+ , ic_no_eqs = False
+ , ic_given = full_theta_vars
+ , ic_wanted = wanteds
+ , ic_status = IC_Unsolved
+ , ic_binds = ev_binds_var
+ , ic_info = skol_info
+ , ic_needed = emptyVarSet
+ , ic_env = tc_lcl_env }
+
+ full_theta = map idType full_theta_vars
+ skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty)
+ | (name, ty) <- name_taus ]
+ -- Don't add the quantified variables here, because
+ -- they are also bound in ic_skols and we want them
+ -- to be tidied uniformly
+
+--------------------
ctsPreds :: Cts -> [PredType]
ctsPreds cts = [ ctEvPred ev | ct <- bagToList cts
, let ev = ctEvidence ct ]
@@ -1092,13 +1112,33 @@ Notice that
Note [Quantification with errors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we find that the RHS of the definition has some absolutely-insoluble
-constraints, we abandon all attempts to find a context to quantify
-over, and instead make the function fully-polymorphic in whatever
-type we have found. For two reasons
- a) Minimise downstream errors
- b) Avoid spurious errors from this function
-
-But NB that we must include *derived* errors in the check. Example:
+constraints (including especially "variable not in scope"), we
+
+* Abandon all attempts to find a context to quantify over,
+ and instead make the function fully-polymorphic in whatever
+ type we have found
+
+* Return a flag from simplifyInfer, indicating that we found an
+ insoluble constraint. This flag is used to suppress the ambiguity
+ check for the inferred type, which may well be bogus, and which
+ tends to obscure the real error. This fix feels a bit clunky,
+ but I failed to come up with anything better.
+
+Reasons:
+ - Avoid downstream errors
+ - Do not perform an ambiguity test on a bogus type, which might well
+ fail spuriously, thereby obfuscating the original insoluble error.
+ Trac #14000 is an example
+
+I tried an alterantive approach: simply failM, after emitting the
+residual implication constraint; the exception will be caught in
+TcBinds.tcPolyBinds, which gives all the binders in the group the type
+(forall a. a). But that didn't work with -fdefer-type-errors, because
+the recovery from failM emits no code at all, so there is no function
+to run! But -fdefer-type-errors aspires to produce a runnable program.
+
+NB that we must include *derived* errors in the check for insolubles.
+Example:
(a::*) ~ Int#
We get an insoluble derived error *~#, and we don't want to discard
it before doing the isInsolubleWC test! (Trac #8262)
@@ -1983,7 +2023,8 @@ floatEqualities skols no_given_eqs
; return ( float_eqs
, wanteds { wc_simple = remaining_simples } ) }
-usefulToFloat :: VarSet -> Ct -> Bool
+usefulToFloat :: VarSet -- ^ the skolems in the implication
+ -> Ct -> Bool
usefulToFloat skol_set ct -- The constraint is un-flattened and de-canonicalised
= is_meta_var_eq pred &&
(tyCoVarsOfType pred `disjointVarSet` skol_set)
@@ -1995,6 +2036,7 @@ usefulToFloat skol_set ct -- The constraint is un-flattened and de-canonicalis
-- See Note [Which equalities to float]
is_meta_var_eq pred
| EqPred NomEq ty1 ty2 <- classifyPredType pred
+ , is_homogeneous ty1 ty2
= case (tcGetTyVar_maybe ty1, tcGetTyVar_maybe ty2) of
(Just tv1, _) -> float_tv_eq tv1 ty2
(_, Just tv2) -> float_tv_eq tv2 ty1
@@ -2006,6 +2048,17 @@ usefulToFloat skol_set ct -- The constraint is un-flattened and de-canonicalis
= isMetaTyVar tv1
&& (not (isSigTyVar tv1) || isTyVarTy ty2)
+ is_homogeneous ty1 ty2
+ = not has_heterogeneous_form || -- checking the shape is quicker
+ -- than looking at kinds
+ typeKind ty1 `tcEqType` typeKind ty2
+
+ has_heterogeneous_form = case ct of
+ CIrredEvCan {} -> True
+ CNonCanonical {} -> True
+ _ -> False
+
+
{- Note [Float equalities from under a skolem binding]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Which of the simple equalities can we float out? Obviously, only
@@ -2035,7 +2088,7 @@ Which equalities should we float? We want to float ones where there
is a decent chance that floating outwards will allow unification to
happen. In particular:
- Float out equalities of form (alpha ~ ty) or (ty ~ alpha), where
+ Float out homogeneous equalities of form (alpha ~ ty) or (ty ~ alpha), where
* alpha is a meta-tyvar.
@@ -2043,6 +2096,15 @@ happen. In particular:
case, floating out won't help either, and it may affect grouping
of error messages.
+Why homogeneous (i.e., the kinds of the types are the same)? Because heterogeneous
+equalities have derived kind equalities. See Note [Equalities with incompatible kinds]
+in TcCanonical. If we float out a hetero equality, then it will spit out the
+same derived kind equality again, which might create duplicate error messages.
+Instead, we do float out the kind equality (if it's worth floating out, as
+above). If/when we solve it, we'll be able to rewrite the original hetero equality
+to be homogeneous, and then perhaps make progress / float it out. The duplicate
+error message was spotted in typecheck/should_fail/T7368.
+
Note [Skolem escape]
~~~~~~~~~~~~~~~~~~~~
You might worry about skolem escape with all this floating.
@@ -2101,7 +2163,8 @@ findDefaultableGroups (default_tys, (ovl_strings, extended_defaults)) wanteds
= []
| otherwise
= [ (tv, map fstOf3 group)
- | group@((_,_,tv):_) <- unary_groups
+ | group'@((_,_,tv) :| _) <- unary_groups
+ , let group = toList group'
, defaultable_tyvar tv
, defaultable_classes (map sndOf3 group) ]
where
@@ -2109,9 +2172,9 @@ findDefaultableGroups (default_tys, (ovl_strings, extended_defaults)) wanteds
(unaries, non_unaries) = partitionWith find_unary (bagToList simples)
unary_groups = equivClasses cmp_tv unaries
- unary_groups :: [[(Ct, Class, TcTyVar)]] -- (C tv) constraints
- unaries :: [(Ct, Class, TcTyVar)] -- (C tv) constraints
- non_unaries :: [Ct] -- and *other* constraints
+ unary_groups :: [NonEmpty (Ct, Class, TcTyVar)] -- (C tv) constraints
+ unaries :: [(Ct, Class, TcTyVar)] -- (C tv) constraints
+ non_unaries :: [Ct] -- and *other* constraints
-- Finds unary type-class constraints
-- But take account of polykinded classes like Typeable,
@@ -2177,10 +2240,8 @@ disambigGroup (default_ty:default_tys) group@(the_tv, wanteds)
try_group
| Just subst <- mb_subst
= do { lcl_env <- TcS.getLclEnv
- ; let loc = CtLoc { ctl_origin = GivenOrigin UnkSkol
- , ctl_env = lcl_env
- , ctl_t_or_k = Nothing
- , ctl_depth = initialSubGoalDepth }
+ ; tc_lvl <- TcS.getTcLevel
+ ; let loc = mkGivenLoc tc_lvl UnkSkol lcl_env
; wanted_evs <- mapM (newWantedEvVarNC loc . substTy subst . ctPred)
wanteds
; fmap isEmptyWC $
diff --git a/compiler/typecheck/TcSplice.hs b/compiler/typecheck/TcSplice.hs
index e6d5097e29..c0c270cc81 100644
--- a/compiler/typecheck/TcSplice.hs
+++ b/compiler/typecheck/TcSplice.hs
@@ -135,8 +135,8 @@ import GHC.Exts ( unsafeCoerce# )
************************************************************************
-}
-tcTypedBracket :: HsBracket GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId)
-tcUntypedBracket :: HsBracket GhcRn -> [PendingRnSplice] -> ExpRhoType
+tcTypedBracket :: HsExpr GhcRn -> HsBracket GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId)
+tcUntypedBracket :: HsExpr GhcRn -> HsBracket GhcRn -> [PendingRnSplice] -> ExpRhoType
-> TcM (HsExpr GhcTcId)
tcSpliceExpr :: HsSplice GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId)
-- None of these functions add constraints to the LIE
@@ -157,7 +157,7 @@ runAnnotation :: CoreAnnTarget -> LHsExpr GhcRn -> TcM Annotation
-- See Note [How brackets and nested splices are handled]
-- tcTypedBracket :: HsBracket Name -> TcRhoType -> TcM (HsExpr TcId)
-tcTypedBracket brack@(TExpBr expr) res_ty
+tcTypedBracket rn_expr brack@(TExpBr expr) res_ty
= addErrCtxt (quotationCtxtDoc brack) $
do { cur_stage <- getStage
; ps_ref <- newMutVar []
@@ -176,20 +176,21 @@ tcTypedBracket brack@(TExpBr expr) res_ty
; ps' <- readMutVar ps_ref
; texpco <- tcLookupId unsafeTExpCoerceName
; tcWrapResultO (Shouldn'tHappenOrigin "TExpBr")
+ rn_expr
(unLoc (mkHsApp (nlHsTyApp texpco [expr_ty])
(noLoc (HsTcBracketOut brack ps'))))
meta_ty res_ty }
-tcTypedBracket other_brack _
+tcTypedBracket _ other_brack _
= pprPanic "tcTypedBracket" (ppr other_brack)
-- tcUntypedBracket :: HsBracket Name -> [PendingRnSplice] -> ExpRhoType -> TcM (HsExpr TcId)
-tcUntypedBracket brack ps res_ty
+tcUntypedBracket rn_expr brack ps res_ty
= do { traceTc "tc_bracket untyped" (ppr brack $$ ppr ps)
; ps' <- mapM tcPendingSplice ps
; meta_ty <- tcBrackTy brack
; traceTc "tc_bracket done untyped" (ppr meta_ty)
; tcWrapResultO (Shouldn'tHappenOrigin "untyped bracket")
- (HsTcBracketOut brack ps') meta_ty res_ty }
+ rn_expr (HsTcBracketOut brack ps') meta_ty res_ty }
---------------
tcBrackTy :: HsBracket GhcRn -> TcM TcType
@@ -868,7 +869,6 @@ instance TH.Quasi TcM where
-- the recovery action is chosen. Otherwise
-- we'll only fail higher up.
qRecover recover main = tryTcDiscardingErrs recover main
- qRunIO io = liftIO io
qAddDependentFile fp = do
ref <- fmap tcg_dependent_files getGblEnv
@@ -1137,7 +1137,11 @@ reifyInstances th_nm th_tys
; let tv_rdrs = freeKiTyVarsAllVars free_vars
-- Rename to HsType Name
; ((tv_names, rn_ty), _fvs)
- <- bindLRdrNames tv_rdrs $ \ tv_names ->
+ <- checkNoErrs $ -- If there are out-of-scope Names here, then we
+ -- must error before proceeding to typecheck the
+ -- renamed type, as that will result in GHC
+ -- internal errors (#13837).
+ bindLRdrNames tv_rdrs $ \ tv_names ->
do { (rn_ty, fvs) <- rnLHsType doc rdr_ty
; return ((tv_names, rn_ty), fvs) }
; (_tvs, ty)
diff --git a/compiler/typecheck/TcSplice.hs-boot b/compiler/typecheck/TcSplice.hs-boot
index 2aa51c8bcd..03b2c31315 100644
--- a/compiler/typecheck/TcSplice.hs-boot
+++ b/compiler/typecheck/TcSplice.hs-boot
@@ -17,11 +17,13 @@ tcSpliceExpr :: HsSplice GhcRn
-> ExpRhoType
-> TcM (HsExpr GhcTcId)
-tcUntypedBracket :: HsBracket GhcRn
+tcUntypedBracket :: HsExpr GhcRn
+ -> HsBracket GhcRn
-> [PendingRnSplice]
-> ExpRhoType
-> TcM (HsExpr GhcTcId)
-tcTypedBracket :: HsBracket GhcRn
+tcTypedBracket :: HsExpr GhcRn
+ -> HsBracket GhcRn
-> ExpRhoType
-> TcM (HsExpr GhcTcId)
diff --git a/compiler/typecheck/TcTyClsDecls.hs b/compiler/typecheck/TcTyClsDecls.hs
index aafea76335..4488da7305 100644
--- a/compiler/typecheck/TcTyClsDecls.hs
+++ b/compiler/typecheck/TcTyClsDecls.hs
@@ -33,7 +33,8 @@ import TcTyDecls
import TcClassDcl
import {-# SOURCE #-} TcInstDcls( tcInstDecls1 )
import TcDeriv (DerivInfo)
-import TcUnify
+import TcEvidence ( tcCoercionKind, isEmptyTcEvBinds )
+import TcUnify ( checkConstraints )
import TcHsType
import TcMType
import TysWiredIn ( unitTy )
@@ -61,6 +62,7 @@ import Outputable
import Maybes
import Unify
import Util
+import Pair
import SrcLoc
import ListSetOps
import DynFlags
@@ -70,6 +72,7 @@ import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
import Data.List
+import Data.List.NonEmpty ( NonEmpty(..) )
{-
************************************************************************
@@ -203,7 +206,7 @@ tcTyClDecls tyclds role_annots
-- Populate environment with knot-tied ATyCon for TyCons
-- NB: if the decls mention any ill-staged data cons
- -- (see Note [Recusion and promoting data constructors])
+ -- (see Note [Recursion and promoting data constructors])
-- we will have failed already in kcTyClGroup, so no worries here
; tcExtendRecEnv (zipRecTyClss tc_tycons rec_tyclss) $
@@ -424,7 +427,7 @@ mkPromotionErrorEnv :: [LTyClDecl GhcRn] -> TcTypeEnv
-- Maps each tycon/datacon to a suitable promotion error
-- tc :-> APromotionErr TyConPE
-- dc :-> APromotionErr RecDataConPE
--- See Note [ARecDataCon: Recursion and promoting data constructors]
+-- See Note [Recursion and promoting data constructors]
mkPromotionErrorEnv decls
= foldr (plusNameEnv . mk_prom_err_env . unLoc)
@@ -454,7 +457,7 @@ getInitialKinds :: [LTyClDecl GhcRn] -> TcM (NameEnv TcTyThing)
-- and each datacon to a suitable promotion error
-- tc :-> ATcTyCon (tc:initial_kind)
-- dc :-> APromotionErr RecDataConPE
--- See Note [ARecDataCon: Recursion and promoting data constructors]
+-- See Note [Recursion and promoting data constructors]
getInitialKinds decls
= tcExtendKindEnv promotion_err_env $
@@ -826,7 +829,7 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info, fdLName = tc_lname@(L _ tc_na
= tcTyClTyVars tc_name $ \ binders res_kind -> do
{ traceTc "data family:" (ppr tc_name)
; checkFamFlag tc_name
- ; (extra_binders, real_res_kind) <- tcDataKindSig res_kind
+ ; (extra_binders, real_res_kind) <- tcDataKindSig False res_kind
; tc_rep_name <- newTyConRepName tc_name
; let tycon = mkFamilyTyCon tc_name (binders `chkAppend` extra_binders)
real_res_kind
@@ -870,7 +873,11 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info, fdLName = tc_lname@(L _ tc_na
Just eqns -> do {
-- Process the equations, creating CoAxBranches
- ; let fam_tc_shape = (tc_name, length $ hsQTvExplicit tvs, binders, res_kind)
+ ; let fam_tc_shape = FamTyConShape { fs_name = tc_name
+ , fs_arity = length $ hsQTvExplicit tvs
+ , fs_flavor = TypeFam
+ , fs_binders = binders
+ , fs_res_kind = res_kind }
; branches <- mapM (tcTyFamInstEqn fam_tc_shape Nothing) eqns
-- Do not attempt to drop equations dominated by earlier
@@ -970,7 +977,7 @@ tcDataDefn roles_info
(HsDataDefn { dd_ND = new_or_data, dd_cType = cType
, dd_ctxt = ctxt, dd_kindSig = mb_ksig
, dd_cons = cons })
- = do { (extra_bndrs, real_res_kind) <- tcDataKindSig res_kind
+ = do { (extra_bndrs, real_res_kind) <- tcDataKindSig True res_kind
; let final_bndrs = tycon_binders `chkAppend` extra_bndrs
roles = roles_info tc_name
@@ -1082,15 +1089,16 @@ tcDefaultAssocDecl _ (d1:_:_)
= failWithTc (text "More than one default declaration for"
<+> ppr (tfe_tycon (unLoc d1)))
-tcDefaultAssocDecl fam_tc [L loc (TyFamEqn { tfe_tycon = L _ tc_name
- , tfe_pats = hs_tvs
+tcDefaultAssocDecl fam_tc [L loc (TyFamEqn { tfe_tycon = lname@(L _ tc_name)
+ , tfe_pats = hs_tvs, tfe_fixity = fixity
, tfe_rhs = rhs })]
| HsQTvs { hsq_implicit = imp_vars, hsq_explicit = exp_vars } <- hs_tvs
= -- See Note [Type-checking default assoc decls]
setSrcSpan loc $
tcAddFamInstCtxt (text "default type instance") tc_name $
do { traceTc "tcDefaultAssocDecl" (ppr tc_name)
- ; let shape@(fam_tc_name, fam_arity, _, _) = famTyConShape fam_tc
+ ; let shape@(FamTyConShape { fs_name = fam_tc_name
+ , fs_arity = fam_arity }) = famTyConShape fam_tc
-- Kind of family check
; ASSERT( fam_tc_name == tc_name )
@@ -1104,12 +1112,20 @@ tcDefaultAssocDecl fam_tc [L loc (TyFamEqn { tfe_tycon = L _ tc_name
; let pats = HsIB { hsib_vars = imp_vars ++ map hsLTyVarName exp_vars
, hsib_body = map hsLTyVarBndrToType exp_vars
, hsib_closed = False } -- this field is ignored, anyway
+ pp_lhs = pprFamInstLHS lname pats fixity [] Nothing
+
-- NB: Use tcFamTyPats, not tcTyClTyVars. The latter expects to get
-- the LHsQTyVars used for declaring a tycon, but the names here
-- are different.
+
+ -- You might think we should pass in some ClsInstInfo, as we're looking
+ -- at an associated type. But this would be wrong, because an associated
+ -- type default LHS can mention *different* type variables than the
+ -- enclosing class. So it's treated more as a freestanding beast.
; (pats', rhs_ty)
<- tcFamTyPats shape Nothing pats
- (discardResult . tcCheckLHsType rhs) $ \tvs pats rhs_kind ->
+ (kcTyFamEqnRhs Nothing pp_lhs rhs) $
+ \tvs pats rhs_kind ->
do { rhs_ty <- solveEqualities $
tcCheckLHsType rhs rhs_kind
@@ -1150,29 +1166,54 @@ proper tcMatchTys here.) -}
-------------------------
kcTyFamInstEqn :: FamTyConShape -> LTyFamInstEqn GhcRn -> TcM ()
-kcTyFamInstEqn fam_tc_shape@(fam_tc_name,_,_,_)
- (L loc (TyFamEqn { tfe_tycon = L _ eqn_tc_name
- , tfe_pats = pats
- , tfe_rhs = hs_ty }))
+kcTyFamInstEqn fam_tc_shape@(FamTyConShape { fs_name = fam_tc_name })
+ (L loc (TyFamEqn { tfe_tycon = lname@(L _ eqn_tc_name)
+ , tfe_pats = pats
+ , tfe_fixity = fixity
+ , tfe_rhs = hs_ty }))
= setSrcSpan loc $
do { checkTc (fam_tc_name == eqn_tc_name)
(wrongTyFamName fam_tc_name eqn_tc_name)
; discardResult $
tc_fam_ty_pats fam_tc_shape Nothing -- not an associated type
- pats (discardResult . (tcCheckLHsType hs_ty)) }
+ pats (kcTyFamEqnRhs Nothing pp_lhs hs_ty) }
+ where
+ pp_lhs = pprFamInstLHS lname pats fixity [] Nothing
+
+-- Infer the kind of the type on the RHS of a type family eqn. Then use
+-- this kind to check the kind of the LHS of the equation. This is useful
+-- as the callback to tc_fam_ty_pats and the kind-checker to
+-- tcFamTyPats.
+kcTyFamEqnRhs :: Maybe ClsInstInfo
+ -> SDoc -- ^ Eqn LHS (for errors only)
+ -> LHsType GhcRn -- ^ Eqn RHS
+ -> TcKind -- ^ Inferred kind of left-hand side
+ -> TcM ([TcType], TcKind) -- ^ New pats, inst'ed kind of left-hand side
+kcTyFamEqnRhs mb_clsinfo pp_lhs_ty rhs_hs_ty lhs_ki
+ = do { -- It's still possible the lhs_ki has some foralls. Instantiate these away.
+ (_lhs_ty', new_pats, insted_lhs_ki)
+ <- instantiateTyUntilN mb_kind_env 0 bogus_ty lhs_ki
+ ; _ <- tcCheckLHsType rhs_hs_ty insted_lhs_ki
+
+ ; return (new_pats, insted_lhs_ki) }
+ where
+ mb_kind_env = thdOf3 <$> mb_clsinfo
+
+ bogus_ty = pprPanic "kcTyFamEqnRhs" (pp_lhs_ty $$ ppr rhs_hs_ty)
tcTyFamInstEqn :: FamTyConShape -> Maybe ClsInstInfo -> LTyFamInstEqn GhcRn
-> TcM CoAxBranch
-- Needs to be here, not in TcInstDcls, because closed families
-- (typechecked here) have TyFamInstEqns
-tcTyFamInstEqn fam_tc_shape@(fam_tc_name,_,_,_) mb_clsinfo
- (L loc (TyFamEqn { tfe_tycon = L _ eqn_tc_name
- , tfe_pats = pats
- , tfe_rhs = hs_ty }))
+tcTyFamInstEqn fam_tc_shape@(FamTyConShape { fs_name = fam_tc_name }) mb_clsinfo
+ (L loc (TyFamEqn { tfe_tycon = lname@(L _ eqn_tc_name)
+ , tfe_pats = pats
+ , tfe_fixity = fixity
+ , tfe_rhs = hs_ty }))
= ASSERT( fam_tc_name == eqn_tc_name )
setSrcSpan loc $
tcFamTyPats fam_tc_shape mb_clsinfo pats
- (discardResult . (tcCheckLHsType hs_ty)) $
+ (kcTyFamEqnRhs mb_clsinfo pp_lhs hs_ty) $
\tvs pats res_kind ->
do { rhs_ty <- solveEqualities $ tcCheckLHsType hs_ty res_kind
@@ -1184,26 +1225,68 @@ tcTyFamInstEqn fam_tc_shape@(fam_tc_name,_,_,_) mb_clsinfo
; return (mkCoAxBranch tvs' [] pats' rhs_ty'
(map (const Nominal) tvs')
loc) }
-
-kcDataDefn :: Name -- ^ the family name, for error msgs only
- -> HsTyPats GhcRn -- ^ the patterns, for error msgs only
- -> HsDataDefn GhcRn -- ^ the RHS
- -> TcKind -- ^ the expected kind
- -> TcM ()
+ where
+ pp_lhs = pprFamInstLHS lname pats fixity [] Nothing
+
+kcDataDefn :: Maybe (VarEnv Kind) -- ^ Possibly, instantiations for vars
+ -- (associated types only)
+ -> DataFamInstDecl GhcRn
+ -> TcKind -- ^ the kind of the tycon applied to pats
+ -> TcM ([TcType], TcKind)
+ -- ^ the kind signature might force instantiation
+ -- of the tycon; this returns any extra args and the inst'ed kind
+ -- See Note [Instantiating a family tycon]
-- Used for 'data instance' only
-- Ordinary 'data' is handled by kcTyClDec
-kcDataDefn fam_name (HsIB { hsib_body = pats })
- (HsDataDefn { dd_ctxt = ctxt, dd_cons = cons, dd_kindSig = mb_kind }) res_k
+kcDataDefn mb_kind_env
+ (DataFamInstDecl
+ { dfid_tycon = fam_name
+ , dfid_pats = pats
+ , dfid_fixity = fixity
+ , dfid_defn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons, dd_kindSig = mb_kind } })
+ res_k
= do { _ <- tcHsContext ctxt
; checkNoErrs $ mapM_ (wrapLocM kcConDecl) cons
-- See Note [Failing early in kcDataDefn]
- ; discardResult $
- case mb_kind of
- Nothing -> unifyKind (Just hs_ty_pats) res_k liftedTypeKind
- Just k -> do { k' <- tcLHsKindSig k
- ; unifyKind (Just hs_ty_pats) res_k k' } }
+ ; exp_res_kind <- case mb_kind of
+ Nothing -> return liftedTypeKind
+ Just k -> tcLHsKindSig k
+
+ -- The expected type might have a forall at the type. Normally, we
+ -- can't skolemise in kinds because we don't have type-level lambda.
+ -- But here, we're at the top-level of an instance declaration, so
+ -- we actually have a place to put the regeneralised variables.
+ -- Thus: skolemise away. cf. Inst.deeplySkolemise and TcUnify.tcSkolemise
+ -- Examples in indexed-types/should_compile/T12369
+ ; let (tvs_to_skolemise, inner_res_kind) = tcSplitForAllTys exp_res_kind
+
+ ; (skol_subst, tvs') <- tcInstSkolTyVars tvs_to_skolemise
+ -- we don't need to do anything substantive with the tvs' because the
+ -- quantifyTyVars in tcFamTyPats will catch them.
+
+ ; let inner_res_kind' = substTyAddInScope skol_subst inner_res_kind
+ tv_prs = zip (map tyVarName tvs_to_skolemise) tvs'
+ skol_info = SigSkol InstDeclCtxt exp_res_kind tv_prs
+
+ ; (ev_binds, (_, new_args, co))
+ <- solveEqualities $
+ checkConstraints skol_info tvs' [] $
+ checkExpectedKindX mb_kind_env pp_fam_app
+ bogus_ty res_k inner_res_kind'
+
+ ; let Pair lhs_ki rhs_ki = tcCoercionKind co
+
+ ; when debugIsOn $
+ do { (_, ev_binds) <- zonkTcEvBinds emptyZonkEnv ev_binds
+ ; MASSERT( isEmptyTcEvBinds ev_binds )
+ ; lhs_ki <- zonkTcType lhs_ki
+ ; rhs_ki <- zonkTcType rhs_ki
+ ; MASSERT( lhs_ki `tcEqType` rhs_ki ) }
+
+ ; return (new_args, lhs_ki) }
where
- hs_ty_pats = mkHsAppTys (noLoc $ HsTyVar NotPromoted (noLoc fam_name)) pats
+ bogus_ty = pprPanic "kcDataDefn" (ppr fam_name <+> ppr pats)
+ pp_fam_app = pprFamInstLHS fam_name pats fixity (unLoc ctxt) mb_kind
{-
Kind check type patterns and kind annotate the embedded type variables.
@@ -1231,6 +1314,28 @@ The type FamTyConShape gives just enough information to do the job.
See also Note [tc_fam_ty_pats vs tcFamTyPats]
+Note [Instantiating a family tycon]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It's possible that kind-checking the result of a family tycon applied to
+its patterns will instantiate the tycon further. For example, we might
+have
+
+ type family F :: k where
+ F = Int
+ F = Maybe
+
+After checking (F :: forall k. k) (with no visible patterns), we still need
+to instantiate the k. With data family instances, this problem can be even
+more intricate, due to Note [Arity of data families] in FamInstEnv. See
+indexed-types/should_compile/T12369 for an example.
+
+So, the kind-checker must return both the new args (that is, Type
+(Type -> Type) for the equations above) and the instantiated kind.
+
+Because we don't need this information in the kind-checking phase of
+checking closed type families, we don't require these extra pieces of
+information in tc_fam_ty_pats. See also Note [tc_fam_ty_pats vs tcFamTyPats].
+
Note [Failing early in kcDataDefn]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We need to use checkNoErrs when calling kcConDecl. This is because kcConDecl
@@ -1245,22 +1350,31 @@ two bad things could happen:
-}
-----------------
-type FamTyConShape = (Name, Arity, [TyConBinder], Kind)
+data TypeOrDataFamily = TypeFam | DataFam
+data FamTyConShape = FamTyConShape { fs_name :: Name
+ , fs_arity :: Arity -- the visible args
+ , fs_flavor :: TypeOrDataFamily
+ , fs_binders :: [TyConBinder]
+ , fs_res_kind :: Kind }
-- See Note [Type-checking type patterns]
famTyConShape :: TyCon -> FamTyConShape
famTyConShape fam_tc
- = ( tyConName fam_tc
- , length $ filterOutInvisibleTyVars fam_tc (tyConTyVars fam_tc)
- , tyConBinders fam_tc
- , tyConResKind fam_tc )
+ = FamTyConShape { fs_name = tyConName fam_tc
+ , fs_arity = length $ filterOutInvisibleTyVars fam_tc (tyConTyVars fam_tc)
+ , fs_flavor = flav
+ , fs_binders = tyConBinders fam_tc
+ , fs_res_kind = tyConResKind fam_tc }
+ where
+ flav
+ | isTypeFamilyTyCon fam_tc = TypeFam
+ | otherwise = DataFam
tc_fam_ty_pats :: FamTyConShape
-> Maybe ClsInstInfo
-> HsTyPats GhcRn -- Patterns
- -> (TcKind -> TcM ()) -- Kind checker for RHS
- -- result is ignored
- -> TcM ([Type], Kind)
+ -> (TcKind -> TcM r) -- Kind checker for RHS
+ -> TcM ([Type], r) -- Returns the type-checked patterns
-- Check the type patterns of a type or data family instance
-- type instance F <pat1> <pat2> = <type>
-- The 'tyvars' are the free type variables of pats
@@ -1272,43 +1386,59 @@ tc_fam_ty_pats :: FamTyConShape
-- In that case, the type variable 'a' will *already be in scope*
-- (and, if C is poly-kinded, so will its kind parameter).
-tc_fam_ty_pats (name, _, binders, res_kind) mb_clsinfo
- (HsIB { hsib_body = arg_pats, hsib_vars = tv_names })
+tc_fam_ty_pats (FamTyConShape { fs_name = name, fs_arity = arity
+ , fs_flavor = flav, fs_binders = binders
+ , fs_res_kind = res_kind })
+ mb_clsinfo (HsIB { hsib_body = arg_pats, hsib_vars = tv_names })
kind_checker
- = do { -- Kind-check and quantify
+ = do { -- First, check the arity.
+ -- If we wait until validity checking, we'll get kind
+ -- errors below when an arity error will be much easier to
+ -- understand.
+ let should_check_arity
+ | TypeFam <- flav = True
+ -- why not check data families? See [Arity of data families] in FamInstEnv
+ | otherwise = False
+
+ ; when should_check_arity $
+ checkTc (arg_pats `lengthIs` arity) $
+ wrongNumberOfParmsErr arity
+ -- report only explicit arguments
+
+ -- Kind-check and quantify
-- See Note [Quantifying over family patterns]
- (_, (insted_res_kind, typats)) <- tcImplicitTKBndrs tv_names $
- do { (insting_subst, _leftover_binders, args, leftovers, n)
- <- tcInferArgs name binders (thdOf3 <$> mb_clsinfo) arg_pats
- ; case leftovers of
- hs_ty:_ -> addErrTc $ too_many_args hs_ty n
- _ -> return ()
- -- don't worry about leftover_binders; TcValidity catches them
-
- ; let insted_res_kind = substTyUnchecked insting_subst res_kind
- ; kind_checker insted_res_kind
- ; return ((insted_res_kind, args), emptyVarSet) }
-
- ; return (typats, insted_res_kind) }
- where
- too_many_args hs_ty n
- = hang (text "Too many parameters to" <+> ppr name <> colon)
- 2 (vcat [ ppr hs_ty <+> text "is unexpected;"
- , text (if n == 1 then "expected" else "expected only") <+>
- speakNOf (n-1) (text "parameter") ])
+ ; (_, result) <- tcImplicitTKBndrs tv_names $
+ do { let loc = nameSrcSpan name
+ lhs_fun = L loc (HsTyVar NotPromoted (L loc name))
+ bogus_fun_ty = pprPanic "tc_fam_ty_pats" (ppr name $$ ppr arg_pats)
+ fun_kind = mkTyConKind binders res_kind
+ mb_kind_env = thdOf3 <$> mb_clsinfo
+
+ ; (_, args, res_kind_out)
+ <- tcInferApps typeLevelMode mb_kind_env
+ lhs_fun bogus_fun_ty fun_kind arg_pats
+
+ ; stuff <- kind_checker res_kind_out
+
+ ; return ((args, stuff), emptyVarSet) }
+
+ ; return result }
-- See Note [tc_fam_ty_pats vs tcFamTyPats]
tcFamTyPats :: FamTyConShape
-> Maybe ClsInstInfo
-> HsTyPats GhcRn -- patterns
- -> (TcKind -> TcM ()) -- kind-checker for RHS
+ -> (TcKind -> TcM ([TcType], TcKind))
+ -- kind-checker for RHS
+ -- See Note [Instantiating a family tycon]
-> ( [TcTyVar] -- Kind and type variables
-> [TcType] -- Kind and type arguments
-> TcKind
-> TcM a) -- NB: You can use solveEqualities here.
-> TcM a
-tcFamTyPats fam_shape@(name,_,_,_) mb_clsinfo pats kind_checker thing_inside
- = do { (typats, res_kind)
+tcFamTyPats fam_shape@(FamTyConShape { fs_name = name }) mb_clsinfo pats
+ kind_checker thing_inside
+ = do { (typats, (more_typats, res_kind))
<- solveEqualities $ -- See Note [Constraints in patterns]
tc_fam_ty_pats fam_shape mb_clsinfo pats kind_checker
@@ -1333,7 +1463,8 @@ tcFamTyPats fam_shape@(name,_,_,_) mb_clsinfo pats kind_checker thing_inside
-- them into skolems, so that we don't subsequently
-- replace a meta kind var with (Any *)
-- Very like kindGeneralize
- ; vars <- zonkTcTypesAndSplitDepVars typats
+ ; let all_pats = typats `chkAppend` more_typats
+ ; vars <- zonkTcTypesAndSplitDepVars all_pats
; qtkvs <- quantifyTyVars emptyVarSet vars
; MASSERT( isEmptyVarSet $ coVarsOfTypes typats )
@@ -1341,14 +1472,14 @@ tcFamTyPats fam_shape@(name,_,_,_) mb_clsinfo pats kind_checker thing_inside
-- above would fail. TODO (RAE): Update once the solveEqualities
-- bit is cleverer.
- ; traceTc "tcFamTyPats" (ppr name $$ ppr typats $$ ppr qtkvs)
+ ; traceTc "tcFamTyPats" (ppr name $$ ppr all_pats $$ ppr qtkvs)
-- Don't print out too much, as we might be in the knot
; tcExtendTyVarEnv qtkvs $
-- Extend envt with TcTyVars not TyVars, because the
-- kind checking etc done by thing_inside does not expect
-- to encounter TyVars; it expects TcTyVars
- thing_inside qtkvs typats res_kind }
+ thing_inside qtkvs all_pats res_kind }
{-
Note [Constraints in patterns]
@@ -1564,7 +1695,7 @@ tcConDecl rep_tycon tmpl_bndrs res_tmpl
; buildDataCon fam_envs name is_infix rep_nm
stricts Nothing field_lbls
- (mkDataConUnivTyVarBinders tmpl_bndrs)
+ (tyConTyVarBinders tmpl_bndrs)
ex_tvs
[{- no eq_preds -}] ctxt arg_tys
res_tmpl rep_tycon
@@ -2238,7 +2369,7 @@ checkValidTyCon tc
-- result type against other candidates' types BOTH WAYS ROUND.
-- If they magically agrees, take the substitution and
-- apply them to the latter ones, and see if they match perfectly.
- check_fields ((label, con1) : other_fields)
+ check_fields ((label, con1) :| other_fields)
-- These fields all have the same name, but are from
-- different constructors in the data type
= recoverM (return ()) $ mapM_ checkOne other_fields
@@ -2256,7 +2387,6 @@ checkValidTyCon tc
where
(_, _, _, res2) = dataConSig con2
fty2 = dataConFieldType con2 lbl
- check_fields [] = panic "checkValidTyCon/check_fields []"
checkFieldCompat :: FieldLabelString -> DataCon -> DataCon
-> Type -> Type -> Type -> Type -> TcM ()
@@ -2528,9 +2658,10 @@ checkValidClass cls
-- Check that any default declarations for associated types are valid
; whenIsJust m_dflt_rhs $ \ (rhs, loc) ->
checkValidTyFamEqn mb_cls fam_tc
- fam_tvs [] (mkTyVarTys fam_tvs) rhs loc }
+ fam_tvs [] (mkTyVarTys fam_tvs) rhs pp_lhs loc }
where
fam_tvs = tyConTyVars fam_tc
+ pp_lhs = ppr (mkTyConApp fam_tc (mkTyVarTys fam_tvs))
check_dm :: UserTypeCtxt -> Id -> PredType -> Type -> DefMethInfo -> TcM ()
-- Check validity of the /top-level/ generic-default type
@@ -2863,6 +2994,10 @@ checkValidRoles tc
ex_roles = mkVarEnv (map (, Nominal) ex_tvs)
role_env = univ_roles `plusVarEnv` ex_roles
+ check_ty_roles env role ty
+ | Just ty' <- coreView ty -- #14101
+ = check_ty_roles env role ty'
+
check_ty_roles env role (TyVarTy tv)
= case lookupVarEnv env tv of
Just role' -> unless (role' `ltRole` role || role' == role) $
diff --git a/compiler/typecheck/TcTyDecls.hs b/compiler/typecheck/TcTyDecls.hs
index 68e15fbd48..e55b8e8503 100644
--- a/compiler/typecheck/TcTyDecls.hs
+++ b/compiler/typecheck/TcTyDecls.hs
@@ -580,6 +580,8 @@ irDataCon datacon
irType :: VarSet -> Type -> RoleM ()
irType = go
where
+ go lcls ty | Just ty' <- coreView ty -- #14101
+ = go lcls ty'
go lcls (TyVarTy tv) = unless (tv `elemVarSet` lcls) $
updateRole Representational tv
go lcls (AppTy t1 t2) = go lcls t1 >> markNominal lcls t2
@@ -771,10 +773,18 @@ mkDefaultMethodIds tycons
mkDefaultMethodType :: Class -> Id -> DefMethSpec Type -> Type
-- Returns the top-level type of the default method
mkDefaultMethodType _ sel_id VanillaDM = idType sel_id
-mkDefaultMethodType cls _ (GenericDM dm_ty) = mkSpecSigmaTy cls_tvs [pred] dm_ty
+mkDefaultMethodType cls _ (GenericDM dm_ty) = mkSigmaTy tv_bndrs [pred] dm_ty
where
- cls_tvs = classTyVars cls
- pred = mkClassPred cls (mkTyVarTys cls_tvs)
+ pred = mkClassPred cls (mkTyVarTys (binderVars cls_bndrs))
+ cls_bndrs = tyConBinders (classTyCon cls)
+ tv_bndrs = tyConTyVarBinders cls_bndrs
+ -- NB: the Class doesn't have TyConBinders; we reach into its
+ -- TyCon to get those. We /do/ need the TyConBinders because
+ -- we need the correct visiblity: these default methods are
+ -- used in code generated by the the fill-in for missing
+ -- methods in instances (TcInstDcls.mkDefMethBind), and
+ -- then typechecked. So we need the right visibilty info
+ -- (Trac #13998)
{-
************************************************************************
diff --git a/compiler/typecheck/TcType.hs b/compiler/typecheck/TcType.hs
index e12b70b6d1..3b97555158 100644
--- a/compiler/typecheck/TcType.hs
+++ b/compiler/typecheck/TcType.hs
@@ -58,7 +58,7 @@ module TcType (
-- These are important because they do not look through newtypes
getTyVar,
tcSplitForAllTy_maybe,
- tcSplitForAllTys, tcSplitPiTys, tcSplitForAllTyVarBndrs,
+ tcSplitForAllTys, tcSplitPiTys, tcSplitPiTy_maybe, tcSplitForAllTyVarBndrs,
tcSplitPhiTy, tcSplitPredFunTy_maybe,
tcSplitFunTy_maybe, tcSplitFunTys, tcFunArgTy, tcFunResultTy, tcFunResultTyN,
tcSplitFunTysN,
@@ -66,7 +66,8 @@ module TcType (
tcRepSplitTyConApp_maybe, tcRepSplitTyConApp_maybe',
tcTyConAppTyCon, tcTyConAppTyCon_maybe, tcTyConAppArgs,
tcSplitAppTy_maybe, tcSplitAppTy, tcSplitAppTys, tcRepSplitAppTy_maybe,
- tcGetTyVar_maybe, tcGetTyVar, nextRole,
+ tcRepGetNumAppTys,
+ tcGetCastedTyVar_maybe, tcGetTyVar_maybe, tcGetTyVar, nextRole,
tcSplitSigmaTy, tcSplitNestedSigmaTys, tcDeepSplitSigmaTy_maybe,
---------------------------------
@@ -186,7 +187,11 @@ module TcType (
pprTheta, pprParendTheta, pprThetaArrowTy, pprClassPred,
pprTvBndr, pprTvBndrs,
- TypeSize, sizeType, sizeTypes, toposortTyVars
+ TypeSize, sizeType, sizeTypes, toposortTyVars,
+
+ ---------------------------------
+ -- argument visibility
+ tcTyConVisibilities, isNextTyConArgVisible, isNextArgVisible
) where
@@ -219,6 +224,7 @@ import BasicTypes
import Util
import Bag
import Maybes
+import ListSetOps ( getNth )
import Outputable
import FastString
import ErrUtils( Validity(..), MsgDoc, isValid )
@@ -1357,6 +1363,10 @@ variables. It's up to you to make sure this doesn't matter.
tcSplitPiTys :: Type -> ([TyBinder], Type)
tcSplitPiTys = splitPiTys
+-- | Splits a type into a TyBinder and a body, if possible. Panics otherwise
+tcSplitPiTy_maybe :: Type -> Maybe (TyBinder, Type)
+tcSplitPiTy_maybe = splitPiTy_maybe
+
tcSplitForAllTy_maybe :: Type -> Maybe (TyVarBinder, Type)
tcSplitForAllTy_maybe ty | Just ty' <- tcView ty = tcSplitForAllTy_maybe ty'
tcSplitForAllTy_maybe (ForAllTy tv ty) = Just (tv, ty)
@@ -1569,7 +1579,21 @@ tcSplitAppTys ty
Just (ty', arg) -> go ty' (arg:args)
Nothing -> (ty,args)
+-- | Returns the number of arguments in the given type, without
+-- looking through synonyms. This is used only for error reporting.
+-- We don't look through synonyms because of #11313.
+tcRepGetNumAppTys :: Type -> Arity
+tcRepGetNumAppTys = length . snd . repSplitAppTys
+
-----------------------
+-- | If the type is a tyvar, possibly under a cast, returns it, along
+-- with the coercion. Thus, the co is :: kind tv ~N kind type
+tcGetCastedTyVar_maybe :: Type -> Maybe (TyVar, CoercionN)
+tcGetCastedTyVar_maybe ty | Just ty' <- tcView ty = tcGetCastedTyVar_maybe ty'
+tcGetCastedTyVar_maybe (CastTy (TyVarTy tv) co) = Just (tv, co)
+tcGetCastedTyVar_maybe (TyVarTy tv) = Just (tv, mkNomReflCo (tyVarKind tv))
+tcGetCastedTyVar_maybe _ = Nothing
+
tcGetTyVar_maybe :: Type -> Maybe TyVar
tcGetTyVar_maybe ty | Just ty' <- tcView ty = tcGetTyVar_maybe ty'
tcGetTyVar_maybe (TyVarTy tv) = Just tv
@@ -1728,7 +1752,7 @@ tc_eq_type view_fun orig_ty1 orig_ty2 = go True orig_env orig_ty1 orig_ty2
-- be oversaturated
where
bndrs = tyConBinders tc
- viss = map (isVisibleArgFlag . tyConBinderArgFlag) bndrs
+ viss = map isVisibleTyConBinder bndrs
tc_vis False _ = repeat False -- if we're not in a visible context, our args
-- aren't either
@@ -2559,8 +2583,11 @@ sizeType = go
go (TyVarTy {}) = 1
go (TyConApp tc tys)
| isTypeFamilyTyCon tc = infinity -- Type-family applications can
- -- expand to any arbitrary size
+ -- expand to any arbitrary size
| otherwise = sizeTypes (filterOutInvisibleTypes tc tys) + 1
+ -- Why filter out invisible args? I suppose any
+ -- size ordering is sound, but why is this better?
+ -- I came across this when investigating #14010.
go (LitTy {}) = 1
go (FunTy arg res) = go arg + go res + 1
go (AppTy fun arg) = go fun + go arg
@@ -2572,3 +2599,28 @@ sizeType = go
sizeTypes :: [Type] -> TypeSize
sizeTypes tys = sum (map sizeType tys)
+
+-----------------------------------------------------------------------------------
+-----------------------------------------------------------------------------------
+-----------------------
+-- | For every arg a tycon can take, the returned list says True if the argument
+-- is taken visibly, and False otherwise. Ends with an infinite tail of Trues to
+-- allow for oversaturation.
+tcTyConVisibilities :: TyCon -> [Bool]
+tcTyConVisibilities tc = tc_binder_viss ++ tc_return_kind_viss ++ repeat True
+ where
+ tc_binder_viss = map isVisibleTyConBinder (tyConBinders tc)
+ tc_return_kind_viss = map isVisibleBinder (fst $ tcSplitPiTys (tyConResKind tc))
+
+-- | If the tycon is applied to the types, is the next argument visible?
+isNextTyConArgVisible :: TyCon -> [Type] -> Bool
+isNextTyConArgVisible tc tys
+ = tcTyConVisibilities tc `getNth` length tys
+
+-- | Should this type be applied to a visible argument?
+isNextArgVisible :: TcType -> Bool
+isNextArgVisible ty
+ | Just (bndr, _) <- tcSplitPiTy_maybe ty = isVisibleBinder bndr
+ | otherwise = True
+ -- this second case might happen if, say, we have an unzonked TauTv.
+ -- But TauTvs can't range over types that take invisible arguments
diff --git a/compiler/typecheck/TcUnify.hs b/compiler/typecheck/TcUnify.hs
index 1cbf5741b2..b792f955c4 100644
--- a/compiler/typecheck/TcUnify.hs
+++ b/compiler/typecheck/TcUnify.hs
@@ -16,7 +16,7 @@ module TcUnify (
checkConstraints, buildImplicationFor,
-- Various unifications
- unifyType, unifyTheta, unifyKind, noThing,
+ unifyType, unifyTheta, unifyKind,
uType, promoteTcType,
swapOverTyVars, canSolveByUnification,
@@ -201,10 +201,9 @@ matchExpectedFunTys herald arity orig_ty thing_inside
-- Like 'matchExpectedFunTys', but used when you have an "actual" type,
-- for example in function application
-matchActualFunTys :: Outputable a
- => SDoc -- See Note [Herald for matchExpectedFunTys]
+matchActualFunTys :: SDoc -- See Note [Herald for matchExpectedFunTys]
-> CtOrigin
- -> Maybe a -- the thing with type TcSigmaType
+ -> Maybe (HsExpr GhcRn) -- the thing with type TcSigmaType
-> Arity
-> TcSigmaType
-> TcM (HsWrapper, [TcSigmaType], TcSigmaType)
@@ -215,10 +214,9 @@ matchActualFunTys herald ct_orig mb_thing arity ty
-- | Variant of 'matchActualFunTys' that works when supplied only part
-- (that is, to the right of some arrows) of the full function type
-matchActualFunTysPart :: Outputable a
- => SDoc -- See Note [Herald for matchExpectedFunTys]
+matchActualFunTysPart :: SDoc -- See Note [Herald for matchExpectedFunTys]
-> CtOrigin
- -> Maybe a -- the thing with type TcSigmaType
+ -> Maybe (HsExpr GhcRn) -- the thing with type TcSigmaType
-> Arity
-> TcSigmaType
-> [TcSigmaType] -- reversed args. See (*) below.
@@ -391,7 +389,7 @@ matchExpectedTyConApp tc orig_ty
-- kind-compatible with T. For example, suppose we have
-- matchExpectedTyConApp T (f Maybe)
-- where data T a = MkT a
- -- Then we don't want to instantate T's data constructors with
+ -- Then we don't want to instantiate T's data constructors with
-- (a::*) ~ Maybe
-- because that'll make types that are utterly ill-kinded.
-- This happened in Trac #7368
@@ -400,7 +398,7 @@ matchExpectedTyConApp tc orig_ty
; traceTc "matchExpectedTyConApp" (ppr tc $$ ppr (tyConTyVars tc) $$ ppr arg_tvs)
; let args = mkTyVarTys arg_tvs
tc_template = mkTyConApp tc args
- ; co <- unifyType noThing tc_template orig_ty
+ ; co <- unifyType Nothing tc_template orig_ty
; return (co, args) }
----------------------
@@ -432,7 +430,7 @@ matchExpectedAppTy orig_ty
defer
= do { ty1 <- newFlexiTyVarTy kind1
; ty2 <- newFlexiTyVarTy kind2
- ; co <- unifyType noThing (mkAppTy ty1 ty2) orig_ty
+ ; co <- unifyType Nothing (mkAppTy ty1 ty2) orig_ty
; return (co, (ty1, ty2)) }
orig_kind = typeKind orig_ty
@@ -531,9 +529,8 @@ skolemising the type.
-- | Call this variant when you are in a higher-rank situation and
-- you know the right-hand type is deeply skolemised.
-tcSubTypeHR :: Outputable a
- => CtOrigin -- ^ of the actual type
- -> Maybe a -- ^ If present, it has type ty_actual
+tcSubTypeHR :: CtOrigin -- ^ of the actual type
+ -> Maybe (HsExpr GhcRn) -- ^ If present, it has type ty_actual
-> TcSigmaType -> ExpRhoType -> TcM HsWrapper
tcSubTypeHR orig = tcSubTypeDS_NC_O orig GenSigCtxt
@@ -547,7 +544,8 @@ tcSubTypeET orig ctxt (Check ty_actual) ty_expected
where
eq_orig = TypeEqOrigin { uo_actual = ty_expected
, uo_expected = ty_actual
- , uo_thing = Nothing }
+ , uo_thing = Nothing
+ , uo_visible = True }
tcSubTypeET _ _ (Infer inf_res) ty_expected
= ASSERT2( not (ir_inst inf_res), ppr inf_res $$ ppr ty_expected )
@@ -566,7 +564,7 @@ tcSubTypeO orig ctxt ty_actual ty_expected
, pprUserTypeCtxt ctxt
, ppr ty_actual
, ppr ty_expected ])
- ; tcSubTypeDS_NC_O orig ctxt noThing ty_actual ty_expected }
+ ; tcSubTypeDS_NC_O orig ctxt Nothing ty_actual ty_expected }
addSubTypeCtxt :: TcType -> ExpType -> TcM a -> TcM a
addSubTypeCtxt ty_actual ty_expected thing_inside
@@ -605,7 +603,8 @@ tcSubType_NC ctxt ty_actual ty_expected
where
origin = TypeEqOrigin { uo_actual = ty_actual
, uo_expected = ty_expected
- , uo_thing = Nothing }
+ , uo_thing = Nothing
+ , uo_visible = True }
tcSubTypeDS :: CtOrigin -> UserTypeCtxt -> TcSigmaType -> ExpRhoType -> TcM HsWrapper
-- Just like tcSubType, but with the additional precondition that
@@ -613,12 +612,11 @@ tcSubTypeDS :: CtOrigin -> UserTypeCtxt -> TcSigmaType -> ExpRhoType -> TcM HsWr
tcSubTypeDS orig ctxt ty_actual ty_expected
= addSubTypeCtxt ty_actual ty_expected $
do { traceTc "tcSubTypeDS_NC" (vcat [pprUserTypeCtxt ctxt, ppr ty_actual, ppr ty_expected])
- ; tcSubTypeDS_NC_O orig ctxt noThing ty_actual ty_expected }
+ ; tcSubTypeDS_NC_O orig ctxt Nothing ty_actual ty_expected }
-tcSubTypeDS_NC_O :: Outputable a
- => CtOrigin -- origin used for instantiation only
+tcSubTypeDS_NC_O :: CtOrigin -- origin used for instantiation only
-> UserTypeCtxt
- -> Maybe a
+ -> Maybe (HsExpr GhcRn)
-> TcSigmaType -> ExpRhoType -> TcM HsWrapper
-- Just like tcSubType, but with the additional precondition that
-- ty_expected is deeply skolemised
@@ -628,7 +626,8 @@ tcSubTypeDS_NC_O inst_orig ctxt m_thing ty_actual ty_expected
Check ty -> tc_sub_type_ds eq_orig inst_orig ctxt ty_actual ty
where
eq_orig = TypeEqOrigin { uo_actual = ty_actual, uo_expected = ty
- , uo_thing = mkErrorThing <$> m_thing }
+ , uo_thing = ppr <$> m_thing
+ , uo_visible = True }
---------------
tc_sub_tc_type :: CtOrigin -- used when calling uType
@@ -643,7 +642,7 @@ tc_sub_tc_type eq_orig inst_orig ctxt ty_actual ty_expected
vcat [ text "ty_actual =" <+> ppr ty_actual
, text "ty_expected =" <+> ppr ty_expected ]
; mkWpCastN <$>
- uType eq_orig TypeLevel ty_actual ty_expected }
+ uType TypeLevel eq_orig ty_actual ty_expected }
| otherwise -- This is the general case
= do { traceTc "tc_sub_tc_type (general case)" $
@@ -789,29 +788,29 @@ tc_sub_type_ds eq_orig inst_orig ctxt ty_actual ty_expected
-> eq_orig { uo_actual = rho_a }
_ -> eq_orig
- ; cow <- uType eq_orig' TypeLevel rho_a ty_expected
+ ; cow <- uType TypeLevel eq_orig' rho_a ty_expected
; return (mkWpCastN cow <.> wrap) }
-- use versions without synonyms expanded
- unify = mkWpCastN <$> uType eq_orig TypeLevel ty_actual ty_expected
+ unify = mkWpCastN <$> uType TypeLevel eq_orig ty_actual ty_expected
-----------------
-- needs both un-type-checked (for origins) and type-checked (for wrapping)
-- expressions
tcWrapResult :: HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType
-> TcM (HsExpr GhcTcId)
-tcWrapResult rn_expr = tcWrapResultO (exprCtOrigin rn_expr)
+tcWrapResult rn_expr = tcWrapResultO (exprCtOrigin rn_expr) rn_expr
-- | Sometimes we don't have a @HsExpr Name@ to hand, and this is more
-- convenient.
-tcWrapResultO :: CtOrigin -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType
+tcWrapResultO :: CtOrigin -> HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType
-> TcM (HsExpr GhcTcId)
-tcWrapResultO orig expr actual_ty res_ty
+tcWrapResultO orig rn_expr expr actual_ty res_ty
= do { traceTc "tcWrapResult" (vcat [ text "Actual: " <+> ppr actual_ty
, text "Expected:" <+> ppr res_ty ])
; cow <- tcSubTypeDS_NC_O orig GenSigCtxt
- (Just expr) actual_ty res_ty
+ (Just rn_expr) actual_ty res_ty
; return (mkHsWrap cow expr) }
-----------------------------------
@@ -958,7 +957,8 @@ promoteTcType dest_lvl ty
; prom_ty <- newMetaTyVarTyAtLevel dest_lvl (tYPE rr)
; let eq_orig = TypeEqOrigin { uo_actual = ty
, uo_expected = prom_ty
- , uo_thing = Nothing }
+ , uo_thing = Nothing
+ , uo_visible = False }
; co <- emitWantedEq eq_orig TypeLevel Nominal ty prom_ty
; return (co, prom_ty) }
@@ -969,8 +969,9 @@ promoteTcType dest_lvl ty
; let ty_kind = typeKind ty
kind_orig = TypeEqOrigin { uo_actual = ty_kind
, uo_expected = res_kind
- , uo_thing = Nothing }
- ; ki_co <- uType kind_orig KindLevel (typeKind ty) res_kind
+ , uo_thing = Nothing
+ , uo_visible = False }
+ ; ki_co <- uType KindLevel kind_orig (typeKind ty) res_kind
; let co = mkTcNomReflCo ty `mkTcCoherenceRightCo` ki_co
; return (co, ty `mkCastTy` ki_co) }
@@ -1184,32 +1185,28 @@ The exported functions are all defined as versions of some
non-exported generic functions.
-}
-unifyType :: Outputable a => Maybe a -- ^ If present, has type 'ty1'
+unifyType :: Maybe (HsExpr GhcRn) -- ^ If present, has type 'ty1'
-> TcTauType -> TcTauType -> TcM TcCoercionN
-- Actual and expected types
-- Returns a coercion : ty1 ~ ty2
unifyType thing ty1 ty2 = traceTc "utype" (ppr ty1 $$ ppr ty2 $$ ppr thing) >>
- uType origin TypeLevel ty1 ty2
+ uType TypeLevel origin ty1 ty2
where
origin = TypeEqOrigin { uo_actual = ty1, uo_expected = ty2
- , uo_thing = mkErrorThing <$> thing }
+ , uo_thing = ppr <$> thing
+ , uo_visible = True } -- always called from a visible context
--- | Use this instead of 'Nothing' when calling 'unifyType' without
--- a good "thing" (where the "thing" has the "actual" type passed in)
--- This has an 'Outputable' instance, avoiding amgiguity problems.
-noThing :: Maybe (HsExpr GhcRn)
-noThing = Nothing
-
-unifyKind :: Outputable a => Maybe a -> TcKind -> TcKind -> TcM CoercionN
+unifyKind :: Maybe (HsType GhcRn) -> TcKind -> TcKind -> TcM CoercionN
unifyKind thing ty1 ty2 = traceTc "ukind" (ppr ty1 $$ ppr ty2 $$ ppr thing) >>
- uType origin KindLevel ty1 ty2
+ uType KindLevel origin ty1 ty2
where origin = TypeEqOrigin { uo_actual = ty1, uo_expected = ty2
- , uo_thing = mkErrorThing <$> thing }
+ , uo_thing = ppr <$> thing
+ , uo_visible = True } -- also always from a visible context
---------------
unifyPred :: PredType -> PredType -> TcM TcCoercionN
-- Actual and expected types
-unifyPred = unifyType noThing
+unifyPred = unifyType Nothing
---------------
unifyTheta :: TcThetaType -> TcThetaType -> TcM [TcCoercionN]
@@ -1231,8 +1228,8 @@ uType is the heart of the unifier.
-}
uType, uType_defer
- :: CtOrigin
- -> TypeOrKind
+ :: TypeOrKind
+ -> CtOrigin
-> TcType -- ty1 is the *actual* type
-> TcType -- ty2 is the *expected* type
-> TcM Coercion
@@ -1240,7 +1237,7 @@ uType, uType_defer
--------------
-- It is always safe to defer unification to the main constraint solver
-- See Note [Deferred unification]
-uType_defer origin t_or_k ty1 ty2
+uType_defer t_or_k origin ty1 ty2
= do { co <- emitWantedEq origin t_or_k Nominal ty1 ty2
-- Error trace only
@@ -1255,7 +1252,7 @@ uType_defer origin t_or_k ty1 ty2
; return co }
--------------
-uType origin t_or_k orig_ty1 orig_ty2
+uType t_or_k origin orig_ty1 orig_ty2
= do { tclvl <- getTcLevel
; traceTc "u_tys" $ vcat
[ text "tclvl" <+> ppr tclvl
@@ -1315,8 +1312,8 @@ uType origin t_or_k orig_ty1 orig_ty2
-- Functions (or predicate functions) just check the two parts
go (FunTy fun1 arg1) (FunTy fun2 arg2)
- = do { co_l <- uType origin t_or_k fun1 fun2
- ; co_r <- uType origin t_or_k arg1 arg2
+ = do { co_l <- uType t_or_k origin fun1 fun2
+ ; co_r <- uType t_or_k origin arg1 arg2
; return $ mkFunCo Nominal co_l co_r }
-- Always defer if a type synonym family (type function)
@@ -1330,8 +1327,11 @@ uType origin t_or_k orig_ty1 orig_ty2
-- See Note [Mismatched type lists and application decomposition]
| tc1 == tc2, equalLength tys1 tys2
= ASSERT2( isGenerativeTyCon tc1 Nominal, ppr tc1 )
- do { cos <- zipWithM (uType origin t_or_k) tys1 tys2
+ do { cos <- zipWith3M (uType t_or_k) origins' tys1 tys2
; return $ mkTyConAppCo Nominal tc1 cos }
+ where
+ origins' = map (\is_vis -> if is_vis then origin else toInvisibleOrigin origin)
+ (tcTyConVisibilities tc1)
go (LitTy m) ty@(LitTy n)
| m == n
@@ -1341,24 +1341,24 @@ uType origin t_or_k orig_ty1 orig_ty2
-- Do not decompose FunTy against App;
-- it's often a type error, so leave it for the constraint solver
go (AppTy s1 t1) (AppTy s2 t2)
- = go_app s1 t1 s2 t2
+ = go_app (isNextArgVisible s1) s1 t1 s2 t2
go (AppTy s1 t1) (TyConApp tc2 ts2)
| Just (ts2', t2') <- snocView ts2
= ASSERT( mightBeUnsaturatedTyCon tc2 )
- go_app s1 t1 (TyConApp tc2 ts2') t2'
+ go_app (isNextTyConArgVisible tc2 ts2') s1 t1 (TyConApp tc2 ts2') t2'
go (TyConApp tc1 ts1) (AppTy s2 t2)
| Just (ts1', t1') <- snocView ts1
= ASSERT( mightBeUnsaturatedTyCon tc1 )
- go_app (TyConApp tc1 ts1') t1' s2 t2
+ go_app (isNextTyConArgVisible tc1 ts1') (TyConApp tc1 ts1') t1' s2 t2
go (CoercionTy co1) (CoercionTy co2)
= do { let ty1 = coercionType co1
ty2 = coercionType co2
- ; kco <- uType (KindEqOrigin orig_ty1 (Just orig_ty2) origin
+ ; kco <- uType KindLevel
+ (KindEqOrigin orig_ty1 (Just orig_ty2) origin
(Just t_or_k))
- KindLevel
ty1 ty2
; return $ mkProofIrrelCo Nominal kco co1 co2 }
@@ -1369,12 +1369,15 @@ uType origin t_or_k orig_ty1 orig_ty2
------------------
defer ty1 ty2 -- See Note [Check for equality before deferring]
| ty1 `tcEqType` ty2 = return (mkNomReflCo ty1)
- | otherwise = uType_defer origin t_or_k ty1 ty2
+ | otherwise = uType_defer t_or_k origin ty1 ty2
------------------
- go_app s1 t1 s2 t2
- = do { co_s <- uType origin t_or_k s1 s2
- ; co_t <- uType origin t_or_k t1 t2
+ go_app vis s1 t1 s2 t2
+ = do { co_s <- uType t_or_k origin s1 s2
+ ; let arg_origin
+ | vis = origin
+ | otherwise = toInvisibleOrigin origin
+ ; co_t <- uType t_or_k arg_origin t1 t2
; return $ mkAppCo co_s co_t }
{- Note [Check for equality before deferring]
@@ -1528,12 +1531,17 @@ uUnfilledVar2 origin t_or_k swapped tv1 ty2
go dflags cur_lvl
| canSolveByUnification cur_lvl tv1 ty2
, Just ty2' <- metaTyVarUpdateOK dflags tv1 ty2
- = do { co_k <- uType kind_origin KindLevel (typeKind ty2') (tyVarKind tv1)
- ; co <- updateMeta tv1 ty2' co_k
- ; return (maybe_sym swapped co) }
+ = do { co_k <- uType KindLevel kind_origin (typeKind ty2') (tyVarKind tv1)
+ ; if isTcReflCo co_k -- only proceed if the kinds matched.
+
+ then do { writeMetaTyVar tv1 ty2'
+ ; return (mkTcNomReflCo ty2') }
+ else defer } -- this cannot be solved now.
+ -- See Note [Equalities with incompatible kinds]
+ -- in TcCanonical
| otherwise
- = unSwap swapped (uType_defer origin t_or_k) ty1 ty2
+ = defer
-- Occurs check or an untouchable: just defer
-- NB: occurs check isn't necessarily fatal:
-- eg tv1 occured in type family parameter
@@ -1541,10 +1549,7 @@ uUnfilledVar2 origin t_or_k swapped tv1 ty2
ty1 = mkTyVarTy tv1
kind_origin = KindEqOrigin ty1 (Just ty2) origin (Just t_or_k)
--- | apply sym iff swapped
-maybe_sym :: SwapFlag -> Coercion -> Coercion
-maybe_sym IsSwapped = mkSymCo
-maybe_sym NotSwapped = id
+ defer = unSwap swapped (uType_defer t_or_k origin) ty1 ty2
swapOverTyVars :: TcTyVar -> TcTyVar -> Bool
swapOverTyVars tv1 tv2
@@ -1768,18 +1773,6 @@ lookupTcTyVar tyvar
where
details = tcTyVarDetails tyvar
--- | Fill in a meta-tyvar
-updateMeta :: TcTyVar -- ^ tv to fill in, tv :: k1
- -> TcType -- ^ ty2 :: k2
- -> Coercion -- ^ kind_co :: k2 ~N k1
- -> TcM Coercion -- ^ :: tv ~N ty2 (= ty2 |> kind_co ~N ty2)
-updateMeta tv1 ty2 kind_co
- = do { let ty2' = ty2 `mkCastTy` kind_co
- ty2_refl = mkNomReflCo ty2
- co = mkCoherenceLeftCo ty2_refl kind_co
- ; writeMetaTyVar tv1 ty2'
- ; return co }
-
{-
Note [Unifying untouchables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1789,12 +1782,12 @@ we return a made-up TcTyVarDetails, but I think it works smoothly.
-}
-- | Breaks apart a function kind into its pieces.
-matchExpectedFunKind :: Arity -- ^ # of args remaining, only for errors
- -> TcType -- ^ type, only for errors
+matchExpectedFunKind :: Outputable fun
+ => fun -- ^ type, only for errors
-> TcKind -- ^ function kind
-> TcM (Coercion, TcKind, TcKind)
-- ^ co :: old_kind ~ arg -> res
-matchExpectedFunKind num_args_remaining ty = go
+matchExpectedFunKind hs_ty = go
where
go k | Just k' <- tcView k = go k'
@@ -1812,12 +1805,12 @@ matchExpectedFunKind num_args_remaining ty = go
= do { arg_kind <- newMetaKindVar
; res_kind <- newMetaKindVar
; let new_fun = mkFunTy arg_kind res_kind
- thing = mkTypeErrorThingArgs ty num_args_remaining
origin = TypeEqOrigin { uo_actual = k
, uo_expected = new_fun
- , uo_thing = Just thing
+ , uo_thing = Just (ppr hs_ty)
+ , uo_visible = True
}
- ; co <- uType origin KindLevel k new_fun
+ ; co <- uType KindLevel origin k new_fun
; return (co, arg_kind, res_kind) }
diff --git a/compiler/typecheck/TcUnify.hs-boot b/compiler/typecheck/TcUnify.hs-boot
index 9af4c27775..5335c15db7 100644
--- a/compiler/typecheck/TcUnify.hs-boot
+++ b/compiler/typecheck/TcUnify.hs-boot
@@ -2,13 +2,12 @@ module TcUnify where
import TcType ( TcTauType )
import TcRnTypes ( TcM )
import TcEvidence ( TcCoercion )
-import Outputable ( Outputable )
import HsExpr ( HsExpr )
+import HsTypes ( HsType )
import HsExtension ( GhcRn )
-- This boot file exists only to tie the knot between
-- TcUnify and Inst
-unifyType :: Outputable a => Maybe a -> TcTauType -> TcTauType -> TcM TcCoercion
-unifyKind :: Outputable a => Maybe a -> TcTauType -> TcTauType -> TcM TcCoercion
-noThing :: Maybe (HsExpr GhcRn)
+unifyType :: Maybe (HsExpr GhcRn) -> TcTauType -> TcTauType -> TcM TcCoercion
+unifyKind :: Maybe (HsType GhcRn) -> TcTauType -> TcTauType -> TcM TcCoercion
diff --git a/compiler/typecheck/TcValidity.hs b/compiler/typecheck/TcValidity.hs
index 4f7507745e..d8e2519fed 100644
--- a/compiler/typecheck/TcValidity.hs
+++ b/compiler/typecheck/TcValidity.hs
@@ -56,13 +56,13 @@ import Util
import ListSetOps
import SrcLoc
import Outputable
-import BasicTypes
import Module
import Unique ( mkAlphaTyVarUnique )
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
import Data.List ( (\\) )
+import qualified Data.List.NonEmpty as NE
{-
************************************************************************
@@ -973,13 +973,13 @@ constraintSynErr env kind
, hang (text "Illegal constraint synonym of kind:" <+> quotes (ppr_tidy env kind))
2 (parens constraintKindsMsg) )
-dupPredWarn :: TidyEnv -> [[PredType]] -> (TidyEnv, SDoc)
+dupPredWarn :: TidyEnv -> [NE.NonEmpty PredType] -> (TidyEnv, SDoc)
dupPredWarn env dups
= ( env
, text "Duplicate constraint" <> plural primaryDups <> text ":"
<+> pprWithCommas (ppr_tidy env) primaryDups )
where
- primaryDups = map head dups
+ primaryDups = map NE.head dups
tyConArityErr :: TyCon -> [TcType] -> SDoc
-- For type-constructor arity errors, be careful to report
@@ -1201,7 +1201,7 @@ It checks for three things
might be applications thus (f (g x)).
Note that tys only includes the visible arguments of the class type
- constructor. Including the non-vivisble arguments can cause the following,
+ constructor. Including the non-visible arguments can cause the following,
perfectly valid instance to be rejected:
class Category (cat :: k -> k -> *) where ...
newtype T (c :: * -> * -> *) a b = MkT (c a b)
@@ -1540,13 +1540,13 @@ type AssocInstArgShape = (Maybe Type, Type)
checkConsistentFamInst
:: Maybe ClsInstInfo
-> TyCon -- ^ Family tycon
- -> [TyVar] -- ^ Type variables of the family instance
-> [Type] -- ^ Type patterns from instance
+ -> SDoc -- ^ pretty-printed user-written instance head
-> TcM ()
-- See Note [Checking consistent instantiation]
checkConsistentFamInst Nothing _ _ _ = return ()
-checkConsistentFamInst (Just (clas, inst_tvs, mini_env)) fam_tc _at_tvs at_tys
+checkConsistentFamInst (Just (clas, inst_tvs, mini_env)) fam_tc at_tys pp_hs_pats
= do { -- Check that the associated type indeed comes from this class
checkTc (Just clas == tyConAssoc_maybe fam_tc)
(badATErr (className clas) (tyConName fam_tc))
@@ -1579,7 +1579,7 @@ checkConsistentFamInst (Just (clas, inst_tvs, mini_env)) fam_tc _at_tvs at_tys
pp_exp_act
= vcat [ text "Expected:" <+> ppr (mkTyConApp fam_tc expected_args)
- , text " Actual:" <+> ppr (mkTyConApp fam_tc at_tys)
+ , text " Actual:" <+> pp_hs_pats
, sdocWithDynFlags $ \dflags ->
ppWhen (has_poly_args dflags) $
vcat [ text "where the `<tv>' arguments are type variables,"
@@ -1669,7 +1669,9 @@ checkValidCoAxBranch mb_clsinfo fam_tc
(CoAxBranch { cab_tvs = tvs, cab_cvs = cvs
, cab_lhs = typats
, cab_rhs = rhs, cab_loc = loc })
- = checkValidTyFamEqn mb_clsinfo fam_tc tvs cvs typats rhs loc
+ = checkValidTyFamEqn mb_clsinfo fam_tc tvs cvs typats rhs pp_lhs loc
+ where
+ pp_lhs = ppr (mkTyConApp fam_tc typats)
-- | Do validity checks on a type family equation, including consistency
-- with any enclosing class instance head, termination, and lack of
@@ -1680,11 +1682,12 @@ checkValidTyFamEqn :: Maybe ClsInstInfo
-> [CoVar] -- ^ bound covars in the equation
-> [Type] -- ^ type patterns
-> Type -- ^ rhs
+ -> SDoc -- ^ user-written LHS
-> SrcSpan
-> TcM ()
-checkValidTyFamEqn mb_clsinfo fam_tc tvs cvs typats rhs loc
+checkValidTyFamEqn mb_clsinfo fam_tc tvs cvs typats rhs pp_lhs loc
= setSrcSpan loc $
- do { checkValidFamPats mb_clsinfo fam_tc tvs cvs typats
+ do { checkValidFamPats mb_clsinfo fam_tc tvs cvs typats [] pp_lhs
-- The argument patterns, and RHS, are all boxed tau types
-- E.g Reject type family F (a :: k1) :: k2
@@ -1722,7 +1725,11 @@ checkFamInstRhs lhsTys famInsts
what = text "type family application" <+> quotes (pprType (TyConApp tc tys))
bad_tvs = fvTypes tys \\ fvs
-checkValidFamPats :: Maybe ClsInstInfo -> TyCon -> [TyVar] -> [CoVar] -> [Type] -> TcM ()
+checkValidFamPats :: Maybe ClsInstInfo -> TyCon -> [TyVar] -> [CoVar]
+ -> [Type] -- ^ patterns the user wrote
+ -> [Type] -- ^ "extra" patterns from a data instance kind sig
+ -> SDoc -- ^ pretty-printed user-written instance head
+ -> TcM ()
-- Patterns in a 'type instance' or 'data instance' decl should
-- a) contain no type family applications
-- (vanilla synonyms are fine, though)
@@ -1730,29 +1737,16 @@ checkValidFamPats :: Maybe ClsInstInfo -> TyCon -> [TyVar] -> [CoVar] -> [Type]
-- e.g. we disallow (Trac #7536)
-- type T a = Int
-- type instance F (T a) = a
--- c) Have the right number of patterns
--- d) For associated types, are consistently instantiated
-checkValidFamPats mb_clsinfo fam_tc tvs cvs ty_pats
- = do { -- A family instance must have exactly the same number of type
- -- parameters as the family declaration. You can't write
- -- type family F a :: * -> *
- -- type instance F Int y = y
- -- because then the type (F Int) would be like (\y.y)
- checkTc (ty_pats `lengthIs` fam_arity) $
- wrongNumberOfParmsErr (fam_arity - count isInvisibleTyConBinder fam_bndrs)
- -- report only explicit arguments
-
- ; mapM_ checkValidTypePat ty_pats
-
- ; let unbound_tcvs = filterOut (`elemVarSet` exactTyCoVarsOfTypes ty_pats) (tvs ++ cvs)
- ; checkTc (null unbound_tcvs) (famPatErr fam_tc unbound_tcvs ty_pats)
+-- c) For associated types, are consistently instantiated
+checkValidFamPats mb_clsinfo fam_tc tvs cvs user_ty_pats extra_ty_pats pp_hs_pats
+ = do { mapM_ checkValidTypePat user_ty_pats
- -- Check that type patterns match the class instance head
- ; checkConsistentFamInst mb_clsinfo fam_tc tvs ty_pats }
- where
- fam_arity = tyConArity fam_tc
- fam_bndrs = tyConBinders fam_tc
+ ; let unbound_tcvs = filterOut (`elemVarSet` exactTyCoVarsOfTypes user_ty_pats)
+ (tvs ++ cvs)
+ ; checkTc (null unbound_tcvs) (famPatErr fam_tc unbound_tcvs user_ty_pats)
+ -- Check that type patterns match the class instance head
+ ; checkConsistentFamInst mb_clsinfo fam_tc (user_ty_pats `chkAppend` extra_ty_pats) pp_hs_pats }
checkValidTypePat :: Type -> TcM ()
-- Used for type patterns in class instances,
@@ -1774,11 +1768,6 @@ isTyFamFree = null . tcTyFamInsts
-- Error messages
-wrongNumberOfParmsErr :: Arity -> SDoc
-wrongNumberOfParmsErr exp_arity
- = text "Number of parameters must match family declaration; expected"
- <+> ppr exp_arity
-
inaccessibleCoAxBranch :: CoAxiom br -> CoAxBranch -> SDoc
inaccessibleCoAxBranch fi_ax cur_branch
= text "Type family instance equation is overlapped:" $$
diff --git a/compiler/types/Class.hs b/compiler/types/Class.hs
index ae1047ebde..b981a4998e 100644
--- a/compiler/types/Class.hs
+++ b/compiler/types/Class.hs
@@ -60,6 +60,10 @@ data Class
classTyVars :: [TyVar], -- The class kind and type variables;
-- identical to those of the TyCon
+ -- If you want visiblity info, look at the classTyCon
+ -- This field is redundant because it's duplicated in the
+ -- classTyCon, but classTyVars is used quite often, so maybe
+ -- it's a bit faster to cache it here
classFunDeps :: [FunDep TyVar], -- The functional dependencies
diff --git a/compiler/types/Coercion.hs b/compiler/types/Coercion.hs
index 3f5036c4dd..214fe2d92e 100644
--- a/compiler/types/Coercion.hs
+++ b/compiler/types/Coercion.hs
@@ -95,7 +95,7 @@ module Coercion (
seqCo,
-- * Pretty-printing
- pprCo, pprParendCo, pprCoBndr,
+ pprCo, pprParendCo,
pprCoAxiom, pprCoAxBranch, pprCoAxBranchHdr,
-- * Tidying
@@ -152,117 +152,32 @@ setCoVarUnique = setVarUnique
setCoVarName :: CoVar -> Name -> CoVar
setCoVarName = setVarName
-
{-
%************************************************************************
%* *
- Pretty-printing coercions
+ Pretty-printing CoAxioms
%* *
%************************************************************************
-@pprCo@ is the standard @Coercion@ printer; the overloaded @ppr@
-function is defined to use this. @pprParendCo@ is the same, except it
-puts parens around the type, except for the atomic cases.
-@pprParendCo@ works just by setting the initial context precedence
-very high.
--}
-
--- Outputable instances are in TyCoRep, to avoid orphans
-
-pprCo, pprParendCo :: Coercion -> SDoc
-pprCo co = ppr_co TopPrec co
-pprParendCo co = ppr_co TyConPrec co
-
-ppr_co :: TyPrec -> Coercion -> SDoc
-ppr_co _ (Refl r ty) = angleBrackets (ppr ty) <> ppr_role r
-
-ppr_co _ (TyConAppCo r tc cos) = pprTcAppCo TyConPrec ppr_co tc cos <> ppr_role r
-ppr_co p (AppCo co arg) = maybeParen p TyConPrec $
- pprCo co <+> ppr_co TyConPrec arg
-ppr_co p co@(ForAllCo {}) = ppr_forall_co p co
-ppr_co p co@(FunCo {}) = ppr_fun_co p co
-ppr_co _ (CoVarCo cv) = parenSymOcc (getOccName cv) (ppr cv)
-ppr_co p (AxiomInstCo con index args)
- = pprPrefixApp p (ppr (getName con) <> brackets (ppr index))
- (map (ppr_co TyConPrec) args)
-
-ppr_co p co@(TransCo {}) = maybeParen p FunPrec $
- case trans_co_list co [] of
- [] -> panic "ppr_co"
- (co:cos) -> sep ( ppr_co FunPrec co
- : [ char ';' <+> ppr_co FunPrec co | co <- cos])
-ppr_co p (InstCo co arg) = maybeParen p TyConPrec $
- pprParendCo co <> text "@" <> ppr_co TopPrec arg
-
-ppr_co p (UnivCo UnsafeCoerceProv r ty1 ty2)
- = pprPrefixApp p (text "UnsafeCo" <+> ppr r)
- [pprParendType ty1, pprParendType ty2]
-ppr_co _ (UnivCo p r t1 t2)
- = char 'U'
- <> parens (ppr_prov <> comma <+> ppr t1 <> comma <+> ppr t2)
- <> ppr_role r
- where
- ppr_prov = case p of
- HoleProv h -> text "hole:" <> ppr h
- PhantomProv kind_co -> text "phant:" <> ppr kind_co
- ProofIrrelProv co -> text "irrel:" <> ppr co
- PluginProv s -> text "plugin:" <> text s
- UnsafeCoerceProv -> text "unsafe"
-
-ppr_co p (SymCo co) = pprPrefixApp p (text "Sym") [pprParendCo co]
-ppr_co p (NthCo n co) = pprPrefixApp p (text "Nth:" <> int n) [pprParendCo co]
-ppr_co p (LRCo sel co) = pprPrefixApp p (ppr sel) [pprParendCo co]
-ppr_co p (CoherenceCo c1 c2) = maybeParen p TyConPrec $
- (ppr_co FunPrec c1) <+> (text "|>") <+>
- (ppr_co FunPrec c2)
-ppr_co p (KindCo co) = pprPrefixApp p (text "kind") [pprParendCo co]
-ppr_co p (SubCo co) = pprPrefixApp p (text "Sub") [pprParendCo co]
-ppr_co p (AxiomRuleCo co cs) = maybeParen p TopPrec $ ppr_axiom_rule_co co cs
-
-ppr_axiom_rule_co :: CoAxiomRule -> [Coercion] -> SDoc
-ppr_axiom_rule_co co ps = ppr (coaxrName co) <+> parens (interpp'SP ps)
-
-ppr_role :: Role -> SDoc
-ppr_role r = underscore <> pp_role
- where pp_role = case r of
- Nominal -> char 'N'
- Representational -> char 'R'
- Phantom -> char 'P'
-
-trans_co_list :: Coercion -> [Coercion] -> [Coercion]
-trans_co_list (TransCo co1 co2) cos = trans_co_list co1 (trans_co_list co2 cos)
-trans_co_list co cos = co : cos
-
-ppr_fun_co :: TyPrec -> Coercion -> SDoc
-ppr_fun_co p co = pprArrowChain p (split co)
- where
- split :: Coercion -> [SDoc]
- split (FunCo _ arg res)
- = ppr_co FunPrec arg : split res
- split co = [ppr_co TopPrec co]
+Defined here to avoid module loops. CoAxiom is loaded very early on.
-ppr_forall_co :: TyPrec -> Coercion -> SDoc
-ppr_forall_co p (ForAllCo tv h co)
- = maybeParen p FunPrec $
- sep [pprCoBndr (tyVarName tv) h, ppr_co TopPrec co]
-ppr_forall_co _ _ = panic "ppr_forall_co"
-
-pprCoBndr :: Name -> Coercion -> SDoc
-pprCoBndr name eta =
- forAllLit <+> parens (ppr name <+> dcolon <+> ppr eta) <> dot
+-}
pprCoAxiom :: CoAxiom br -> SDoc
pprCoAxiom ax@(CoAxiom { co_ax_branches = branches })
= hang (text "axiom" <+> ppr ax <+> dcolon)
- 2 (vcat (map (ppr_co_ax_branch (const ppr) ax) $ fromBranches branches))
+ 2 (vcat (map (ppr_co_ax_branch (const pprType) ax) $ fromBranches branches))
pprCoAxBranch :: CoAxiom br -> CoAxBranch -> SDoc
pprCoAxBranch = ppr_co_ax_branch pprRhs
where
- pprRhs fam_tc (TyConApp tycon _)
- | isDataFamilyTyCon fam_tc
+ pprRhs fam_tc rhs
+ | Just (tycon, _) <- splitTyConApp_maybe rhs
+ , isDataFamilyTyCon fam_tc
= pprDataCons tycon
- pprRhs _ rhs = ppr rhs
+
+ | otherwise
+ = ppr rhs
pprCoAxBranchHdr :: CoAxiom br -> BranchIndex -> SDoc
pprCoAxBranchHdr ax index = pprCoAxBranch ax (coAxiomNthBranch ax index)
@@ -1598,6 +1513,8 @@ ty_co_subst lc role ty
= go role ty
where
go :: Role -> Type -> Coercion
+ go r ty | Just ty' <- coreView ty
+ = go r ty'
go Phantom ty = lift_phantom ty
go r (TyVarTy tv) = expectJust "ty_co_subst bad roles" $
liftCoSubstTyVar lc r tv
diff --git a/compiler/types/Coercion.hs-boot b/compiler/types/Coercion.hs-boot
index dd10d6e5ca..d9aa234193 100644
--- a/compiler/types/Coercion.hs-boot
+++ b/compiler/types/Coercion.hs-boot
@@ -8,7 +8,6 @@ import {-# SOURCE #-} TyCon
import BasicTypes ( LeftOrRight )
import CoAxiom
import Var
-import Outputable
import Pair
import Util
@@ -47,5 +46,3 @@ seqCo :: Coercion -> ()
coercionKind :: Coercion -> Pair Type
coercionType :: Coercion -> Type
-
-pprCo :: Coercion -> SDoc
diff --git a/compiler/types/FamInstEnv.hs b/compiler/types/FamInstEnv.hs
index 6d179a9a10..cec7b58e38 100644
--- a/compiler/types/FamInstEnv.hs
+++ b/compiler/types/FamInstEnv.hs
@@ -29,9 +29,8 @@ module FamInstEnv (
-- Normalisation
topNormaliseType, topNormaliseType_maybe,
- normaliseType, normaliseTcApp,
+ normaliseType, normaliseTcApp, normaliseTcArgs,
reduceTyFamApp_maybe,
- pmTopNormaliseType_maybe,
-- Flattening
flattenTys
@@ -43,7 +42,6 @@ import Unify
import Type
import TyCoRep
import TyCon
-import DataCon (DataCon)
import Coercion
import CoAxiom
import VarSet
@@ -62,7 +60,7 @@ import SrcLoc
import FastString
import MonadUtils
import Control.Monad
-import Data.List( mapAccumL, find )
+import Data.List( mapAccumL )
{-
************************************************************************
@@ -125,8 +123,50 @@ data FamFlavor
= SynFamilyInst -- A synonym family
| DataFamilyInst TyCon -- A data family, with its representation TyCon
-{- Note [Eta reduction for data families]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{-
+Note [Arity of data families]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Data family instances might legitimately be over- or under-saturated.
+
+Under-saturation has two potential causes:
+ U1) Eta reduction. See Note [Eta reduction for data families].
+ U2) When the user has specified a return kind instead of written out patterns.
+ Example:
+
+ data family Sing (a :: k)
+ data instance Sing :: Bool -> Type
+
+ The data family tycon Sing has an arity of 2, the k and the a. But
+ the data instance has only one pattern, Bool (standing in for k).
+ This instance is equivalent to `data instance Sing (a :: Bool)`, but
+ without the last pattern, we have an under-saturated data family instance.
+ On its own, this example is not compelling enough to add support for
+ under-saturation, but U1 makes this feature more compelling.
+
+Over-saturation is also possible:
+ O1) If the data family's return kind is a type variable (see also #12369),
+ an instance might legitimately have more arguments than the family.
+ Example:
+
+ data family Fix :: (Type -> k) -> k
+ data instance Fix f = MkFix1 (f (Fix f))
+ data instance Fix f x = MkFix2 (f (Fix f x) x)
+
+ In the first instance here, the k in the data family kind is chosen to
+ be Type. In the second, it's (Type -> Type).
+
+ However, we require that any over-saturation is eta-reducible. That is,
+ we require that any extra patterns be bare unrepeated type variables;
+ see Note [Eta reduction for data families]. Accordingly, the FamInst
+ is never over-saturated.
+
+Why can we allow such flexibility for data families but not for type families?
+Because data families can be decomposed -- that is, they are generative and
+injective. A Type family is neither and so always must be applied to all its
+arguments.
+
+Note [Eta reduction for data families]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this
data family T a b :: *
newtype instance T Int a = MkT (IO a) deriving( Monad )
@@ -156,7 +196,7 @@ See also Note [Newtype eta] in TyCon.
Bottom line:
For a FamInst with fi_flavour = DataFamilyInst rep_tc,
- - fi_tvs may be shorter than tyConTyVars of rep_tc
+ - fi_tvs may be shorter than tyConTyVars of rep_tc.
- fi_tys may be shorter than tyConArity of the family tycon
i.e. LHS is unsaturated
- fi_rhs will be (rep_tc fi_tvs)
@@ -1232,114 +1272,6 @@ topNormaliseType_maybe env ty
_ -> NS_Done
---------------
-pmTopNormaliseType_maybe :: FamInstEnvs -> Type -> Maybe (Type, [DataCon], Type)
--- ^ Get rid of *outermost* (or toplevel)
--- * type function redex
--- * data family redex
--- * newtypes
---
--- Behaves exactly like `topNormaliseType_maybe`, but instead of returning a
--- coercion, it returns useful information for issuing pattern matching
--- warnings. See Note [Type normalisation for EmptyCase] for details.
-pmTopNormaliseType_maybe env typ
- = do ((ty_f,tm_f), ty) <- topNormaliseTypeX stepper comb typ
- return (eq_src_ty ty (typ : ty_f [ty]), tm_f [], ty)
- where
- -- Find the first type in the sequence of rewrites that is a data type,
- -- newtype, or a data family application (not the representation tycon!).
- -- This is the one that is equal (in source Haskell) to the initial type.
- -- If none is found in the list, then all of them are type family
- -- applications, so we simply return the last one, which is the *simplest*.
- eq_src_ty :: Type -> [Type] -> Type
- eq_src_ty ty tys = maybe ty id (find is_alg_or_data_family tys)
-
- is_alg_or_data_family :: Type -> Bool
- is_alg_or_data_family ty = isClosedAlgType ty || isDataFamilyAppType ty
-
- -- For efficiency, represent both lists as difference lists.
- -- comb performs the concatenation, for both lists.
- comb (tyf1, tmf1) (tyf2, tmf2) = (tyf1 . tyf2, tmf1 . tmf2)
-
- stepper = newTypeStepper `composeSteppers` tyFamStepper
-
- -- A 'NormaliseStepper' that unwraps newtypes, careful not to fall into
- -- a loop. If it would fall into a loop, it produces 'NS_Abort'.
- newTypeStepper :: NormaliseStepper ([Type] -> [Type],[DataCon] -> [DataCon])
- newTypeStepper rec_nts tc tys
- | Just (ty', _co) <- instNewTyCon_maybe tc tys
- = case checkRecTc rec_nts tc of
- Just rec_nts' -> let tyf = ((TyConApp tc tys):)
- tmf = ((tyConSingleDataCon tc):)
- in NS_Step rec_nts' ty' (tyf, tmf)
- Nothing -> NS_Abort
- | otherwise
- = NS_Done
-
- tyFamStepper :: NormaliseStepper ([Type] -> [Type], [DataCon] -> [DataCon])
- tyFamStepper rec_nts tc tys -- Try to step a type/data family
- = let (_args_co, ntys) = normaliseTcArgs env Representational tc tys in
- -- NB: It's OK to use normaliseTcArgs here instead of
- -- normalise_tc_args (which takes the LiftingContext described
- -- in Note [Normalising types]) because the reduceTyFamApp below
- -- works only at top level. We'll never recur in this function
- -- after reducing the kind of a bound tyvar.
-
- case reduceTyFamApp_maybe env Representational tc ntys of
- Just (_co, rhs) -> NS_Step rec_nts rhs ((rhs:), id)
- _ -> NS_Done
-
-{- Note [Type normalisation for EmptyCase]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-EmptyCase is an exception for pattern matching, since it is strict. This means
-that it boils down to checking whether the type of the scrutinee is inhabited.
-Function pmTopNormaliseType_maybe gets rid of the outermost type function/data
-family redex and newtypes, in search of an algebraic type constructor, which is
-easier to check for inhabitation.
-
-It returns 3 results instead of one, because there are 2 subtle points:
-1. Newtypes are isomorphic to the underlying type in core but not in the source
- language,
-2. The representational data family tycon is used internally but should not be
- shown to the user
-
-Hence, if pmTopNormaliseType_maybe env ty = Just (src_ty, dcs, core_ty), then
- (a) src_ty is the rewritten type which we can show to the user. That is, the
- type we get if we rewrite type families but not data families or
- newtypes.
- (b) dcs is the list of data constructors "skipped", every time we normalise a
- newtype to it's core representation, we keep track of the source data
- constructor.
- (c) core_ty is the rewritten type. That is,
- pmTopNormaliseType_maybe env ty = Just (src_ty, dcs, core_ty)
- implies
- topNormaliseType_maybe env ty = Just (co, core_ty)
- for some coercion co.
-
-To see how all cases come into play, consider the following example:
-
- data family T a :: *
- data instance T Int = T1 | T2 Bool
- -- Which gives rise to FC:
- -- data T a
- -- data R:TInt = T1 | T2 Bool
- -- axiom ax_ti : T Int ~R R:TInt
-
- newtype G1 = MkG1 (T Int)
- newtype G2 = MkG2 G1
-
- type instance F Int = F Char
- type instance F Char = G2
-
-In this case pmTopNormaliseType_maybe env (F Int) results in
-
- Just (G2, [MkG2,MkG1], R:TInt)
-
-Which means that in source Haskell:
- - G2 is equivalent to F Int (in contrast, G1 isn't).
- - if (x : R:TInt) then (MkG2 (MkG1 x) : F Int).
--}
-
----------------
normaliseTcApp :: FamInstEnvs -> Role -> TyCon -> [Type] -> (Coercion, Type)
-- See comments on normaliseType for the arguments of this function
normaliseTcApp env role tc tys
diff --git a/compiler/types/OptCoercion.hs b/compiler/types/OptCoercion.hs
index 67644094ed..f26351f3bd 100644
--- a/compiler/types/OptCoercion.hs
+++ b/compiler/types/OptCoercion.hs
@@ -4,9 +4,7 @@
-- The default iteration limit is a bit too low for the definitions
-- in this module.
-#if __GLASGOW_HASKELL__ >= 800
{-# OPTIONS_GHC -fmax-pmcheck-iterations=10000000 #-}
-#endif
module OptCoercion ( optCoercion, checkAxInstCo ) where
diff --git a/compiler/types/TyCoRep.hs b/compiler/types/TyCoRep.hs
index 5ac63e5b04..8b8a960f72 100644
--- a/compiler/types/TyCoRep.hs
+++ b/compiler/types/TyCoRep.hs
@@ -18,7 +18,6 @@ Note [The Type-related module hierarchy]
-- We expose the relevant stuff from this module via the Type module
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE CPP, DeriveDataTypeable, MultiWayIf #-}
-{-# LANGUAGE ImplicitParams #-}
module TyCoRep (
TyThing(..), tyThingCategory, pprTyThingCategory, pprShortTyThing,
@@ -62,10 +61,12 @@ module TyCoRep (
pprTyVar, pprTyVars,
pprThetaArrowTy, pprClassPred,
pprKind, pprParendKind, pprTyLit,
- TyPrec(..), maybeParen, pprTcAppCo,
+ TyPrec(..), maybeParen,
pprPrefixApp, pprArrowChain,
pprDataCons, ppSuggestExplicitKinds,
+ pprCo, pprParendCo,
+
-- * Free variables
tyCoVarsOfType, tyCoVarsOfTypeDSet, tyCoVarsOfTypes, tyCoVarsOfTypesDSet,
tyCoFVsBndr, tyCoFVsOfType, tyCoVarsOfTypeList,
@@ -93,7 +94,7 @@ module TyCoRep (
extendTCvInScope, extendTCvInScopeList, extendTCvInScopeSet,
extendTCvSubst,
extendCvSubst, extendCvSubstWithClone,
- extendTvSubst, extendTvSubstBinder, extendTvSubstWithClone,
+ extendTvSubst, extendTvSubstBinderAndInScope, extendTvSubstWithClone,
extendTvSubstList, extendTvSubstAndInScope,
unionTCvSubst, zipTyEnv, zipCoEnv, mkTyCoInScopeSet,
zipTvSubst, zipCvSubst,
@@ -137,15 +138,16 @@ import {-# SOURCE #-} DataCon( dataConFullSig
, dataConUnivTyVarBinders, dataConExTyVarBinders
, DataCon, filterEqSpec )
import {-# SOURCE #-} Type( isPredTy, isCoercionTy, mkAppTy, mkCastTy
- , tyCoVarsOfTypesWellScoped
, tyCoVarsOfTypeWellScoped
+ , tyCoVarsOfTypesWellScoped
+ , toposortTyVars
, coreView, typeKind )
-- Transitively pulls in a LOT of stuff, better to break the loop
import {-# SOURCE #-} Coercion
import {-# SOURCE #-} ConLike ( ConLike(..), conLikeName )
import {-# SOURCE #-} ToIface( toIfaceTypeX, toIfaceTyLit, toIfaceForAllBndr
- , toIfaceTyCon, toIfaceTcArgs, toIfaceCoercion )
+ , toIfaceTyCon, toIfaceTcArgs, toIfaceCoercionX )
-- friends:
import IfaceType
@@ -457,28 +459,38 @@ words, if `x` is either a function or a polytype, `x arg` makes sense
(for an appropriate `arg`).
-Note [TyBinders and ArgFlags]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A ForAllTy contains a TyVarBinder. Each TyVarBinder is equipped
-with a ArgFlag, which says whether or not arguments for this
-binder should be visible (explicit) in source Haskell.
-
------------------------------------------------------------------------
- Occurrences look like this
- TyBinder GHC displays type as in Haskell souce code
------------------------------------------------------------------------
-In the type of a term
- Anon: f :: type -> type Arg required: f x
- Named Inferred: f :: forall {a}. type Arg not allowed: f
- Named Specified: f :: forall a. type Arg optional: f or f @Int
- Named Required: Illegal: See Note [No Required TyBinder in terms]
-
-In the kind of a type
- Anon: T :: kind -> kind Required: T *
- Named Inferred: T :: forall {k}. kind Arg not allowed: T
- Named Specified: T :: forall k. kind Arg not allowed[1]: T
- Named Required: T :: forall k -> kind Required: T *
-------------------------------------------------------------------------
+Note [TyVarBndrs, TyVarBinders, TyConBinders, and visiblity]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* A ForAllTy (used for both types and kinds) contains a TyVarBinder.
+ Each TyVarBinder
+ TvBndr a tvis
+ is equipped with tvis::ArgFlag, which says whether or not arguments
+ for this binder should be visible (explicit) in source Haskell.
+
+* A TyCon contains a list of TyConBinders. Each TyConBinder
+ TvBndr a cvis
+ is equipped with cvis::TyConBndrVis, which says whether or not type
+ and kind arguments for this TyCon should be visible (explicit) in
+ source Haskell.
+
+This table summarises the visiblity rules:
+---------------------------------------------------------------------------------------
+| Occurrences look like this
+| GHC displays type as in Haskell source code
+|-----------------------------------------------------------------------
+| TvBndr a tvis :: TyVarBinder, in the binder of ForAllTy for a term
+| tvis :: ArgFlag
+| tvis = Inferred: f :: forall {a}. type Arg not allowed: f
+| tvis = Specified: f :: forall a. type Arg optional: f or f @Int
+| tvis = Required: Illegal: See Note [No Required TyBinder in terms]
+|
+| TvBndr k cvis :: TyConBinder, in the TyConBinders of a TyCon
+| cvis :: TyConBndrVis
+| cvis = AnonTCB: T :: kind -> kind Required: T *
+| cvis = NamedTCB Inferred: T :: forall {k}. kind Arg not allowed: T
+| cvis = NamedTCB Specified: T :: forall k. kind Arg not allowed[1]: T
+| cvis = NamedTCB Required: T :: forall k -> kind Required: T *
+---------------------------------------------------------------------------------------
[1] In types, in the Specified case, it would make sense to allow
optional kind applications, thus (T @*), but we have not
@@ -1835,10 +1847,10 @@ extendTvSubst :: TCvSubst -> TyVar -> Type -> TCvSubst
extendTvSubst (TCvSubst in_scope tenv cenv) tv ty
= TCvSubst in_scope (extendVarEnv tenv tv ty) cenv
-extendTvSubstBinder :: TCvSubst -> TyBinder -> Type -> TCvSubst
-extendTvSubstBinder subst (Named bndr) ty
- = extendTvSubst subst (binderVar bndr) ty
-extendTvSubstBinder subst (Anon _) _
+extendTvSubstBinderAndInScope :: TCvSubst -> TyBinder -> Type -> TCvSubst
+extendTvSubstBinderAndInScope subst (Named bndr) ty
+ = extendTvSubstAndInScope subst (binderVar bndr) ty
+extendTvSubstBinderAndInScope subst (Anon _) _
= subst
extendTvSubstWithClone :: TCvSubst -> TyVar -> TyVar -> TCvSubst
@@ -2435,7 +2447,7 @@ pprType = pprPrecType TopPrec
pprParendType = pprPrecType TyConPrec
pprPrecType :: TyPrec -> Type -> SDoc
-pprPrecType prec ty = pprPrecIfaceType prec (tidyToIfaceType ty)
+pprPrecType prec ty = getPprStyle $ \sty -> pprPrecIfaceType prec (tidyToIfaceTypeSty ty sty)
pprTyLit :: TyLit -> SDoc
pprTyLit = pprIfaceTyLit . toIfaceTyLit
@@ -2444,6 +2456,12 @@ pprKind, pprParendKind :: Kind -> SDoc
pprKind = pprType
pprParendKind = pprParendType
+tidyToIfaceTypeSty :: Type -> PprStyle -> IfaceType
+tidyToIfaceTypeSty ty sty
+ | userStyle sty = tidyToIfaceType ty
+ | otherwise = toIfaceTypeX (tyCoVarsOfType ty) ty
+ -- in latter case, don't tidy, as we'll be printing uniques.
+
tidyToIfaceType :: Type -> IfaceType
-- It's vital to tidy before converting to an IfaceType
-- or nested binders will become indistinguishable!
@@ -2457,6 +2475,29 @@ tidyToIfaceType ty = toIfaceTypeX (mkVarSet free_tcvs) (tidyType env ty)
free_tcvs = tyCoVarsOfTypeWellScoped ty
------------
+pprCo, pprParendCo :: Coercion -> SDoc
+pprCo co = getPprStyle $ \ sty -> pprIfaceCoercion (tidyToIfaceCoSty co sty)
+pprParendCo co = getPprStyle $ \ sty -> pprParendIfaceCoercion (tidyToIfaceCoSty co sty)
+
+tidyToIfaceCoSty :: Coercion -> PprStyle -> IfaceCoercion
+tidyToIfaceCoSty co sty
+ | userStyle sty = tidyToIfaceCo co
+ | otherwise = toIfaceCoercionX (tyCoVarsOfCo co) co
+ -- in latter case, don't tidy, as we'll be printing uniques.
+
+tidyToIfaceCo :: Coercion -> IfaceCoercion
+-- It's vital to tidy before converting to an IfaceType
+-- or nested binders will become indistinguishable!
+--
+-- Also for the free type variables, tell toIfaceCoercionX to
+-- leave them as IfaceFreeCoVar. This is super-important
+-- for debug printing.
+tidyToIfaceCo co = toIfaceCoercionX (mkVarSet free_tcvs) (tidyCo env co)
+ where
+ env = tidyFreeTyCoVars emptyTidyEnv free_tcvs
+ free_tcvs = toposortTyVars $ tyCoVarsOfCoList co
+
+------------
pprClassPred :: Class -> [Type] -> SDoc
pprClassPred clas tys = pprTypeApp (classTyCon clas) tys
@@ -2580,11 +2621,6 @@ pprTypeApp tc tys
(toIfaceTcArgs tc tys)
-- TODO: toIfaceTcArgs seems rather wasteful here
-pprTcAppCo :: TyPrec -> (TyPrec -> Coercion -> SDoc)
- -> TyCon -> [Coercion] -> SDoc
-pprTcAppCo p _pp tc cos
- = pprIfaceCoTcApp p (toIfaceTyCon tc) (map toIfaceCoercion cos)
-
------------------
pprPrefixApp :: TyPrec -> SDoc -> [SDoc] -> SDoc
diff --git a/compiler/types/TyCon.hs b/compiler/types/TyCon.hs
index 1be318d96a..95207c493b 100644
--- a/compiler/types/TyCon.hs
+++ b/compiler/types/TyCon.hs
@@ -94,7 +94,7 @@ module TyCon(
newTyConDataCon_maybe,
algTcFields,
tyConRuntimeRepInfo,
- tyConBinders, tyConResKind,
+ tyConBinders, tyConResKind, tyConTyVarBinders,
tcTyConScopedTyVars,
-- ** Manipulating TyCons
@@ -222,7 +222,10 @@ See also Note [Wrappers for data instance tycons] in MkId.hs
DataFamInstTyCon T [Int] ax_ti
* The axiom ax_ti may be eta-reduced; see
- Note [Eta reduction for data family axioms] in TcInstDcls
+ Note [Eta reduction for data family axioms] in FamInstEnv
+
+* Data family instances may have a different arity than the data family.
+ See Note [Arity of data families] in FamInstEnv
* The data constructor T2 has a wrapper (which is what the
source-level "T2" invokes):
@@ -428,6 +431,72 @@ mkTyConKind bndrs res_kind = foldr mk res_kind bndrs
mk (TvBndr tv AnonTCB) k = mkFunKind (tyVarKind tv) k
mk (TvBndr tv (NamedTCB vis)) k = mkForAllKind tv vis k
+tyConTyVarBinders :: [TyConBinder] -- From the TyCon
+ -> [TyVarBinder] -- Suitable for the foralls of a term function
+-- See Note [Building TyVarBinders from TyConBinders]
+tyConTyVarBinders tc_bndrs
+ = map mk_binder tc_bndrs
+ where
+ mk_binder (TvBndr tv tc_vis) = mkTyVarBinder vis tv
+ where
+ vis = case tc_vis of
+ AnonTCB -> Specified
+ NamedTCB Required -> Specified
+ NamedTCB vis -> vis
+
+{- Note [Building TyVarBinders from TyConBinders]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We sometimes need to build the quantified type of a value from
+the TyConBinders of a type or class. For that we need not
+TyConBinders but TyVarBinders (used in forall-type) E.g:
+
+ * From data T a = MkT (Maybe a)
+ we are going to make a data constructor with type
+ MkT :: forall a. Maybe a -> T a
+ See the TyVarBinders passed to buildDataCon
+
+ * From class C a where { op :: a -> Maybe a }
+ we are going to make a default method
+ $dmop :: forall a. C a => a -> Maybe a
+ See the TyVarBindres passed to mkSigmaTy in mkDefaultMethodType
+
+Both of these are user-callable. (NB: default methods are not callable
+directly by the user but rather via the code generated by 'deriving',
+which uses visible type application; see mkDefMethBind.)
+
+Since they are user-callable we must get their type-argument visibility
+information right; and that info is in the TyConBinders.
+Here is an example:
+
+ data App a b = MkApp (a b) -- App :: forall {k}. (k->*) -> k -> *
+
+The TyCon has
+
+ tyConTyBinders = [ Named (TvBndr (k :: *) Inferred), Anon (k->*), Anon k ]
+
+The TyConBinders for App line up with App's kind, given above.
+
+But the DataCon MkApp has the type
+ MkApp :: forall {k} (a:k->*) (b:k). a b -> App k a b
+
+That is, its TyVarBinders should be
+
+ dataConUnivTyVarBinders = [ TvBndr (k:*) Inferred
+ , TvBndr (a:k->*) Specified
+ , TvBndr (b:k) Specified ]
+
+So tyConTyVarBinders converts TyCon's TyConBinders into TyVarBinders:
+ - variable names from the TyConBinders
+ - but changing Anon/Required to Specified
+
+The last part about Required->Specified comes from this:
+ data T k (a:k) b = MkT (a b)
+Here k is Required in T's kind, but we don't have Required binders in
+the TyBinders for a term (see Note [No Required TyBinder in terms]
+in TyCoRep), so we change it to Specified when making MkT's TyBinders
+-}
+
+
{- Note [The binders/kind/arity fields of a TyCon]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All TyCons have this group of fields
@@ -451,8 +520,8 @@ They fit together like so:
Note that that are three binders here, including the
kind variable k.
- See Note [TyBinders and ArgFlags] in TyCoRep for what
- the visibility flag means.
+- See Note [TyVarBndrs, TyVarBinders, TyConBinders, and visibility] in TyCoRep
+ for what the visibility flag means.
* Each TyConBinder tyConBinders has a TyVar, and that TyVar may
scope over some other part of the TyCon's definition. Eg
@@ -874,7 +943,8 @@ data AlgTyConFlav
-- use the tyConTyVars of this TyCon
TyCon -- The family TyCon
[Type] -- Argument types (mentions the tyConTyVars of this TyCon)
- -- Match in length the tyConTyVars of the family TyCon
+ -- No shorter in length than the tyConTyVars of the family TyCon
+ -- How could it be longer? See [Arity of data families] in FamInstEnv
-- E.g. data instance T [a] = ...
-- gives a representation tycon:
@@ -895,7 +965,7 @@ okParent :: Name -> AlgTyConFlav -> Bool
okParent _ (VanillaAlgTyCon {}) = True
okParent _ (UnboxedAlgTyCon {}) = True
okParent tc_name (ClassTyCon cls _) = tc_name == tyConName (classTyCon cls)
-okParent _ (DataFamInstTyCon _ fam_tc tys) = tys `lengthIs` tyConArity fam_tc
+okParent _ (DataFamInstTyCon _ fam_tc tys) = tys `lengthAtLeast` tyConArity fam_tc
isNoParent :: AlgTyConFlav -> Bool
isNoParent (VanillaAlgTyCon {}) = True
@@ -2038,6 +2108,10 @@ expandSynTyCon_maybe tc tys
-- | Check if the tycon actually refers to a proper `data` or `newtype`
-- with user defined constructors rather than one from a class or other
-- construction.
+
+-- NB: This is only used in TcRnExports.checkPatSynParent to determine if an
+-- exported tycon can have a pattern synonym bundled with it, e.g.,
+-- module Foo (TyCon(.., PatSyn)) where
isTyConWithSrcDataCons :: TyCon -> Bool
isTyConWithSrcDataCons (AlgTyCon { algTcRhs = rhs, algTcParent = parent }) =
case rhs of
@@ -2047,6 +2121,8 @@ isTyConWithSrcDataCons (AlgTyCon { algTcRhs = rhs, algTcParent = parent }) =
_ -> False
where
isSrcParent = isNoParent parent
+isTyConWithSrcDataCons (FamilyTyCon { famTcFlav = DataFamilyTyCon {} })
+ = True -- #14058
isTyConWithSrcDataCons _ = False
diff --git a/compiler/types/Type.hs b/compiler/types/Type.hs
index 8621e6cd52..f43e0e0b56 100644
--- a/compiler/types/Type.hs
+++ b/compiler/types/Type.hs
@@ -110,7 +110,7 @@ module Type (
-- (Lifting and boxity)
isLiftedType_maybe, isUnliftedType, isUnboxedTupleType, isUnboxedSumType,
- isAlgType, isClosedAlgType, isDataFamilyAppType,
+ isAlgType, isDataFamilyAppType,
isPrimitiveType, isStrictType,
isRuntimeRepTy, isRuntimeRepVar, isRuntimeRepKindedTy,
dropRuntimeRepArgs,
@@ -166,7 +166,7 @@ module Type (
zapTCvSubst, getTCvInScope, getTCvSubstRangeFVs,
extendTCvInScope, extendTCvInScopeList, extendTCvInScopeSet,
extendTCvSubst, extendCvSubst,
- extendTvSubst, extendTvSubstBinder,
+ extendTvSubst, extendTvSubstBinderAndInScope,
extendTvSubstList, extendTvSubstAndInScope,
extendTvSubstWithClone,
isInScope, composeTCvSubstEnv, composeTCvSubst, zipTyEnv, zipCoEnv,
@@ -615,8 +615,8 @@ getTyVar_maybe ty | Just ty' <- coreView ty = getTyVar_maybe ty'
| otherwise = repGetTyVar_maybe ty
-- | If the type is a tyvar, possibly under a cast, returns it, along
--- with the coercion. Thus, the co is :: kind tv ~R kind type
-getCastedTyVar_maybe :: Type -> Maybe (TyVar, Coercion)
+-- with the coercion. Thus, the co is :: kind tv ~N kind type
+getCastedTyVar_maybe :: Type -> Maybe (TyVar, CoercionN)
getCastedTyVar_maybe ty | Just ty' <- coreView ty = getCastedTyVar_maybe ty'
getCastedTyVar_maybe (CastTy (TyVarTy tv) co) = Just (tv, co)
getCastedTyVar_maybe (TyVarTy tv)
@@ -789,7 +789,7 @@ splitAppTys ty = split ty ty []
split orig_ty _ args = (orig_ty, args)
-- | Like 'splitAppTys', but doesn't look through type synonyms
-repSplitAppTys :: Type -> (Type, [Type])
+repSplitAppTys :: HasDebugCallStack => Type -> (Type, [Type])
repSplitAppTys ty = split ty []
where
split (AppTy ty arg) args = split ty (arg:args)
@@ -943,7 +943,7 @@ funArgTy ty | Just ty' <- coreView ty = funArgTy ty'
funArgTy (FunTy arg _res) = arg
funArgTy ty = pprPanic "funArgTy" (ppr ty)
-piResultTy :: Type -> Type -> Type
+piResultTy :: HasDebugCallStack => Type -> Type -> Type
piResultTy ty arg = case piResultTy_maybe ty arg of
Just res -> res
Nothing -> pprPanic "piResultTy" (ppr ty $$ ppr arg)
@@ -988,7 +988,7 @@ piResultTy_maybe ty arg
-- so we pay attention to efficiency, especially in the special case
-- where there are no for-alls so we are just dropping arrows from
-- a function type/kind.
-piResultTys :: Type -> [Type] -> Type
+piResultTys :: HasDebugCallStack => Type -> [Type] -> Type
piResultTys ty [] = ty
piResultTys ty orig_args@(arg:args)
| Just ty' <- coreView ty
@@ -1315,8 +1315,12 @@ mkLamType v ty
mkLamTypes vs ty = foldr mkLamType ty vs
--- | Given a list of type-level vars and a result type, makes TyBinders, preferring
--- anonymous binders if the variable is, in fact, not dependent.
+-- | Given a list of type-level vars and a result kind,
+-- makes TyBinders, preferring anonymous binders
+-- if the variable is, in fact, not dependent.
+-- e.g. mkTyConBindersPreferAnon [(k:*),(b:k),(c:k)] (k->k)
+-- We want (k:*) Named, (a;k) Anon, (c:k) Anon
+--
-- All binders are /visible/.
mkTyConBindersPreferAnon :: [TyVar] -> Type -> [TyConBinder]
mkTyConBindersPreferAnon vars inner_ty = fst (go vars)
@@ -1486,14 +1490,6 @@ isTauTy (CoercionTy _) = False -- Not sure about this
%************************************************************************
-}
--- | Make a named binder
-mkTyVarBinder :: ArgFlag -> Var -> TyVarBinder
-mkTyVarBinder vis var = TvBndr var vis
-
--- | Make many named binders
-mkTyVarBinders :: ArgFlag -> [TyVar] -> [TyVarBinder]
-mkTyVarBinders vis = map (mkTyVarBinder vis)
-
-- | Make an anonymous binder
mkAnonBinder :: Type -> TyBinder
mkAnonBinder = Anon
@@ -1836,7 +1832,7 @@ predTypeEqRel ty
--
-- This is a deterministic sorting operation
-- (that is, doesn't depend on Uniques).
-toposortTyVars :: [TyVar] -> [TyVar]
+toposortTyVars :: [TyCoVar] -> [TyCoVar]
toposortTyVars tvs = reverse $
[ node_payload node | node <- topologicalSortG $
graphFromEdgedVerticesOrd nodes ]
@@ -2023,17 +2019,6 @@ isAlgType ty
isAlgTyCon tc
_other -> False
--- | See "Type#type_classification" for what an algebraic type is.
--- Should only be applied to /types/, as opposed to e.g. partially
--- saturated type constructors. Closed type constructors are those
--- with a fixed right hand side, as opposed to e.g. associated types
-isClosedAlgType :: Type -> Bool
-isClosedAlgType ty
- = case splitTyConApp_maybe ty of
- Just (tc, ty_args) | isAlgTyCon tc && not (isFamilyTyCon tc)
- -> ASSERT2( ty_args `lengthIs` tyConArity tc, ppr ty ) True
- _other -> False
-
-- | Check whether a type is a data family type
isDataFamilyAppType :: Type -> Bool
isDataFamilyAppType ty = case tyConAppTyCon_maybe ty of
diff --git a/compiler/types/Type.hs-boot b/compiler/types/Type.hs-boot
index 2fc251acb7..002db72cf1 100644
--- a/compiler/types/Type.hs-boot
+++ b/compiler/types/Type.hs-boot
@@ -2,7 +2,7 @@
module Type where
import TyCon
-import Var ( TyVar )
+import Var ( TyCoVar )
import {-# SOURCE #-} TyCoRep( Type, Coercion, Kind )
import Util
@@ -11,7 +11,7 @@ isCoercionTy :: Type -> Bool
mkAppTy :: Type -> Type -> Type
mkCastTy :: Type -> Coercion -> Type
-piResultTy :: Type -> Type -> Type
+piResultTy :: HasDebugCallStack => Type -> Type -> Type
typeKind :: Type -> Kind
eqType :: Type -> Type -> Bool
@@ -21,6 +21,7 @@ partitionInvisibles :: TyCon -> (a -> Type) -> [a] -> ([a], [a])
coreView :: Type -> Maybe Type
tcView :: Type -> Maybe Type
-tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]
-tyCoVarsOfTypeWellScoped :: Type -> [TyVar]
+tyCoVarsOfTypesWellScoped :: [Type] -> [TyCoVar]
+tyCoVarsOfTypeWellScoped :: Type -> [TyCoVar]
+toposortTyVars :: [TyCoVar] -> [TyCoVar]
splitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])
diff --git a/compiler/types/Unify.hs b/compiler/types/Unify.hs
index 79d0897a14..c9c78f7d19 100644
--- a/compiler/types/Unify.hs
+++ b/compiler/types/Unify.hs
@@ -42,9 +42,7 @@ import UniqFM
import UniqSet
import Control.Monad
-#if __GLASGOW_HASKELL__ > 710
import qualified Control.Monad.Fail as MonadFail
-#endif
import Control.Applicative hiding ( empty )
import qualified Control.Applicative
@@ -1050,10 +1048,8 @@ instance Alternative UM where
instance MonadPlus UM
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail.MonadFail UM where
fail _ = UM (\_ -> SurelyApart) -- failed pattern match
-#endif
initUM :: TvSubstEnv -- subst to extend
-> CvSubstEnv
diff --git a/compiler/utils/IOEnv.hs b/compiler/utils/IOEnv.hs
index 29854c51fe..5a7ccd9972 100644
--- a/compiler/utils/IOEnv.hs
+++ b/compiler/utils/IOEnv.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE CPP #-}
-
--
-- (c) The University of Glasgow 2002-2006
--
@@ -41,9 +39,7 @@ import Data.IORef ( IORef, newIORef, readIORef, writeIORef, modifyIORef,
import System.IO.Unsafe ( unsafeInterleaveIO )
import System.IO ( fixIO )
import Control.Monad
-#if __GLASGOW_HASKELL__ > 710
import qualified Control.Monad.Fail as MonadFail
-#endif
import MonadUtils
import Control.Applicative (Alternative(..))
@@ -62,11 +58,8 @@ instance Monad (IOEnv m) where
(>>) = (*>)
fail _ = failM -- Ignore the string
-#if __GLASGOW_HASKELL__ > 710
instance MonadFail.MonadFail (IOEnv m) where
fail _ = failM -- Ignore the string
-#endif
-
instance Applicative (IOEnv m) where
pure = returnM
diff --git a/compiler/utils/Json.hs b/compiler/utils/Json.hs
index 1318ce2611..ffbff50641 100644
--- a/compiler/utils/Json.hs
+++ b/compiler/utils/Json.hs
@@ -39,7 +39,7 @@ escapeJsonString = concatMap escapeChar
escapeChar '\n' = "\\n"
escapeChar '\r' = "\\r"
escapeChar '\t' = "\\t"
- escapeChar '"' = "\""
+ escapeChar '"' = "\\\""
escapeChar '\\' = "\\\\"
escapeChar c | isControl c || fromEnum c >= 0x7f = uni_esc c
escapeChar c = [c]
diff --git a/compiler/utils/ListSetOps.hs b/compiler/utils/ListSetOps.hs
index f1aa2c3755..7fa441402c 100644
--- a/compiler/utils/ListSetOps.hs
+++ b/compiler/utils/ListSetOps.hs
@@ -27,6 +27,8 @@ import Outputable
import Util
import Data.List
+import qualified Data.List.NonEmpty as NE
+import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.Set as S
getNth :: Outputable a => [a] -> Int -> a
@@ -131,19 +133,19 @@ hasNoDups xs = f [] xs
equivClasses :: (a -> a -> Ordering) -- Comparison
-> [a]
- -> [[a]]
+ -> [NonEmpty a]
-equivClasses _ [] = []
-equivClasses _ stuff@[_] = [stuff]
-equivClasses cmp items = groupBy eq (sortBy cmp items)
+equivClasses _ [] = []
+equivClasses _ [stuff] = [stuff :| []]
+equivClasses cmp items = NE.groupBy eq (sortBy cmp items)
where
eq a b = case cmp a b of { EQ -> True; _ -> False }
removeDups :: (a -> a -> Ordering) -- Comparison function
-> [a]
- -> ([a], -- List with no duplicates
- [[a]]) -- List of duplicate groups. One representative from
- -- each group appears in the first result
+ -> ([a], -- List with no duplicates
+ [NonEmpty a]) -- List of duplicate groups. One representative
+ -- from each group appears in the first result
removeDups _ [] = ([], [])
removeDups _ [x] = ([x],[])
@@ -151,12 +153,12 @@ removeDups cmp xs
= case (mapAccumR collect_dups [] (equivClasses cmp xs)) of { (dups, xs') ->
(xs', dups) }
where
- collect_dups _ [] = panic "ListSetOps: removeDups"
- collect_dups dups_so_far [x] = (dups_so_far, x)
- collect_dups dups_so_far dups@(x:_) = (dups:dups_so_far, x)
+ collect_dups :: [NonEmpty a] -> NonEmpty a -> ([NonEmpty a], a)
+ collect_dups dups_so_far (x :| []) = (dups_so_far, x)
+ collect_dups dups_so_far dups@(x :| _) = (dups:dups_so_far, x)
-findDupsEq :: (a->a->Bool) -> [a] -> [[a]]
+findDupsEq :: (a->a->Bool) -> [a] -> [NonEmpty a]
findDupsEq _ [] = []
findDupsEq eq (x:xs) | null eq_xs = findDupsEq eq xs
- | otherwise = (x:eq_xs) : findDupsEq eq neq_xs
+ | otherwise = (x :| eq_xs) : findDupsEq eq neq_xs
where (eq_xs, neq_xs) = partition (eq x) xs
diff --git a/compiler/utils/MonadUtils.hs b/compiler/utils/MonadUtils.hs
index 93a835e04e..d6fb31731e 100644
--- a/compiler/utils/MonadUtils.hs
+++ b/compiler/utils/MonadUtils.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE CPP #-}
-
-- | Utilities related to Monad and Applicative classes
-- Mostly for backwards compatibility.
@@ -34,9 +32,6 @@ import Maybes
import Control.Monad
import Control.Monad.Fix
import Control.Monad.IO.Class
-#if __GLASGOW_HASKELL__ < 800
-import Control.Monad.Trans.Error () -- for orphan `instance MonadPlus IO`
-#endif
-------------------------------------------------------------------------------
-- Lift combinators
diff --git a/compiler/utils/OrdList.hs b/compiler/utils/OrdList.hs
index 3c5b9d7380..1660090ba7 100644
--- a/compiler/utils/OrdList.hs
+++ b/compiler/utils/OrdList.hs
@@ -9,7 +9,6 @@ Provide trees (of instructions), so that lists of instructions
can be appended in linear time.
-}
-{-# LANGUAGE CPP #-}
module OrdList (
OrdList,
nilOL, isNilOL, unitOL, appOL, consOL, snocOL, concatOL, lastOL,
@@ -18,10 +17,8 @@ module OrdList (
import Outputable
-#if __GLASGOW_HASKELL__ > 710
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
-#endif
infixl 5 `appOL`
infixl 5 `snocOL`
@@ -39,10 +36,8 @@ data OrdList a
instance Outputable a => Outputable (OrdList a) where
ppr ol = ppr (fromOL ol) -- Convert to list and print that
-#if __GLASGOW_HASKELL__ > 710
instance Semigroup (OrdList a) where
(<>) = appOL
-#endif
instance Monoid (OrdList a) where
mempty = nilOL
diff --git a/compiler/utils/Outputable.hs b/compiler/utils/Outputable.hs
index 4107e5beef..bc46f2f472 100644
--- a/compiler/utils/Outputable.hs
+++ b/compiler/utils/Outputable.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP, ImplicitParams #-}
{-
(c) The University of Glasgow 2006-2012
(c) The GRASP Project, Glasgow University, 1992-1998
@@ -122,6 +121,7 @@ import Data.List (intersperse)
import GHC.Fingerprint
import GHC.Show ( showMultiLineString )
+import GHC.Stack ( callStack, prettyCallStack )
{-
************************************************************************
@@ -1130,7 +1130,8 @@ doOrDoes _ = text "do"
callStackDoc :: HasCallStack => SDoc
callStackDoc =
- hang (text "Call stack:") 4 (vcat $ map text $ lines prettyCurrentCallStack)
+ hang (text "Call stack:")
+ 4 (vcat $ map text $ lines (prettyCallStack callStack))
pprPanic :: HasCallStack => String -> SDoc -> a
-- ^ Throw an exception saying "bug in GHC"
diff --git a/compiler/utils/UniqFM.hs b/compiler/utils/UniqFM.hs
index 71a092b28e..8ea8ba4537 100644
--- a/compiler/utils/UniqFM.hs
+++ b/compiler/utils/UniqFM.hs
@@ -85,10 +85,8 @@ import qualified Data.Monoid as Mon
import qualified Data.IntSet as S
import Data.Typeable
import Data.Data
-#if __GLASGOW_HASKELL__ > 710
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
-#endif
newtype UniqFM ele = UFM (M.IntMap ele)
@@ -358,10 +356,8 @@ equalKeysUFM (UFM m1) (UFM m2) = M.keys m1 == M.keys m2
-- Instances
-#if __GLASGOW_HASKELL__ > 710
instance Semigroup (UniqFM a) where
(<>) = plusUFM
-#endif
instance Monoid (UniqFM a) where
mempty = emptyUFM
diff --git a/compiler/utils/UniqSet.hs b/compiler/utils/UniqSet.hs
index f29a1e6e1f..fcac865ea8 100644
--- a/compiler/utils/UniqSet.hs
+++ b/compiler/utils/UniqSet.hs
@@ -9,7 +9,6 @@ Based on @UniqFMs@ (as you would expect).
Basically, the things need to be in class @Uniquable@.
-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
module UniqSet (
@@ -53,9 +52,7 @@ import Data.Coerce
import Outputable
import Data.Foldable (foldl')
import Data.Data
-#if __GLASGOW_HASKELL__ >= 801
import qualified Data.Semigroup
-#endif
-- Note [UniqSet invariant]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -189,10 +186,8 @@ unsafeUFMToUniqSet = UniqSet
instance Outputable a => Outputable (UniqSet a) where
ppr = pprUniqSet ppr
-#if __GLASGOW_HASKELL__ >= 801
instance Data.Semigroup.Semigroup (UniqSet a) where
(<>) = mappend
-#endif
instance Monoid (UniqSet a) where
mempty = UniqSet mempty
UniqSet s `mappend` UniqSet t = UniqSet (s `mappend` t)
diff --git a/compiler/utils/Util.hs b/compiler/utils/Util.hs
index 35a6340fd4..6146bf0113 100644
--- a/compiler/utils/Util.hs
+++ b/compiler/utils/Util.hs
@@ -4,11 +4,6 @@
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE BangPatterns #-}
-#if __GLASGOW_HASKELL__ < 800
--- For CallStack business
-{-# LANGUAGE ImplicitParams #-}
-{-# LANGUAGE FlexibleContexts #-}
-#endif
-- | Highly random utility functions
--
@@ -124,12 +119,8 @@ module Util (
hashString,
-- * Call stacks
-#if MIN_VERSION_GLASGOW_HASKELL(7,10,2,0)
- GHC.Stack.CallStack,
-#endif
HasCallStack,
HasDebugCallStack,
- prettyCurrentCallStack,
-- * Utils for flags
OverridingBool(..),
@@ -147,7 +138,7 @@ import System.IO.Unsafe ( unsafePerformIO )
import Data.List hiding (group)
import GHC.Exts
-import qualified GHC.Stack
+import GHC.Stack (HasCallStack)
import Control.Applicative ( liftA2 )
import Control.Monad ( liftM )
@@ -1368,16 +1359,6 @@ mulHi a b = fromIntegral (r `shiftR` 32)
where r :: Int64
r = fromIntegral a * fromIntegral b
--- | A compatibility wrapper for the @GHC.Stack.HasCallStack@ constraint.
-#if __GLASGOW_HASKELL__ >= 800
-type HasCallStack = GHC.Stack.HasCallStack
-#elif MIN_VERSION_GLASGOW_HASKELL(7,10,2,0)
-type HasCallStack = (?callStack :: GHC.Stack.CallStack)
--- CallStack wasn't present in GHC 7.10.1, disable callstacks in stage 1
-#else
-type HasCallStack = (() :: Constraint)
-#endif
-
-- | A call stack constraint, but only when 'isDebugOn'.
#if defined(DEBUG)
type HasDebugCallStack = HasCallStack
@@ -1385,18 +1366,6 @@ type HasDebugCallStack = HasCallStack
type HasDebugCallStack = (() :: Constraint)
#endif
--- | Pretty-print the current callstack
-#if __GLASGOW_HASKELL__ >= 800
-prettyCurrentCallStack :: HasCallStack => String
-prettyCurrentCallStack = GHC.Stack.prettyCallStack GHC.Stack.callStack
-#elif MIN_VERSION_GLASGOW_HASKELL(7,10,2,0)
-prettyCurrentCallStack :: (?callStack :: GHC.Stack.CallStack) => String
-prettyCurrentCallStack = GHC.Stack.showCallStack ?callStack
-#else
-prettyCurrentCallStack :: HasCallStack => String
-prettyCurrentCallStack = "Call stack unavailable"
-#endif
-
data OverridingBool
= Auto
| Always
diff --git a/configure.ac b/configure.ac
index 00fae0aad0..c11910ea85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,8 +158,8 @@ if test "$WithGhc" = ""
then
AC_MSG_ERROR([GHC is required.])
fi
-FP_COMPARE_VERSIONS([$GhcVersion],[-lt],[7.10],
- [AC_MSG_ERROR([GHC version 7.10 or later is required to compile GHC.])])
+FP_COMPARE_VERSIONS([$GhcVersion],[-lt],[8.0],
+ [AC_MSG_ERROR([GHC version 8.0 or later is required to compile GHC.])])
if test `expr $GhcMinVersion % 2` = "1"
then
diff --git a/docs/core-spec/CoreSyn.ott b/docs/core-spec/CoreSyn.ott
index 578d200b6b..c42e38a980 100644
--- a/docs/core-spec/CoreSyn.ott
+++ b/docs/core-spec/CoreSyn.ott
@@ -318,7 +318,7 @@ terminals :: 'terminals_' ::=
| no_duplicates :: :: no_duplicates {{ tex \textsf{no\_duplicates } }}
| vars_of :: :: vars_of {{ tex \textsf{vars\_of } }}
| not :: :: not {{ tex \neg }}
- | isUnLiftedTyCon :: :: isUnLiftenTyCon {{ tex \textsf{isUnLiftedTyCon} }}
+ | isUnLiftedTyCon :: :: isUnLiftedTyCon {{ tex \textsf{isUnLiftedTyCon} }}
| compatibleUnBoxedTys :: :: compatibleUnBoxedTys {{ tex \textsf{compatibleUnBoxedTys} }}
| false :: :: false {{ tex \textsf{false} }}
| true :: :: true {{ tex \textsf{true} }}
diff --git a/docs/users_guide/8.4.1-notes.rst b/docs/users_guide/8.4.1-notes.rst
index 9b9d79ffd4..d3cef24c57 100644
--- a/docs/users_guide/8.4.1-notes.rst
+++ b/docs/users_guide/8.4.1-notes.rst
@@ -21,6 +21,12 @@ Full details
Language
~~~~~~~~
+- Data families have been generalised a bit: a data family declaration can now
+ end with a kind variable ``k`` instead of ``Type``. Additionally, data/newtype
+ instance no longer need to list all the patterns of the family if they don't
+ wish to; this is quite like how regular datatypes with a kind signature can omit
+ some type variables.
+
Compiler
~~~~~~~~
@@ -140,3 +146,9 @@ Template Haskell
#endif
can be used.
+
+``base`` library
+~~~~~~~~~~~~~~~~
+
+- Blank strings can now be used as values for environment variables using the
+ System.Environment.Blank module. See :ghc-ticket:`12494`
diff --git a/docs/users_guide/ffi-chap.rst b/docs/users_guide/ffi-chap.rst
index 311146c4d9..320a3a6e70 100644
--- a/docs/users_guide/ffi-chap.rst
+++ b/docs/users_guide/ffi-chap.rst
@@ -337,6 +337,12 @@ reliably re-initialise after this has happened; see :ref:`infelicities-ffi`.
don't forget the flag :ghc-flag:`-no-hs-main`, otherwise GHC
will try to link to the ``Main`` Haskell module.
+.. note::
+ On Windows hs_init treats argv as UTF8-encoded. Passing other encodings
+ might lead to unexpected results. Passing NULL as argv is valid but can
+ lead to <unknown> showing up in error messages instead of the name of the
+ executable.
+
To use ``+RTS`` flags with ``hs_init()``, we have to modify the example
slightly. By default, GHC's RTS will only accept "safe" ``+RTS`` flags (see
:ref:`options-linker`), and the :ghc-flag:`-rtsopts[=⟨none|some|all⟩]`
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index a2cc0ba269..bc09402668 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -1701,8 +1701,8 @@ example, consider these two candidate definitions of ``absurd``:
::
- data a :==: b where
- Refl :: a :==: a
+ data a :~: b where
+ Refl :: a :~: a
absurd :: True :~: False -> a
absurd x = error "absurd" -- (A)
@@ -1710,10 +1710,9 @@ example, consider these two candidate definitions of ``absurd``:
We much prefer (B). Why? Because GHC can figure out that
``(True :~: False)`` is an empty type. So (B) has no partiality and GHC
-should be able to compile with :ghc-flag:`-Wincomplete-patterns`. (Though
-the pattern match checking is not yet clever enough to do that.) On the
-other hand (A) looks dangerous, and GHC doesn't check to make sure that,
-in fact, the function can never get called.
+is able to compile with :ghc-flag:`-Wincomplete-patterns` and
+:ghc-flag:`-Werror`. On the other hand (A) looks dangerous, and GHC doesn't
+check to make sure that, in fact, the function can never get called.
.. _multi-way-if:
@@ -6772,6 +6771,11 @@ entirely optional, so that we can declare ``Array`` alternatively with ::
data family Array :: * -> *
+Unlike with ordinary data definitions, the result kind of a data family
+does not need to be ``*``: it can alternatively be a kind variable
+(with :ghc-flag:`-XPolyKinds`). Data instances' kinds must end in
+``*``, however.
+
.. _data-instance-declarations:
Data instance declarations
@@ -8347,9 +8351,9 @@ enabled).
The only way ``*`` is unordinary is in its parsing. In order to be backward
compatible, ``*`` is parsed as if it were an alphanumeric idenfifier; note
that we do not write ``Int :: (*)`` but just plain ``Int :: *``. Due to the
-bizarreness with which ``*`` is parsed-and the fact that it is the only such
-operator in GHC-there are some corner cases that are
-not handled. We are aware of two:
+bizarreness with which ``*`` is parsed--and the fact that it is the only such
+operator in GHC--there are some corner cases that are
+not handled. We are aware of three:
- In a Haskell-98-style data constructor, you must put parentheses around
``*``, like this: ::
@@ -8363,6 +8367,10 @@ not handled. We are aware of two:
Note that the keyword ``type`` there is just to disambiguate the import
from a term-level ``(*)``. (:ref:`explicit-namespaces`)
+- In an instance declaration head (the part after the word ``instance``), you
+ must parenthesize ``*``. This applies to all manners of instances, including
+ the left-hand sides of individual equations of a closed type family.
+
The ``Data.Kind`` module also exports ``Type`` as a synonym for ``*``.
Now that type synonyms work in kinds, it is conceivable that we will deprecate
``*`` when there is a good migration story for everyone to use ``Type``.
@@ -10286,6 +10294,10 @@ warnings instead of errors. Additionally, these warnings can be silenced
with the :ghc-flag:`-Wno-partial-type-signatures <-Wpartial-type-signatures>`
flag.
+However, because GHC must *infer* the type when part of a type is left
+out, it is unable to use polymorphic recursion. The same restriction
+takes place when the type signature is omitted completely.
+
.. _pts-syntax:
Syntax
diff --git a/docs/users_guide/phases.rst b/docs/users_guide/phases.rst
index cefaa8a6d1..074b9499f5 100644
--- a/docs/users_guide/phases.rst
+++ b/docs/users_guide/phases.rst
@@ -740,6 +740,15 @@ for example).
an error message. If the ``GHCRTS`` environment variable is set,
then the program will emit a warning message, ``GHCRTS`` will be
ignored, and the program will run as normal.
+
+ ``-rtsopts=ignore``
+ Disables all processing of RTS options. Unlike ``none`` this treats
+ all RTS flags appearing on the command line the same way as regular
+ arguments. (Passing them on to your program as arguments).
+ ``GHCRTS`` options will be processed normally.
+
+ ``-rtsopts=ignoreAll``
+ Same as ``ignore`` but also ignores ``GHCRTS``.
``-rtsopts=some``
[this is the default setting] Enable only the "safe" RTS
diff --git a/docs/users_guide/runtime_control.rst b/docs/users_guide/runtime_control.rst
index 422eaa2ceb..f141c323f6 100644
--- a/docs/users_guide/runtime_control.rst
+++ b/docs/users_guide/runtime_control.rst
@@ -117,8 +117,8 @@ Setting RTS options with the ``GHCRTS`` environment variable
.. envvar:: GHCRTS
- If the ``-rtsopts`` flag is set to something other than ``none`` when
- linking, RTS options are also taken from the environment variable
+ If the ``-rtsopts`` flag is set to something other than ``none`` or ``ignoreAll``
+ when linking, RTS options are also taken from the environment variable
:envvar:`GHCRTS`. For example, to set the maximum heap size to 2G
for all GHC-compiled programs (using an ``sh``\-like shell):
diff --git a/ghc.mk b/ghc.mk
index 4eb1658174..55cc1197c5 100644
--- a/ghc.mk
+++ b/ghc.mk
@@ -430,7 +430,7 @@ else # CLEANING
# programs such as GHC and ghc-pkg, that we do not assume the stage0
# compiler already has installed (or up-to-date enough).
-PACKAGES_STAGE0 = binary Cabal/Cabal hpc ghc-boot-th ghc-boot transformers template-haskell ghci
+PACKAGES_STAGE0 = binary text transformers mtl parsec Cabal/Cabal hpc ghc-boot-th ghc-boot template-haskell ghci
ifeq "$(Windows_Host)" "NO"
PACKAGES_STAGE0 += terminfo
endif
@@ -457,11 +457,17 @@ PACKAGES_STAGE1 += process
PACKAGES_STAGE1 += hpc
PACKAGES_STAGE1 += pretty
PACKAGES_STAGE1 += binary
+PACKAGES_STAGE1 += text
+PACKAGES_STAGE1 += transformers
+PACKAGES_STAGE1 += mtl
+PACKAGES_STAGE1 += parsec
+# temporary until Cabal switches to parsec mode by default
+libraries/Cabal/Cabal_dist-boot_CONFIGURE_OPTS += --flag parsec
+libraries/Cabal/Cabal_dist-install_CONFIGURE_OPTS += --flag parsec
PACKAGES_STAGE1 += Cabal/Cabal
PACKAGES_STAGE1 += ghc-boot-th
PACKAGES_STAGE1 += ghc-boot
PACKAGES_STAGE1 += template-haskell
-PACKAGES_STAGE1 += transformers
PACKAGES_STAGE1 += ghc-compact
ifeq "$(HADDOCK_DOCS)" "YES"
@@ -1264,6 +1270,7 @@ $(eval $(call sdist-ghc-file,compiler,stage2,parser,Parser,y))
$(eval $(call sdist-ghc-file,utils/hpc,dist-install,,HpcParser,y))
$(eval $(call sdist-ghc-file,utils/genprimopcode,dist,,Lexer,x))
$(eval $(call sdist-ghc-file,utils/genprimopcode,dist,,Parser,y))
+$(eval $(call sdist-ghc-file2,libraries/Cabal/Cabal,dist-install,Distribution/Parsec,Lexer,x))
.PHONY: sdist-ghc-prep
sdist-ghc-prep : sdist-ghc-prep-tree
diff --git a/ghc/hschooks.c b/ghc/hschooks.c
index 031cb02d1a..87feab370a 100644
--- a/ghc/hschooks.c
+++ b/ghc/hschooks.c
@@ -63,11 +63,9 @@ StackOverflowHook (StgWord stack_size) /* in bytes */
int main (int argc, char *argv[])
{
RtsConfig conf = defaultRtsConfig;
-#if __GLASGOW_HASKELL__ >= 711
conf.defaultsHook = defaultsHook;
conf.rts_opts_enabled = RtsOptsAll;
conf.stackOverflowHook = StackOverflowHook;
-#endif
extern StgClosure ZCMain_main_closure;
hs_main(argc, argv, &ZCMain_main_closure, conf);
diff --git a/includes/Rts.h b/includes/Rts.h
index aca24e4f28..a59a8ca432 100644
--- a/includes/Rts.h
+++ b/includes/Rts.h
@@ -211,12 +211,6 @@ DLL_IMPORT_RTS extern char **prog_argv; /* so we can get at these from Haskell *
DLL_IMPORT_RTS extern int prog_argc;
DLL_IMPORT_RTS extern char *prog_name;
-#if defined(mingw32_HOST_OS)
-// We need these two from Haskell too
-void getWin32ProgArgv(int *argc, wchar_t **argv[]);
-void setWin32ProgArgv(int argc, wchar_t *argv[]);
-#endif
-
void reportStackOverflow(StgTSO* tso);
void reportHeapOverflow(void);
diff --git a/includes/RtsAPI.h b/includes/RtsAPI.h
index 1ed5fb06f0..ca61328b7c 100644
--- a/includes/RtsAPI.h
+++ b/includes/RtsAPI.h
@@ -53,6 +53,8 @@ typedef struct CapabilityPublic_ {
typedef enum {
RtsOptsNone, // +RTS causes an error
+ RtsOptsIgnore, // Ignore command line arguments
+ RtsOptsIgnoreAll, // Ignore command line and Environment arguments
RtsOptsSafeOnly, // safe RTS options allowed; others cause an error
RtsOptsAll // all RTS options allowed
} RtsOptsEnabledEnum;
diff --git a/libraries/base/Control/Applicative.hs b/libraries/base/Control/Applicative.hs
index 559cceda66..3e531e5b15 100644
--- a/libraries/base/Control/Applicative.hs
+++ b/libraries/base/Control/Applicative.hs
@@ -107,7 +107,7 @@ newtype ZipList a = ZipList { getZipList :: [a] }
-- |
-- > f '<$>' 'ZipList' xs1 '<*>' ... '<*>' 'ZipList' xsN
--- = 'ZipList' (zipWithN f xs1 ... xsN)
+-- > = 'ZipList' (zipWithN f xs1 ... xsN)
--
-- where @zipWithN@ refers to the @zipWith@ function of the appropriate arity
-- (@zipWith@, @zipWith3@, @zipWith4@, ...). For example:
diff --git a/libraries/base/Data/Bits.hs b/libraries/base/Data/Bits.hs
index d12d6dc4bd..da2ea3d18f 100644
--- a/libraries/base/Data/Bits.hs
+++ b/libraries/base/Data/Bits.hs
@@ -57,17 +57,13 @@ module Data.Bits (
#include "MachDeps.h"
-#if defined(MIN_VERSION_integer_gmp)
-# define HAVE_INTEGER_GMP1 MIN_VERSION_integer_gmp(1,0,0)
-#endif
-
import Data.Maybe
import GHC.Enum
import GHC.Num
import GHC.Base
import GHC.Real
-#if HAVE_INTEGER_GMP1
+#if defined(MIN_VERSION_integer_gmp)
import GHC.Integer.GMP.Internals (bitInteger, popCountInteger)
#endif
@@ -526,7 +522,7 @@ instance Bits Integer where
testBit x (I# i) = testBitInteger x i
zeroBits = 0
-#if HAVE_INTEGER_GMP1
+#if defined(MIN_VERSION_integer_gmp)
bit (I# i#) = bitInteger i#
popCount x = I# (popCountInteger x)
#else
diff --git a/libraries/base/Data/Functor.hs b/libraries/base/Data/Functor.hs
index 62bb70927e..2c0fbc3f29 100644
--- a/libraries/base/Data/Functor.hs
+++ b/libraries/base/Data/Functor.hs
@@ -20,6 +20,7 @@ module Data.Functor
(<$),
($>),
(<$>),
+ (<&>),
void,
) where
@@ -74,6 +75,31 @@ infixl 4 <$>
infixl 4 $>
+-- | Flipped version of '<$>'.
+--
+-- @
+-- ('<&>') = 'flip' 'fmap'
+-- @
+--
+-- @since 4.11.0.0
+--
+-- ==== __Examples__
+-- Apply @(+1)@ to a list, a 'Data.Maybe.Just' and a 'Data.Either.Right':
+--
+-- >>> Just 2 <&> (+1)
+-- Just 3
+--
+-- >>> [1,2,3] <&> (+1)
+-- [2,3,4]
+--
+-- >>> Right 3 <&> (+1)
+-- Right 4
+--
+(<&>) :: Functor f => f a -> (a -> b) -> f b
+as <&> f = f <$> as
+
+infixl 1 <&>
+
-- | Flipped version of '<$'.
--
-- @since 4.7.0.0
diff --git a/libraries/base/Data/OldList.hs b/libraries/base/Data/OldList.hs
index bee1b6f98a..d03c0bcc96 100644
--- a/libraries/base/Data/OldList.hs
+++ b/libraries/base/Data/OldList.hs
@@ -228,8 +228,12 @@ infix 5 \\ -- comment to fool cpp: https://www.haskell.org/ghc/docs/latest/html/
-- | The 'dropWhileEnd' function drops the largest suffix of a list
-- in which the given predicate holds for all elements. For example:
--
--- > dropWhileEnd isSpace "foo\n" == "foo"
--- > dropWhileEnd isSpace "foo bar" == "foo bar"
+-- >>> dropWhileEnd isSpace "foo\n"
+-- "foo"
+--
+-- >>> dropWhileEnd isSpace "foo bar"
+-- "foo bar"
+--
-- > dropWhileEnd isSpace ("foo\n" ++ undefined) == "foo" ++ undefined
--
-- @since 4.5.0.0
@@ -240,10 +244,17 @@ dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x : xs) []
-- It returns 'Nothing' if the list did not start with the prefix
-- given, or 'Just' the list after the prefix, if it does.
--
--- > stripPrefix "foo" "foobar" == Just "bar"
--- > stripPrefix "foo" "foo" == Just ""
--- > stripPrefix "foo" "barfoo" == Nothing
--- > stripPrefix "foo" "barfoobaz" == Nothing
+-- >>> stripPrefix "foo" "foobar"
+-- Just "bar"
+--
+-- >>> stripPrefix "foo" "foo"
+-- Just ""
+--
+-- >>> stripPrefix "foo" "barfoo"
+-- Nothing
+--
+-- >>> stripPrefix "foo" "barfoobaz"
+-- Nothing
stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]
stripPrefix [] ys = Just ys
stripPrefix (x:xs) (y:ys)
@@ -253,28 +264,46 @@ stripPrefix _ _ = Nothing
-- | The 'elemIndex' function returns the index of the first element
-- in the given list which is equal (by '==') to the query element,
-- or 'Nothing' if there is no such element.
+--
+-- >>> elemIndex 4 [0..]
+-- Just 4
elemIndex :: Eq a => a -> [a] -> Maybe Int
elemIndex x = findIndex (x==)
-- | The 'elemIndices' function extends 'elemIndex', by returning the
-- indices of all elements equal to the query element, in ascending order.
+--
+-- >>> elemIndices 'o' "Hello World"
+-- [4,7]
elemIndices :: Eq a => a -> [a] -> [Int]
elemIndices x = findIndices (x==)
-- | The 'find' function takes a predicate and a list and returns the
-- first element in the list matching the predicate, or 'Nothing' if
-- there is no such element.
+--
+-- >>> find (> 4) [1..]
+-- Just 5
+--
+-- >>> find (< 0) [1..10]
+-- Nothing
find :: (a -> Bool) -> [a] -> Maybe a
find p = listToMaybe . filter p
-- | The 'findIndex' function takes a predicate and a list and returns
-- the index of the first element in the list satisfying the predicate,
-- or 'Nothing' if there is no such element.
+--
+-- >>> findIndex isSpace "Hello World!"
+-- Just 5
findIndex :: (a -> Bool) -> [a] -> Maybe Int
findIndex p = listToMaybe . findIndices p
-- | The 'findIndices' function extends 'findIndex', by returning the
-- indices of all elements satisfying the predicate, in ascending order.
+--
+-- >>> findIndices (`elem` "aeiou") "Hello World!"
+-- [1,4,7]
findIndices :: (a -> Bool) -> [a] -> [Int]
#if defined(USE_REPORT_PRELUDE)
findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
@@ -289,6 +318,12 @@ findIndices p ls = build $ \c n ->
-- | The 'isPrefixOf' function takes two lists and returns 'True'
-- iff the first list is a prefix of the second.
+--
+-- >>> "Hello" `isPrefixOf` "Hello World!"
+-- True
+--
+-- >>> "Hello" `isPrefixOf` "Wello Horld!"
+-- False
isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
isPrefixOf [] _ = True
isPrefixOf _ [] = False
@@ -297,6 +332,12 @@ isPrefixOf (x:xs) (y:ys)= x == y && isPrefixOf xs ys
-- | The 'isSuffixOf' function takes two lists and returns 'True' iff
-- the first list is a suffix of the second. The second list must be
-- finite.
+--
+-- >>> "ld!" `isSuffixOf` "Hello World!"
+-- True
+--
+-- >>> "World" `isSuffixOf` "Hello World!"
+-- False
isSuffixOf :: (Eq a) => [a] -> [a] -> Bool
ns `isSuffixOf` hs = maybe False id $ do
delta <- dropLengthMaybe ns hs
@@ -311,6 +352,12 @@ ns `isSuffixOf` hs = maybe False id $ do
-- entirety. dropLength is also generally faster than (drop . length)
-- Both this and dropLengthMaybe could be written as folds over their first
-- arguments, but this reduces clarity with no benefit to isSuffixOf.
+--
+-- >>> dropLength "Hello" "Holla world"
+-- " world"
+--
+-- >>> dropLength [1..] [1,2,3]
+-- []
dropLength :: [a] -> [b] -> [b]
dropLength [] y = y
dropLength _ [] = []
@@ -318,6 +365,9 @@ dropLength (_:x') (_:y') = dropLength x' y'
-- A version of dropLength that returns Nothing if the second list runs out of
-- elements before the first.
+--
+-- >>> dropLengthMaybe [1..] [1,2,3]
+-- Nothing
dropLengthMaybe :: [a] -> [b] -> Maybe [b]
dropLengthMaybe [] y = Just y
dropLengthMaybe _ [] = Nothing
@@ -327,10 +377,11 @@ dropLengthMaybe (_:x') (_:y') = dropLengthMaybe x' y'
-- iff the first list is contained, wholly and intact,
-- anywhere within the second.
--
--- Example:
+-- >>> isInfixOf "Haskell" "I really like Haskell."
+-- True
--
--- >isInfixOf "Haskell" "I really like Haskell." == True
--- >isInfixOf "Ial" "I really like Haskell." == False
+-- >>> isInfixOf "Ial" "I really like Haskell."
+-- False
isInfixOf :: (Eq a) => [a] -> [a] -> Bool
isInfixOf needle haystack = any (isPrefixOf needle) (tails haystack)
@@ -339,12 +390,18 @@ isInfixOf needle haystack = any (isPrefixOf needle) (tails haystack)
-- (The name 'nub' means \`essence\'.)
-- It is a special case of 'nubBy', which allows the programmer to supply
-- their own equality test.
+--
+-- >>> nub [1,2,3,4,3,2,1,2,4,3,5]
+-- [1,2,3,4,5]
nub :: (Eq a) => [a] -> [a]
nub = nubBy (==)
-- | The 'nubBy' function behaves just like 'nub', except it uses a
-- user-supplied equality predicate instead of the overloaded '=='
-- function.
+--
+-- >>> nubBy (\x y -> mod x 3 == mod y 3) [1,2,4,5,6]
+-- [1,2,6]
nubBy :: (a -> a -> Bool) -> [a] -> [a]
#if defined(USE_REPORT_PRELUDE)
nubBy eq [] = []
@@ -374,16 +431,19 @@ elem_by eq y (x:xs) = x `eq` y || elem_by eq y xs
-- | 'delete' @x@ removes the first occurrence of @x@ from its list argument.
-- For example,
--
--- > delete 'a' "banana" == "bnana"
+-- >>> delete 'a' "banana"
+-- "bnana"
--
-- It is a special case of 'deleteBy', which allows the programmer to
-- supply their own equality test.
-
delete :: (Eq a) => a -> [a] -> [a]
delete = deleteBy (==)
-- | The 'deleteBy' function behaves like 'delete', but takes a
-- user-supplied equality predicate.
+--
+-- >>> deleteBy (<=) 4 [1..10]
+-- [1,2,3,5,6,7,8,9,10]
deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
deleteBy _ _ [] = []
deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys
@@ -394,6 +454,9 @@ deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys
--
-- > (xs ++ ys) \\ xs == ys.
--
+-- >>> "Hello World!" \\ "ell W"
+-- "Hoorld!"
+--
-- It is a special case of 'deleteFirstsBy', which allows the programmer
-- to supply their own equality test.
@@ -403,7 +466,8 @@ deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys
-- | The 'union' function returns the list union of the two lists.
-- For example,
--
--- > "dog" `union` "cow" == "dogcw"
+-- >>> "dog" `union` "cow"
+-- "dogcw"
--
-- Duplicates, and elements of the first list, are removed from the
-- the second list, but if the first list contains duplicates, so will
@@ -421,11 +485,13 @@ unionBy eq xs ys = xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs
-- | The 'intersect' function takes the list intersection of two lists.
-- For example,
--
--- > [1,2,3,4] `intersect` [2,4,6,8] == [2,4]
+-- >>> [1,2,3,4] `intersect` [2,4,6,8]
+-- [2,4]
--
-- If the first list contains duplicates, so will the result.
--
--- > [1,2,2,3,4] `intersect` [6,4,4,2] == [2,2,4]
+-- >>> [1,2,2,3,4] `intersect` [6,4,4,2]
+-- [2,2,4]
--
-- It is a special case of 'intersectBy', which allows the programmer to
-- supply their own equality test. If the element is found in both the first
@@ -444,8 +510,8 @@ intersectBy eq xs ys = [x | x <- xs, any (eq x) ys]
-- \`intersperses\' that element between the elements of the list.
-- For example,
--
--- > intersperse ',' "abcde" == "a,b,c,d,e"
-
+-- >>> intersperse ',' "abcde"
+-- "a,b,c,d,e"
intersperse :: a -> [a] -> [a]
intersperse _ [] = []
intersperse sep (x:xs) = x : prependToAll sep xs
@@ -462,18 +528,22 @@ prependToAll sep (x:xs) = sep : x : prependToAll sep xs
-- | 'intercalate' @xs xss@ is equivalent to @('concat' ('intersperse' xs xss))@.
-- It inserts the list @xs@ in between the lists in @xss@ and concatenates the
-- result.
+--
+-- >>> intercalate ", " ["Lorem", "ipsum", "dolor"]
+-- "Lorem, ipsum, dolor"
intercalate :: [a] -> [[a]] -> [a]
intercalate xs xss = concat (intersperse xs xss)
-- | The 'transpose' function transposes the rows and columns of its argument.
-- For example,
--
--- > transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
+-- >>> transpose [[1,2,3],[4,5,6]]
+-- [[1,4],[2,5],[3,6]]
--
-- If some of the rows are shorter than the following rows, their elements are skipped:
--
--- > transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]]
-
+-- >>> transpose [[10,11],[20],[],[30,31,32]]
+-- [[10,20,30],[11,31],[32]]
transpose :: [[a]] -> [[a]]
transpose [] = []
transpose ([] : xss) = transpose xss
@@ -485,7 +555,9 @@ transpose ((x:xs) : xss) = (x : [h | (h:_) <- xss]) : transpose (xs : [ t | (_:t
-- predicate, respectively; i.e.,
--
-- > partition p xs == (filter p xs, filter (not . p) xs)
-
+--
+-- >>> partition (`elem` "aeiou") "Hello World!"
+-- ("eoo","Hll Wrld!")
partition :: (a -> Bool) -> [a] -> ([a],[a])
{-# INLINE partition #-}
partition p xs = foldr (select p) ([],[]) xs
@@ -549,6 +621,9 @@ mapAccumR f s (x:xs) = (s'', y:ys)
-- is sorted before the call, the result will also be sorted.
-- It is a special case of 'insertBy', which allows the programmer to
-- supply their own comparison function.
+--
+-- >>> insert 4 [1,2,3,5,6,7]
+-- [1,2,3,4,5,6,7]
insert :: Ord a => a -> [a] -> [a]
insert e ls = insertBy (compare) e ls
@@ -563,6 +638,11 @@ insertBy cmp x ys@(y:ys')
-- | The 'maximumBy' function takes a comparison function and a list
-- and returns the greatest element of the list by the comparison function.
-- The list must be finite and non-empty.
+--
+-- We can use this to find the longest entry of a list:
+--
+-- >>> maximumBy (\x y -> compare (length x) (length y)) ["Hello", "World", "!", "Longest", "bar"]
+-- "Longest"
maximumBy :: (a -> a -> Ordering) -> [a] -> a
maximumBy _ [] = errorWithoutStackTrace "List.maximumBy: empty list"
maximumBy cmp xs = foldl1 maxBy xs
@@ -574,6 +654,11 @@ maximumBy cmp xs = foldl1 maxBy xs
-- | The 'minimumBy' function takes a comparison function and a list
-- and returns the least element of the list by the comparison function.
-- The list must be finite and non-empty.
+--
+-- We can use this to find the shortest entry of a list:
+--
+-- >>> minimumBy (\x y -> compare (length x) (length y)) ["Hello", "World", "!", "Longest", "bar"]
+-- "!"
minimumBy :: (a -> a -> Ordering) -> [a] -> a
minimumBy _ [] = errorWithoutStackTrace "List.minimumBy: empty list"
minimumBy cmp xs = foldl1 minBy xs
@@ -734,7 +819,8 @@ deleteFirstsBy eq = foldl (flip (deleteBy eq))
-- that the concatenation of the result is equal to the argument. Moreover,
-- each sublist in the result contains only equal elements. For example,
--
--- > group "Mississippi" = ["M","i","ss","i","ss","i","pp","i"]
+-- >>> group "Mississippi"
+-- ["M","i","ss","i","ss","i","pp","i"]
--
-- It is a special case of 'groupBy', which allows the programmer to supply
-- their own equality test.
@@ -750,7 +836,8 @@ groupBy eq (x:xs) = (x:ys) : groupBy eq zs
-- | The 'inits' function returns all initial segments of the argument,
-- shortest first. For example,
--
--- > inits "abc" == ["","a","ab","abc"]
+-- >>> inits "abc"
+-- ["","a","ab","abc"]
--
-- Note that 'inits' has the following strictness property:
-- @inits (xs ++ _|_) = inits xs ++ _|_@
@@ -768,7 +855,8 @@ inits = map toListSB . scanl' snocSB emptySB
-- | The 'tails' function returns all final segments of the argument,
-- longest first. For example,
--
--- > tails "abc" == ["abc", "bc", "c",""]
+-- >>> tails "abc"
+-- ["abc","bc","c",""]
--
-- Note that 'tails' has the following strictness property:
-- @tails _|_ = _|_ : _|_@
@@ -782,14 +870,16 @@ tails lst = build (\c n ->
-- | The 'subsequences' function returns the list of all subsequences of the argument.
--
--- > subsequences "abc" == ["","a","b","ab","c","ac","bc","abc"]
+-- >>> subsequences "abc"
+-- ["","a","b","ab","c","ac","bc","abc"]
subsequences :: [a] -> [[a]]
subsequences xs = [] : nonEmptySubsequences xs
-- | The 'nonEmptySubsequences' function returns the list of all subsequences of the argument,
-- except for the empty list.
--
--- > nonEmptySubsequences "abc" == ["a","b","ab","c","ac","bc","abc"]
+-- >>> nonEmptySubsequences "abc"
+-- ["a","b","ab","c","ac","bc","abc"]
nonEmptySubsequences :: [a] -> [[a]]
nonEmptySubsequences [] = []
nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs)
@@ -798,7 +888,8 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs)
-- | The 'permutations' function returns the list of all permutations of the argument.
--
--- > permutations "abc" == ["abc","bac","cba","bca","cab","acb"]
+-- >>> permutations "abc"
+-- ["abc","bac","cba","bca","cab","acb"]
permutations :: [a] -> [[a]]
permutations xs0 = xs0 : perms xs0 []
where
@@ -819,9 +910,15 @@ permutations xs0 = xs0 : perms xs0 []
--
-- Elements are arranged from from lowest to highest, keeping duplicates in
-- the order they appeared in the input.
+--
+-- >>> sort [1,6,4,3,2,5]
+-- [1,2,3,4,5,6]
sort :: (Ord a) => [a] -> [a]
-- | The 'sortBy' function is the non-overloaded version of 'sort'.
+--
+-- >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")]
+-- [(1,"Hello"),(2,"world"),(4,"!")]
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
#if defined(USE_REPORT_PRELUDE)
@@ -987,6 +1084,9 @@ rqpart cmp x (y:ys) rle rgt r =
-- Elements are arranged from from lowest to highest, keeping duplicates in
-- the order they appeared in the input.
--
+-- >>> sortOn fst [(2, "world"), (4, "!"), (1, "Hello")]
+-- [(1,"Hello"),(2,"world"),(4,"!")]
+--
-- @since 4.8.0.0
sortOn :: Ord b => (a -> b) -> [a] -> [a]
sortOn f =
@@ -1012,8 +1112,8 @@ sortOn f =
--
-- A simple use of unfoldr:
--
--- > unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10
--- > [10,9,8,7,6,5,4,3,2,1]
+-- >>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10
+-- [10,9,8,7,6,5,4,3,2,1]
--
-- Note [INLINE unfoldr]
@@ -1058,13 +1158,26 @@ unfoldr f b0 = build (\c n ->
-- last part of the string is considered a line even if it doesn't end
-- with a newline. For example,
--
--- > lines "" == []
--- > lines "\n" == [""]
--- > lines "one" == ["one"]
--- > lines "one\n" == ["one"]
--- > lines "one\n\n" == ["one",""]
--- > lines "one\ntwo" == ["one","two"]
--- > lines "one\ntwo\n" == ["one","two"]
+-- >>> lines ""
+-- []
+--
+-- >>> lines "\n"
+-- [""]
+--
+-- >>> lines "one"
+-- ["one"]
+--
+-- >>> lines "one\n"
+-- ["one"]
+--
+-- >>> lines "one\n\n"
+-- ["one",""]
+--
+-- >>> lines "one\ntwo"
+-- ["one","two"]
+--
+-- >>> lines "one\ntwo\n"
+-- ["one","two"]
--
-- Thus @'lines' s@ contains at least as many elements as newlines in @s@.
lines :: String -> [String]
@@ -1082,6 +1195,9 @@ lines s = cons (case break (== '\n') s of
-- | 'unlines' is an inverse operation to 'lines'.
-- It joins lines, after appending a terminating newline to each.
+--
+-- >>> unlines ["Hello", "World", "!"]
+-- "Hello\nWorld\n!\n"
unlines :: [String] -> String
#if defined(USE_REPORT_PRELUDE)
unlines = concatMap (++ "\n")
@@ -1094,6 +1210,9 @@ unlines (l:ls) = l ++ '\n' : unlines ls
-- | 'words' breaks a string up into a list of words, which were delimited
-- by white space.
+--
+-- >>> words "Lorem ipsum\ndolor"
+-- ["Lorem","ipsum","dolor"]
words :: String -> [String]
{-# NOINLINE [1] words #-}
words s = case dropWhile {-partain:Char.-}isSpace s of
@@ -1117,6 +1236,9 @@ wordsFB c n = go
-- | 'unwords' is an inverse operation to 'words'.
-- It joins words with separating spaces.
+--
+-- >>> unwords ["Lorem", "ipsum", "dolor"]
+-- "Lorem ipsum dolor"
unwords :: [String] -> String
#if defined(USE_REPORT_PRELUDE)
unwords [] = ""
diff --git a/libraries/base/Data/Typeable.hs b/libraries/base/Data/Typeable.hs
index 6157e82b1f..61b70cfd2e 100644
--- a/libraries/base/Data/Typeable.hs
+++ b/libraries/base/Data/Typeable.hs
@@ -86,8 +86,6 @@ module Data.Typeable
-- * For backwards compatibility
, typeOf1, typeOf2, typeOf3, typeOf4, typeOf5, typeOf6, typeOf7
- , Typeable1, Typeable2, Typeable3, Typeable4
- , Typeable5, Typeable6, Typeable7
) where
import qualified Data.Typeable.Internal as I
@@ -225,19 +223,3 @@ typeOf6 _ = I.someTypeRep (Proxy :: Proxy t)
typeOf7 :: forall t (a :: *) (b :: *) (c :: *) (d :: *) (e :: *) (f :: *)
(g :: *). Typeable t => t a b c d e f g -> TypeRep
typeOf7 _ = I.someTypeRep (Proxy :: Proxy t)
-
-type Typeable1 (a :: * -> *) = Typeable a
-type Typeable2 (a :: * -> * -> *) = Typeable a
-type Typeable3 (a :: * -> * -> * -> *) = Typeable a
-type Typeable4 (a :: * -> * -> * -> * -> *) = Typeable a
-type Typeable5 (a :: * -> * -> * -> * -> * -> *) = Typeable a
-type Typeable6 (a :: * -> * -> * -> * -> * -> * -> *) = Typeable a
-type Typeable7 (a :: * -> * -> * -> * -> * -> * -> * -> *) = Typeable a
-
-{-# DEPRECATED Typeable1 "renamed to 'Typeable'" #-} -- deprecated in 7.8
-{-# DEPRECATED Typeable2 "renamed to 'Typeable'" #-} -- deprecated in 7.8
-{-# DEPRECATED Typeable3 "renamed to 'Typeable'" #-} -- deprecated in 7.8
-{-# DEPRECATED Typeable4 "renamed to 'Typeable'" #-} -- deprecated in 7.8
-{-# DEPRECATED Typeable5 "renamed to 'Typeable'" #-} -- deprecated in 7.8
-{-# DEPRECATED Typeable6 "renamed to 'Typeable'" #-} -- deprecated in 7.8
-{-# DEPRECATED Typeable7 "renamed to 'Typeable'" #-} -- deprecated in 7.8
diff --git a/libraries/base/GHC/Environment.hs b/libraries/base/GHC/Environment.hs
index a077f6f8c4..0270aedf55 100644
--- a/libraries/base/GHC/Environment.hs
+++ b/libraries/base/GHC/Environment.hs
@@ -8,11 +8,10 @@ import Foreign
import Foreign.C
import GHC.Base
import GHC.Real ( fromIntegral )
+import GHC.IO.Encoding
+import qualified GHC.Foreign as GHC
#if defined(mingw32_HOST_OS)
-import GHC.IO (finally)
-import GHC.Windows
-
# if defined(i386_HOST_ARCH)
# define WINDOWS_CCONV stdcall
# elif defined(x86_64_HOST_ARCH)
@@ -20,9 +19,6 @@ import GHC.Windows
# else
# error Unknown mingw32 arch
# endif
-#else
-import GHC.IO.Encoding
-import qualified GHC.Foreign as GHC
#endif
-- | Computation 'getFullArgs' is the "raw" version of 'getArgs', similar
@@ -30,37 +26,14 @@ import qualified GHC.Foreign as GHC
-- command line arguments, starting with the program name, and
-- including those normally eaten by the RTS (+RTS ... -RTS).
getFullArgs :: IO [String]
-#if defined(mingw32_HOST_OS)
--- Ignore the arguments to hs_init on Windows for the sake of Unicode compat
getFullArgs = do
- p_arg_string <- c_GetCommandLine
- alloca $ \p_argc -> do
- p_argv <- c_CommandLineToArgv p_arg_string p_argc
- if p_argv == nullPtr
- then throwGetLastError "getFullArgs"
- else flip finally (c_LocalFree p_argv) $ do
- argc <- peek p_argc
- p_argvs <- peekArray (fromIntegral argc) p_argv
- mapM peekCWString p_argvs
-
-foreign import WINDOWS_CCONV unsafe "windows.h GetCommandLineW"
- c_GetCommandLine :: IO (Ptr CWString)
-
-foreign import WINDOWS_CCONV unsafe "windows.h CommandLineToArgvW"
- c_CommandLineToArgv :: Ptr CWString -> Ptr CInt -> IO (Ptr CWString)
-
-foreign import WINDOWS_CCONV unsafe "Windows.h LocalFree"
- c_LocalFree :: Ptr a -> IO (Ptr a)
-#else
-getFullArgs =
- alloca $ \ p_argc ->
- alloca $ \ p_argv -> do
- getFullProgArgv p_argc p_argv
- p <- fromIntegral `liftM` peek p_argc
- argv <- peek p_argv
- enc <- getFileSystemEncoding
- peekArray p argv >>= mapM (GHC.peekCString enc)
+ alloca $ \ p_argc -> do
+ alloca $ \ p_argv -> do
+ getFullProgArgv p_argc p_argv
+ p <- fromIntegral `liftM` peek p_argc
+ argv <- peek p_argv
+ enc <- argvEncoding
+ peekArray p argv >>= mapM (GHC.peekCString enc)
foreign import ccall unsafe "getFullProgArgv"
getFullProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
-#endif
diff --git a/libraries/base/GHC/IO/Encoding.hs b/libraries/base/GHC/IO/Encoding.hs
index 578a420faf..daff97e560 100644
--- a/libraries/base/GHC/IO/Encoding.hs
+++ b/libraries/base/GHC/IO/Encoding.hs
@@ -27,6 +27,7 @@ module GHC.IO.Encoding (
setLocaleEncoding, setFileSystemEncoding, setForeignEncoding,
char8,
mkTextEncoding,
+ argvEncoding
) where
import GHC.Base
@@ -161,6 +162,17 @@ initFileSystemEncoding = CodePage.mkLocaleEncoding RoundtripFailure
initForeignEncoding = CodePage.mkLocaleEncoding IgnoreCodingFailure
#endif
+-- See Note [Windows Unicode Arguments] in rts/RtsFlags.c
+-- On Windows we assume hs_init argv is in utf8 encoding.
+
+-- | Internal encoding of argv
+argvEncoding :: IO TextEncoding
+#if defined(mingw32_HOST_OS)
+argvEncoding = return utf8
+#else
+argvEncoding = getFileSystemEncoding
+#endif
+
-- | An encoding in which Unicode code points are translated to bytes
-- by taking the code point modulo 256. When decoding, bytes are
-- translated directly into the equivalent code point.
diff --git a/libraries/base/GHC/Natural.hs b/libraries/base/GHC/Natural.hs
index 0e5abc77bc..13560850af 100644
--- a/libraries/base/GHC/Natural.hs
+++ b/libraries/base/GHC/Natural.hs
@@ -47,16 +47,10 @@ module GHC.Natural
#include "MachDeps.h"
-#if defined(MIN_VERSION_integer_gmp)
-# define HAVE_GMP_BIGNAT MIN_VERSION_integer_gmp(1,0,0)
-#else
-# define HAVE_GMP_BIGNAT 0
-#endif
-
import GHC.Arr
import GHC.Base
import {-# SOURCE #-} GHC.Exception (underflowException)
-#if HAVE_GMP_BIGNAT
+#if defined(MIN_VERSION_integer_gmp)
import GHC.Integer.GMP.Internals
import Data.Word
import Data.Int
@@ -87,7 +81,7 @@ underflowError = raise# underflowException
-- Natural type
-------------------------------------------------------------------------------
-#if HAVE_GMP_BIGNAT
+#if defined(MIN_VERSION_integer_gmp)
-- TODO: if saturated arithmetic is to used, replace 'underflowError' by '0'
-- | Type representing arbitrary-precision non-negative integers.
@@ -450,7 +444,7 @@ naturalToInt :: Natural -> Int
naturalToInt (NatS# w#) = I# (word2Int# w#)
naturalToInt (NatJ# bn) = I# (bigNatToInt bn)
-#else /* !HAVE_GMP_BIGNAT */
+#else /* !defined(MIN_VERSION_integer_gmp) */
----------------------------------------------------------------------------
-- Use wrapped 'Integer' as fallback; taken from Edward Kmett's nats package
@@ -606,7 +600,7 @@ instance Integral Natural where
--
-- @since 4.8.0.0
wordToNatural :: Word -> Natural
-#if HAVE_GMP_BIGNAT
+#if defined(MIN_VERSION_integer_gmp)
wordToNatural (W# w#) = NatS# w#
#else
wordToNatural w = Natural (fromIntegral w)
@@ -617,7 +611,7 @@ wordToNatural w = Natural (fromIntegral w)
--
-- @since 4.8.0.0
naturalToWordMaybe :: Natural -> Maybe Word
-#if HAVE_GMP_BIGNAT
+#if defined(MIN_VERSION_integer_gmp)
naturalToWordMaybe (NatS# w#) = Just (W# w#)
naturalToWordMaybe (NatJ# _) = Nothing
#else
@@ -633,7 +627,7 @@ naturalToWordMaybe (Natural i)
--
-- @since 4.8.0.0
powModNatural :: Natural -> Natural -> Natural -> Natural
-#if HAVE_GMP_BIGNAT
+#if defined(MIN_VERSION_integer_gmp)
powModNatural _ _ (NatS# 0##) = divZeroError
powModNatural _ _ (NatS# 1##) = NatS# 0##
powModNatural _ (NatS# 0##) _ = NatS# 1##
diff --git a/libraries/base/GHC/Real.hs b/libraries/base/GHC/Real.hs
index 1154091dd5..6206598e39 100644
--- a/libraries/base/GHC/Real.hs
+++ b/libraries/base/GHC/Real.hs
@@ -646,7 +646,6 @@ lcm x y = abs ((x `quot` (gcd x y)) * y)
gcdInt' :: Int -> Int -> Int
gcdInt' (I# x) (I# y) = I# (gcdInt x y)
-#if MIN_VERSION_integer_gmp(1,0,0)
{-# RULES
"gcd/Word->Word->Word" gcd = gcdWord'
#-}
@@ -654,7 +653,6 @@ gcdInt' (I# x) (I# y) = I# (gcdInt x y)
gcdWord' :: Word -> Word -> Word
gcdWord' (W# x) (W# y) = W# (gcdWord x y)
#endif
-#endif
integralEnumFrom :: (Integral a, Bounded a) => a -> [a]
integralEnumFrom n = map fromInteger [toInteger n .. toInteger (maxBound `asTypeOf` n)]
diff --git a/libraries/base/GHC/Stack.hs b/libraries/base/GHC/Stack.hs
index f5b175c0bb..1f102c9f9b 100644
--- a/libraries/base/GHC/Stack.hs
+++ b/libraries/base/GHC/Stack.hs
@@ -85,7 +85,10 @@ popCallStack stk = case stk of
--
-- @since 4.9.0.0
callStack :: HasCallStack => CallStack
-callStack = popCallStack ?callStack
+callStack =
+ case ?callStack of
+ EmptyCallStack -> EmptyCallStack
+ _ -> popCallStack ?callStack
{-# INLINE callStack #-}
-- | Perform some computation without adding new entries to the 'CallStack'.
diff --git a/libraries/base/System/Environment.hs b/libraries/base/System/Environment.hs
index 56e6961f8a..343b7722c6 100644
--- a/libraries/base/System/Environment.hs
+++ b/libraries/base/System/Environment.hs
@@ -38,13 +38,13 @@ import Control.Exception.Base (bracket)
#endif
-- import GHC.IO
import GHC.IO.Exception
-import GHC.IO.Encoding (getFileSystemEncoding)
import qualified GHC.Foreign as GHC
import Control.Monad
#if defined(mingw32_HOST_OS)
-import GHC.Environment
+import GHC.IO.Encoding (argvEncoding)
import GHC.Windows
#else
+import GHC.IO.Encoding (getFileSystemEncoding, argvEncoding)
import System.Posix.Internals (withFilePath)
#endif
@@ -65,89 +65,21 @@ import System.Environment.ExecutablePath
-- ---------------------------------------------------------------------------
-- getArgs, getProgName, getEnv
-#if defined(mingw32_HOST_OS)
-
-{-
-Note [Ignore hs_init argv]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-Ignore the arguments to hs_init on Windows for the sake of Unicode compat
-
-Instead on Windows we get the list of arguments from getCommandLineW and
-filter out arguments which the RTS would not have passed along.
-
-This is done to ensure we get the arguments in proper Unicode Encoding which
-the RTS at this moment does not seem provide. The filtering has to match the
-one done by the RTS to avoid inconsistencies like #13287.
--}
-
-getWin32ProgArgv_certainly :: IO [String]
-getWin32ProgArgv_certainly = do
- mb_argv <- getWin32ProgArgv
- case mb_argv of
- -- see Note [Ignore hs_init argv]
- Nothing -> fmap dropRTSArgs getFullArgs
- Just argv -> return argv
-
-withWin32ProgArgv :: [String] -> IO a -> IO a
-withWin32ProgArgv argv act = bracket begin setWin32ProgArgv (\_ -> act)
- where
- begin = do
- mb_old_argv <- getWin32ProgArgv
- setWin32ProgArgv (Just argv)
- return mb_old_argv
-
-getWin32ProgArgv :: IO (Maybe [String])
-getWin32ProgArgv = alloca $ \p_argc -> alloca $ \p_argv -> do
- c_getWin32ProgArgv p_argc p_argv
- argc <- peek p_argc
- argv_p <- peek p_argv
- if argv_p == nullPtr
- then return Nothing
- else do
- argv_ps <- peekArray (fromIntegral argc) argv_p
- fmap Just $ mapM peekCWString argv_ps
-
-setWin32ProgArgv :: Maybe [String] -> IO ()
-setWin32ProgArgv Nothing = c_setWin32ProgArgv 0 nullPtr
-setWin32ProgArgv (Just argv) = withMany withCWString argv $ \argv_ps -> withArrayLen argv_ps $ \argc argv_p -> do
- c_setWin32ProgArgv (fromIntegral argc) argv_p
-
-foreign import ccall unsafe "getWin32ProgArgv"
- c_getWin32ProgArgv :: Ptr CInt -> Ptr (Ptr CWString) -> IO ()
-
-foreign import ccall unsafe "setWin32ProgArgv"
- c_setWin32ProgArgv :: CInt -> Ptr CWString -> IO ()
-
--- See Note [Ignore hs_init argv]
-dropRTSArgs :: [String] -> [String]
-dropRTSArgs [] = []
-dropRTSArgs rest@("--":_) = rest
-dropRTSArgs ("+RTS":rest) = dropRTSArgs (dropWhile (/= "-RTS") rest)
-dropRTSArgs ("--RTS":rest) = rest
-dropRTSArgs ("-RTS":rest) = dropRTSArgs rest
-dropRTSArgs (arg:rest) = arg : dropRTSArgs rest
-
-#endif
-
-- | Computation 'getArgs' returns a list of the program's command
-- line arguments (not including the program name).
getArgs :: IO [String]
-
-#if defined(mingw32_HOST_OS)
-getArgs = fmap tail getWin32ProgArgv_certainly
-#else
getArgs =
alloca $ \ p_argc ->
alloca $ \ p_argv -> do
getProgArgv p_argc p_argv
p <- fromIntegral `liftM` peek p_argc
argv <- peek p_argv
- enc <- getFileSystemEncoding
+ enc <- argvEncoding
peekArray (p - 1) (advancePtr argv 1) >>= mapM (GHC.peekCString enc)
+
foreign import ccall unsafe "getProgArgv"
getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
-#endif
{-|
Computation 'getProgName' returns the name of the program as it was
@@ -160,10 +92,7 @@ between platforms: on Windows, for example, a program invoked as foo
is probably really @FOO.EXE@, and that is what 'getProgName' will return.
-}
getProgName :: IO String
-#if defined(mingw32_HOST_OS)
-- Ignore the arguments to hs_init on Windows for the sake of Unicode compat
-getProgName = fmap (basename . head) getWin32ProgArgv_certainly
-#else
getProgName =
alloca $ \ p_argc ->
alloca $ \ p_argv -> do
@@ -173,10 +102,9 @@ getProgName =
unpackProgName :: Ptr (Ptr CChar) -> IO String -- argv[0]
unpackProgName argv = do
- enc <- getFileSystemEncoding
+ enc <- argvEncoding
s <- peekElemOff argv 0 >>= GHC.peekCString enc
return (basename s)
-#endif
basename :: FilePath -> FilePath
basename f = go f f
@@ -262,9 +190,10 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv"
-- | @setEnv name value@ sets the specified environment variable to @value@.
--
--- On Windows setting an environment variable to the /empty string/ removes
+-- Early versions of this function operated under the mistaken belief that
+-- setting an environment variable to the /empty string/ on Windows removes
-- that environment variable from the environment. For the sake of
--- compatibility we adopt that behavior. In particular
+-- compatibility, it adopted that behavior on POSIX. In particular
--
-- @
-- setEnv name \"\"
@@ -276,9 +205,8 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv"
-- `unsetEnv` name
-- @
--
--- If you don't care about Windows support and want to set an environment
--- variable to the empty string use @System.Posix.Env.setEnv@ from the @unix@
--- package instead.
+-- If you'd like to be able to set environment variables to blank strings,
+-- use `System.Environment.Blank.setEnv`.
--
-- Throws `Control.Exception.IOException` if @name@ is the empty string or
-- contains an equals sign.
@@ -371,15 +299,7 @@ withProgName nm act = do
-- the duration of an action.
withArgv :: [String] -> IO a -> IO a
-
-#if defined(mingw32_HOST_OS)
--- We have to reflect the updated arguments in the RTS-side variables as
--- well, because the RTS still consults them for error messages and the like.
--- If we don't do this then ghc-e005 fails.
-withArgv new_args act = withWin32ProgArgv new_args $ withProgArgv new_args act
-#else
withArgv = withProgArgv
-#endif
withProgArgv :: [String] -> IO a -> IO a
withProgArgv new_args act = do
@@ -391,7 +311,7 @@ withProgArgv new_args act = do
setProgArgv :: [String] -> IO ()
setProgArgv argv = do
- enc <- getFileSystemEncoding
+ enc <- argvEncoding
GHC.withCStringsLen enc argv $ \len css ->
c_setProgArgv (fromIntegral len) css
diff --git a/libraries/base/System/Environment/Blank.hsc b/libraries/base/System/Environment/Blank.hsc
new file mode 100644
index 0000000000..ebca1ef150
--- /dev/null
+++ b/libraries/base/System/Environment/Blank.hsc
@@ -0,0 +1,196 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE CApiFFI #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module : System.Environment.Blank
+-- Copyright : (c) Habib Alamin 2017
+-- License : BSD-style (see the file libraries/base/LICENSE)
+--
+-- Maintainer : libraries@haskell.org
+-- Stability : provisional
+-- Portability : portable
+--
+-- A setEnv implementation that allows blank environment variables. Mimics
+-- the `System.Posix.Env` module from the @unix@ package, but with support
+-- for Windows too.
+--
+-- The matrix of platforms that:
+--
+-- * support putenv("FOO") to unset environment variables,
+-- * support putenv("FOO=") to unset environment variables or set them
+-- to blank values,
+-- * support unsetenv to unset environment variables,
+-- * support setenv to set environment variables,
+-- * etc.
+--
+-- is very complicated. I think AIX is screwed, but we don't support it.
+-- The whole situation with setenv(3), unsetenv(3), and putenv(3) is not
+-- good. Even mingw32 adds its own crap to the pile, but luckily, we can
+-- just use Windows' native environment functions to sidestep the issue.
+--
+-- #12494
+--
+-----------------------------------------------------------------------------
+
+module System.Environment.Blank
+ (
+ module System.Environment,
+ getEnv,
+ getEnvDefault,
+ setEnv,
+ unsetEnv,
+ ) where
+
+import Foreign.C
+#ifdef mingw32_HOST_OS
+import Foreign.Ptr
+import GHC.Windows
+import Control.Monad
+#else
+import System.Posix.Internals
+#endif
+import GHC.IO.Exception
+import System.IO.Error
+import Control.Exception.Base
+import Data.Maybe
+
+import System.Environment
+ (
+ getArgs,
+ getProgName,
+ getExecutablePath,
+ withArgs,
+ withProgName,
+ getEnvironment
+ )
+#ifndef mingw32_HOST_OS
+import qualified System.Environment as Environment
+#endif
+
+-- TODO: include windows_cconv.h when it's merged, instead of duplicating
+-- this C macro block.
+#if defined(mingw32_HOST_OS)
+# if defined(i386_HOST_ARCH)
+## define WINDOWS_CCONV stdcall
+# elif defined(x86_64_HOST_ARCH)
+## define WINDOWS_CCONV ccall
+# else
+## error Unknown mingw32 arch
+# endif
+#endif
+
+#include "HsBaseConfig.h"
+
+throwInvalidArgument :: String -> IO a
+throwInvalidArgument from =
+ throwIO (mkIOError InvalidArgument from Nothing Nothing)
+
+-- | `System.Environment.lookupEnv`.
+getEnv :: String -> IO (Maybe String)
+#ifdef mingw32_HOST_OS
+getEnv = (<$> getEnvironment) . lookup
+#else
+getEnv = Environment.lookupEnv
+#endif
+
+-- | Get an environment value or a default value.
+getEnvDefault ::
+ String {- ^ variable name -} ->
+ String {- ^ fallback value -} ->
+ IO String {- ^ variable value or fallback value -}
+getEnvDefault name fallback = fromMaybe fallback <$> getEnv name
+
+-- | Like `System.Environment.setEnv`, but allows blank environment values
+-- and mimics the function signature of `System.Posix.Env.setEnv` from the
+-- @unix@ package.
+setEnv ::
+ String {- ^ variable name -} ->
+ String {- ^ variable value -} ->
+ Bool {- ^ overwrite -} ->
+ IO ()
+setEnv key_ value_ overwrite
+ | null key = throwInvalidArgument "setEnv"
+ | '=' `elem` key = throwInvalidArgument "setEnv"
+ | otherwise =
+ if overwrite
+ then setEnv_ key value
+ else do
+ env_var <- getEnv key
+ case env_var of
+ Just _ -> return ()
+ Nothing -> setEnv_ key value
+ where
+ key = takeWhile (/= '\NUL') key_
+ value = takeWhile (/= '\NUL') value_
+
+setEnv_ :: String -> String -> IO ()
+#if defined(mingw32_HOST_OS)
+setEnv_ key value = withCWString key $ \k -> withCWString value $ \v -> do
+ success <- c_SetEnvironmentVariable k v
+ unless success (throwGetLastError "setEnv")
+
+foreign import WINDOWS_CCONV unsafe "windows.h SetEnvironmentVariableW"
+ c_SetEnvironmentVariable :: LPTSTR -> LPTSTR -> IO Bool
+#else
+setEnv_ key value =
+ withFilePath key $ \ keyP ->
+ withFilePath value $ \ valueP ->
+ throwErrnoIfMinus1_ "setenv" $
+ c_setenv keyP valueP (fromIntegral (fromEnum True))
+
+foreign import ccall unsafe "setenv"
+ c_setenv :: CString -> CString -> CInt -> IO CInt
+#endif
+
+-- | Like `System.Environment.unsetEnv`, but allows for the removal of
+-- blank environment variables.
+unsetEnv :: String -> IO ()
+#if defined(mingw32_HOST_OS)
+unsetEnv key = withCWString key $ \k -> do
+ success <- c_SetEnvironmentVariable k nullPtr
+ unless success $ do
+ -- We consider unsetting an environment variable that does not exist not as
+ -- an error, hence we ignore eRROR_ENVVAR_NOT_FOUND.
+ err <- c_GetLastError
+ unless (err == eRROR_ENVVAR_NOT_FOUND) $ do
+ throwGetLastError "unsetEnv"
+
+eRROR_ENVVAR_NOT_FOUND :: DWORD
+eRROR_ENVVAR_NOT_FOUND = 203
+
+foreign import WINDOWS_CCONV unsafe "windows.h GetLastError"
+ c_GetLastError:: IO DWORD
+#elif HAVE_UNSETENV
+# if !UNSETENV_RETURNS_VOID
+unsetEnv name = withFilePath name $ \ s ->
+ throwErrnoIfMinus1_ "unsetenv" (c_unsetenv s)
+
+-- POSIX.1-2001 compliant unsetenv(3)
+foreign import capi unsafe "HsBase.h unsetenv"
+ c_unsetenv :: CString -> IO CInt
+# else
+unsetEnv name = withFilePath name c_unsetenv
+
+-- pre-POSIX unsetenv(3) returning @void@
+foreign import capi unsafe "HsBase.h unsetenv"
+ c_unsetenv :: CString -> IO ()
+# endif
+#else
+unsetEnv name =
+ if '=' `elem` name
+ then throwInvalidArgument "unsetEnv"
+ else putEnv name
+
+putEnv :: String -> IO ()
+putEnv keyvalue = do
+ s <- getFileSystemEncoding >>= (`newCString` keyvalue)
+ -- IMPORTANT: Do not free `s` after calling putenv!
+ --
+ -- According to SUSv2, the string passed to putenv becomes part of the
+ -- environment. #7342
+ throwErrnoIf_ (/= 0) "putenv" (c_putenv s)
+
+foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt
+#endif
diff --git a/libraries/base/base.cabal b/libraries/base/base.cabal
index 9429de05c3..4bbe2f2d51 100644
--- a/libraries/base/base.cabal
+++ b/libraries/base/base.cabal
@@ -289,6 +289,7 @@ Library
System.CPUTime
System.Console.GetOpt
System.Environment
+ System.Environment.Blank
System.Exit
System.IO
System.IO.Error
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 0cfd9c1ba8..708676fe65 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -10,6 +10,10 @@
* Add `infixl 9 !!` declaration for `Data.List.NonEmpty.!!`
+ * Add `<&>` operator to `Data.Functor` (#14029)
+
+ * Remove the deprecated `Typeable{1..7}` type synonyms (#14047)
+
## 4.10.0.0 *April 2017*
* Bundled with GHC *TBA*
diff --git a/libraries/base/tests/T12494.hs b/libraries/base/tests/T12494.hs
new file mode 100644
index 0000000000..544f5ed908
--- /dev/null
+++ b/libraries/base/tests/T12494.hs
@@ -0,0 +1,36 @@
+import System.Environment.Blank
+
+main = do
+ let envVar = "AN_ENVIRONMENT_VARIABLE"
+
+ valueBeforeSettingVariable <- getEnv envVar
+ print valueBeforeSettingVariable -- Nothing
+
+ valueWithDefaultBeforeSetting <- getEnvDefault envVar "DEFAULT"
+ print valueWithDefaultBeforeSetting -- "DEFAULT"
+
+ setEnv envVar "" False
+
+ valueAfterSettingVariable <- getEnv envVar
+ print valueAfterSettingVariable -- Just ""
+
+ valueWithDefaultAfterSetting <- getEnvDefault envVar "DEFAULT"
+ print valueWithDefaultAfterSetting -- ""
+
+ valueFromGetEnvironment <- lookup envVar <$> getEnvironment
+ print valueFromGetEnvironment -- Just ""
+
+ setEnv envVar "NO_OVERRIDE" False
+
+ valueAfterSettingWithExistingValueAndOverrideFalse <- getEnv envVar
+ print valueAfterSettingWithExistingValueAndOverrideFalse -- Just ""
+
+ setEnv envVar "OVERRIDE" True
+
+ valueAfterSettingWithExistingValueAndOverrideTrue <- getEnv envVar
+ print valueAfterSettingWithExistingValueAndOverrideTrue -- Just "OVERRIDE"
+
+ unsetEnv envVar
+
+ valueAfterUnsettingVariable <- getEnv envVar
+ print valueAfterUnsettingVariable -- Nothing
diff --git a/libraries/base/tests/T12494.stdout b/libraries/base/tests/T12494.stdout
new file mode 100644
index 0000000000..a3b77cc271
--- /dev/null
+++ b/libraries/base/tests/T12494.stdout
@@ -0,0 +1,8 @@
+Nothing
+"DEFAULT"
+Just ""
+""
+Just ""
+Just ""
+Just "OVERRIDE"
+Nothing
diff --git a/libraries/base/tests/all.T b/libraries/base/tests/all.T
index 4bd8084220..d97d79afe3 100644
--- a/libraries/base/tests/all.T
+++ b/libraries/base/tests/all.T
@@ -201,6 +201,7 @@ test('T9848',
test('T10149', normal, compile_and_run, [''])
test('T11334a', normal, compile_and_run, [''])
test('T11555', normal, compile_and_run, [''])
+test('T12494', normal, compile_and_run, [''])
test('T12852', when(opsys('mingw32'), skip), compile_and_run, [''])
test('lazySTexamples', normal, compile_and_run, [''])
test('T11760', normal, compile_and_run, ['-threaded -with-rtsopts=-N2'])
@@ -214,3 +215,4 @@ test('T13191',
['-O'])
test('T13525', when(opsys('mingw32'), skip), compile_and_run, [''])
test('T13097', normal, compile_and_run, [''])
+test('functorOperators', normal, compile_and_run, [''])
diff --git a/libraries/base/tests/functorOperators.hs b/libraries/base/tests/functorOperators.hs
new file mode 100644
index 0000000000..aea5dfda80
--- /dev/null
+++ b/libraries/base/tests/functorOperators.hs
@@ -0,0 +1,38 @@
+-- Test infix operators of 'Functor'
+
+import Data.Functor
+
+main :: IO ()
+main = do
+ testInfixFmap
+ testFlippedInfixFmap
+ testInfixReplace
+ testFlippedInfixReplace
+
+testInfixFmap :: IO ()
+testInfixFmap = do
+ print "<$> tests:"
+ print $ (+ 1) <$> Just 2 -- => Just 3
+ print (((+ 1) <$> Right 3) :: Either Int Int) -- => Right 4
+ print $ (+ 1) <$> [1, 2, 3] -- => [2,3,4]
+
+testFlippedInfixFmap :: IO ()
+testFlippedInfixFmap = do
+ print "<&> tests:"
+ print $ Just 2 <&> (+ 1) -- => Just 3
+ print ((Right 3 <&> (+ 1)) :: Either Int Int) -- => Right 4
+ print $ [1, 2, 3] <&> (+ 1) -- => [2,3,4]
+
+testInfixReplace :: IO ()
+testInfixReplace = do
+ print "<$ tests:"
+ print $ 42 <$ Just 1 -- => Just 42
+ print ((42 <$ Right 1) :: Either Int Int) -- => Right 42
+ print $ 42 <$ [1, 2, 3] -- => [42,42,42]
+
+testFlippedInfixReplace :: IO ()
+testFlippedInfixReplace = do
+ print "$> tests:"
+ print $ Just 1 $> 42 -- => Just 42
+ print ((Right 1 $> 42) :: Either Int Int) -- => Right 42
+ print $ [1, 2, 3] $> 42 -- => [42,42,42]
diff --git a/libraries/base/tests/functorOperators.stdout b/libraries/base/tests/functorOperators.stdout
new file mode 100644
index 0000000000..00a17ed3b8
--- /dev/null
+++ b/libraries/base/tests/functorOperators.stdout
@@ -0,0 +1,16 @@
+"<$> tests:"
+Just 3
+Right 4
+[2,3,4]
+"<&> tests:"
+Just 3
+Right 4
+[2,3,4]
+"<$ tests:"
+Just 42
+Right 42
+[42,42,42]
+"$> tests:"
+Just 42
+Right 42
+[42,42,42]
diff --git a/libraries/ghci/GHCi/Message.hs b/libraries/ghci/GHCi/Message.hs
index 81de2fbd21..fe63d641a4 100644
--- a/libraries/ghci/GHCi/Message.hs
+++ b/libraries/ghci/GHCi/Message.hs
@@ -48,11 +48,7 @@ import Data.Typeable (TypeRep)
import Data.IORef
import Data.Map (Map)
import GHC.Generics
-#if MIN_VERSION_base(4,9,0)
import GHC.Stack.CCS
-#else
-import GHC.Stack as GHC.Stack.CCS
-#endif
import qualified Language.Haskell.TH as TH
import qualified Language.Haskell.TH.Syntax as TH
import System.Exit
@@ -384,17 +380,7 @@ fromSerializableException EUserInterrupt = toException UserInterrupt
fromSerializableException (EExitCode c) = toException c
fromSerializableException (EOtherException str) = toException (ErrorCall str)
--- NB: Replace this with a derived instance once we depend on GHC 8.0
--- as the minimum
-instance Binary ExitCode where
- put ExitSuccess = putWord8 0
- put (ExitFailure ec) = putWord8 1 >> put ec
- get = do
- w <- getWord8
- case w of
- 0 -> pure ExitSuccess
- _ -> ExitFailure <$> get
-
+instance Binary ExitCode
instance Binary SerializableException
data THResult a
diff --git a/libraries/ghci/GHCi/TH.hs b/libraries/ghci/GHCi/TH.hs
index 1b08501580..09fbca7e32 100644
--- a/libraries/ghci/GHCi/TH.hs
+++ b/libraries/ghci/GHCi/TH.hs
@@ -97,6 +97,7 @@ import GHC.Serialized
import Control.Exception
import qualified Control.Monad.Fail as Fail
+import Control.Monad.IO.Class (MonadIO (..))
import Data.Binary
import Data.Binary.Put
import Data.ByteString (ByteString)
@@ -160,6 +161,9 @@ ghcCmd m = GHCiQ $ \s -> do
THException str -> throwIO (GHCiQException s str)
THComplete res -> return (res, s)
+instance MonadIO GHCiQ where
+ liftIO m = GHCiQ $ \s -> fmap (,s) m
+
instance TH.Quasi GHCiQ where
qNewName str = ghcCmd (NewName str)
qReport isError msg = ghcCmd (Report isError msg)
@@ -190,7 +194,6 @@ instance TH.Quasi GHCiQ where
qReifyModule m = ghcCmd (ReifyModule m)
qReifyConStrictness name = ghcCmd (ReifyConStrictness name)
qLocation = fromMaybe noLoc . qsLocation <$> getState
- qRunIO m = GHCiQ $ \s -> fmap (,s) m
qAddDependentFile file = ghcCmd (AddDependentFile file)
qAddTopDecls decls = ghcCmd (AddTopDecls decls)
qAddForeignFile str lang = ghcCmd (AddForeignFile str lang)
diff --git a/libraries/mtl b/libraries/mtl
new file mode 160000
+Subproject b4725fe28cba8a535e969e0ddbce3d5e05146cc
diff --git a/libraries/parsec b/libraries/parsec
new file mode 160000
+Subproject d21d86387998614de31697a26fd8fec15d40e62
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib.hs b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
index 78fbc41d6f..9ad36f8586 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Lib.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
@@ -1,8 +1,13 @@
-- |
--- TH.Lib contains lots of useful helper functions for
+-- Language.Haskell.TH.Lib contains lots of useful helper functions for
-- generating and manipulating Template Haskell terms
-{-# LANGUAGE CPP #-}
+-- Note: this module mostly re-exports functions from
+-- Language.Haskell.TH.Lib.Internal, but if a change occurs to Template
+-- Haskell which requires breaking the API offered in this module, we opt to
+-- copy the old definition here, and make the changes in
+-- Language.Haskell.TH.Lib.Internal. This way, we can retain backwards
+-- compatibility while still allowing GHC to make changes as it needs.
module Language.Haskell.TH.Lib (
-- All of the exports from this module should
@@ -11,11 +16,12 @@ module Language.Haskell.TH.Lib (
-- * Library functions
-- ** Abbreviations
- InfoQ, ExpQ, TExpQ, DecQ, DecsQ, ConQ, TypeQ, TyLitQ, CxtQ, PredQ,
- DerivClauseQ, MatchQ, ClauseQ, BodyQ, GuardQ, StmtQ, RangeQ,
- SourceStrictnessQ, SourceUnpackednessQ, BangQ, BangTypeQ, VarBangTypeQ,
- StrictTypeQ, VarStrictTypeQ, FieldExpQ, PatQ, FieldPatQ, RuleBndrQ,
- TySynEqnQ, PatSynDirQ, PatSynArgsQ,
+ InfoQ, ExpQ, TExpQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, TyVarBndrQ,
+ TyLitQ, CxtQ, PredQ, DerivClauseQ, MatchQ, ClauseQ, BodyQ, GuardQ,
+ StmtQ, RangeQ, SourceStrictnessQ, SourceUnpackednessQ, BangQ,
+ BangTypeQ, VarBangTypeQ, StrictTypeQ, VarStrictTypeQ, FieldExpQ, PatQ,
+ FieldPatQ, RuleBndrQ, TySynEqnQ, PatSynDirQ, PatSynArgsQ,
+ FamilyResultSigQ,
-- ** Constructors lifted to 'Q'
-- *** Literals
@@ -111,358 +117,45 @@ module Language.Haskell.TH.Lib (
) where
-import Language.Haskell.TH.Syntax hiding (Role, InjectivityAnn)
-import qualified Language.Haskell.TH.Syntax as TH
-import Control.Monad( liftM, liftM2 )
-import Data.Word( Word8 )
-
-----------------------------------------------------------
--- * Type synonyms
-----------------------------------------------------------
-
-type InfoQ = Q Info
-type PatQ = Q Pat
-type FieldPatQ = Q FieldPat
-type ExpQ = Q Exp
-type TExpQ a = Q (TExp a)
-type DecQ = Q Dec
-type DecsQ = Q [Dec]
-type ConQ = Q Con
-type TypeQ = Q Type
-type TyLitQ = Q TyLit
-type CxtQ = Q Cxt
-type PredQ = Q Pred
-type DerivClauseQ = Q DerivClause
-type MatchQ = Q Match
-type ClauseQ = Q Clause
-type BodyQ = Q Body
-type GuardQ = Q Guard
-type StmtQ = Q Stmt
-type RangeQ = Q Range
-type SourceStrictnessQ = Q SourceStrictness
-type SourceUnpackednessQ = Q SourceUnpackedness
-type BangQ = Q Bang
-type BangTypeQ = Q BangType
-type VarBangTypeQ = Q VarBangType
-type StrictTypeQ = Q StrictType
-type VarStrictTypeQ = Q VarStrictType
-type FieldExpQ = Q FieldExp
-type RuleBndrQ = Q RuleBndr
-type TySynEqnQ = Q TySynEqn
-type PatSynDirQ = Q PatSynDir
-type PatSynArgsQ = Q PatSynArgs
-
--- must be defined here for DsMeta to find it
-type Role = TH.Role
-type InjectivityAnn = TH.InjectivityAnn
-
-----------------------------------------------------------
--- * Lowercase pattern syntax functions
-----------------------------------------------------------
-
-intPrimL :: Integer -> Lit
-intPrimL = IntPrimL
-wordPrimL :: Integer -> Lit
-wordPrimL = WordPrimL
-floatPrimL :: Rational -> Lit
-floatPrimL = FloatPrimL
-doublePrimL :: Rational -> Lit
-doublePrimL = DoublePrimL
-integerL :: Integer -> Lit
-integerL = IntegerL
-charL :: Char -> Lit
-charL = CharL
-charPrimL :: Char -> Lit
-charPrimL = CharPrimL
-stringL :: String -> Lit
-stringL = StringL
-stringPrimL :: [Word8] -> Lit
-stringPrimL = StringPrimL
-rationalL :: Rational -> Lit
-rationalL = RationalL
-
-litP :: Lit -> PatQ
-litP l = return (LitP l)
-
-varP :: Name -> PatQ
-varP v = return (VarP v)
-
-tupP :: [PatQ] -> PatQ
-tupP ps = do { ps1 <- sequence ps; return (TupP ps1)}
-
-unboxedTupP :: [PatQ] -> PatQ
-unboxedTupP ps = do { ps1 <- sequence ps; return (UnboxedTupP ps1)}
-
-unboxedSumP :: PatQ -> SumAlt -> SumArity -> PatQ
-unboxedSumP p alt arity = do { p1 <- p; return (UnboxedSumP p1 alt arity) }
-
-conP :: Name -> [PatQ] -> PatQ
-conP n ps = do ps' <- sequence ps
- return (ConP n ps')
-infixP :: PatQ -> Name -> PatQ -> PatQ
-infixP p1 n p2 = do p1' <- p1
- p2' <- p2
- return (InfixP p1' n p2')
-uInfixP :: PatQ -> Name -> PatQ -> PatQ
-uInfixP p1 n p2 = do p1' <- p1
- p2' <- p2
- return (UInfixP p1' n p2')
-parensP :: PatQ -> PatQ
-parensP p = do p' <- p
- return (ParensP p')
-
-tildeP :: PatQ -> PatQ
-tildeP p = do p' <- p
- return (TildeP p')
-bangP :: PatQ -> PatQ
-bangP p = do p' <- p
- return (BangP p')
-asP :: Name -> PatQ -> PatQ
-asP n p = do p' <- p
- return (AsP n p')
-wildP :: PatQ
-wildP = return WildP
-recP :: Name -> [FieldPatQ] -> PatQ
-recP n fps = do fps' <- sequence fps
- return (RecP n fps')
-listP :: [PatQ] -> PatQ
-listP ps = do ps' <- sequence ps
- return (ListP ps')
-sigP :: PatQ -> TypeQ -> PatQ
-sigP p t = do p' <- p
- t' <- t
- return (SigP p' t')
-viewP :: ExpQ -> PatQ -> PatQ
-viewP e p = do e' <- e
- p' <- p
- return (ViewP e' p')
-
-fieldPat :: Name -> PatQ -> FieldPatQ
-fieldPat n p = do p' <- p
- return (n, p')
-
-
--------------------------------------------------------------------------------
--- * Stmt
-
-bindS :: PatQ -> ExpQ -> StmtQ
-bindS p e = liftM2 BindS p e
-
-letS :: [DecQ] -> StmtQ
-letS ds = do { ds1 <- sequence ds; return (LetS ds1) }
-
-noBindS :: ExpQ -> StmtQ
-noBindS e = do { e1 <- e; return (NoBindS e1) }
-
-parS :: [[StmtQ]] -> StmtQ
-parS sss = do { sss1 <- mapM sequence sss; return (ParS sss1) }
-
--------------------------------------------------------------------------------
--- * Range
-
-fromR :: ExpQ -> RangeQ
-fromR x = do { a <- x; return (FromR a) }
-
-fromThenR :: ExpQ -> ExpQ -> RangeQ
-fromThenR x y = do { a <- x; b <- y; return (FromThenR a b) }
-
-fromToR :: ExpQ -> ExpQ -> RangeQ
-fromToR x y = do { a <- x; b <- y; return (FromToR a b) }
-
-fromThenToR :: ExpQ -> ExpQ -> ExpQ -> RangeQ
-fromThenToR x y z = do { a <- x; b <- y; c <- z;
- return (FromThenToR a b c) }
--------------------------------------------------------------------------------
--- * Body
-
-normalB :: ExpQ -> BodyQ
-normalB e = do { e1 <- e; return (NormalB e1) }
-
-guardedB :: [Q (Guard,Exp)] -> BodyQ
-guardedB ges = do { ges' <- sequence ges; return (GuardedB ges') }
-
--------------------------------------------------------------------------------
--- * Guard
-
-normalG :: ExpQ -> GuardQ
-normalG e = do { e1 <- e; return (NormalG e1) }
-
-normalGE :: ExpQ -> ExpQ -> Q (Guard, Exp)
-normalGE g e = do { g1 <- g; e1 <- e; return (NormalG g1, e1) }
-
-patG :: [StmtQ] -> GuardQ
-patG ss = do { ss' <- sequence ss; return (PatG ss') }
-
-patGE :: [StmtQ] -> ExpQ -> Q (Guard, Exp)
-patGE ss e = do { ss' <- sequence ss;
- e' <- e;
- return (PatG ss', e') }
-
--------------------------------------------------------------------------------
--- * Match and Clause
-
--- | Use with 'caseE'
-match :: PatQ -> BodyQ -> [DecQ] -> MatchQ
-match p rhs ds = do { p' <- p;
- r' <- rhs;
- ds' <- sequence ds;
- return (Match p' r' ds') }
-
--- | Use with 'funD'
-clause :: [PatQ] -> BodyQ -> [DecQ] -> ClauseQ
-clause ps r ds = do { ps' <- sequence ps;
- r' <- r;
- ds' <- sequence ds;
- return (Clause ps' r' ds') }
-
-
----------------------------------------------------------------------------
--- * Exp
-
--- | Dynamically binding a variable (unhygenic)
-dyn :: String -> ExpQ
-dyn s = return (VarE (mkName s))
-
-varE :: Name -> ExpQ
-varE s = return (VarE s)
-
-conE :: Name -> ExpQ
-conE s = return (ConE s)
-
-litE :: Lit -> ExpQ
-litE c = return (LitE c)
-
-appE :: ExpQ -> ExpQ -> ExpQ
-appE x y = do { a <- x; b <- y; return (AppE a b)}
-
-appTypeE :: ExpQ -> TypeQ -> ExpQ
-appTypeE x t = do { a <- x; s <- t; return (AppTypeE a s) }
-
-parensE :: ExpQ -> ExpQ
-parensE x = do { x' <- x; return (ParensE x') }
-
-uInfixE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
-uInfixE x s y = do { x' <- x; s' <- s; y' <- y;
- return (UInfixE x' s' y') }
-
-infixE :: Maybe ExpQ -> ExpQ -> Maybe ExpQ -> ExpQ
-infixE (Just x) s (Just y) = do { a <- x; s' <- s; b <- y;
- return (InfixE (Just a) s' (Just b))}
-infixE Nothing s (Just y) = do { s' <- s; b <- y;
- return (InfixE Nothing s' (Just b))}
-infixE (Just x) s Nothing = do { a <- x; s' <- s;
- return (InfixE (Just a) s' Nothing)}
-infixE Nothing s Nothing = do { s' <- s; return (InfixE Nothing s' Nothing) }
-
-infixApp :: ExpQ -> ExpQ -> ExpQ -> ExpQ
-infixApp x y z = infixE (Just x) y (Just z)
-sectionL :: ExpQ -> ExpQ -> ExpQ
-sectionL x y = infixE (Just x) y Nothing
-sectionR :: ExpQ -> ExpQ -> ExpQ
-sectionR x y = infixE Nothing x (Just y)
-
-lamE :: [PatQ] -> ExpQ -> ExpQ
-lamE ps e = do ps' <- sequence ps
- e' <- e
- return (LamE ps' e')
-
--- | Single-arg lambda
-lam1E :: PatQ -> ExpQ -> ExpQ
-lam1E p e = lamE [p] e
-
-lamCaseE :: [MatchQ] -> ExpQ
-lamCaseE ms = sequence ms >>= return . LamCaseE
-
-tupE :: [ExpQ] -> ExpQ
-tupE es = do { es1 <- sequence es; return (TupE es1)}
-
-unboxedTupE :: [ExpQ] -> ExpQ
-unboxedTupE es = do { es1 <- sequence es; return (UnboxedTupE es1)}
-
-unboxedSumE :: ExpQ -> SumAlt -> SumArity -> ExpQ
-unboxedSumE e alt arity = do { e1 <- e; return (UnboxedSumE e1 alt arity) }
-
-condE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
-condE x y z = do { a <- x; b <- y; c <- z; return (CondE a b c)}
-
-multiIfE :: [Q (Guard, Exp)] -> ExpQ
-multiIfE alts = sequence alts >>= return . MultiIfE
-
-letE :: [DecQ] -> ExpQ -> ExpQ
-letE ds e = do { ds2 <- sequence ds; e2 <- e; return (LetE ds2 e2) }
-
-caseE :: ExpQ -> [MatchQ] -> ExpQ
-caseE e ms = do { e1 <- e; ms1 <- sequence ms; return (CaseE e1 ms1) }
-
-doE :: [StmtQ] -> ExpQ
-doE ss = do { ss1 <- sequence ss; return (DoE ss1) }
-
-compE :: [StmtQ] -> ExpQ
-compE ss = do { ss1 <- sequence ss; return (CompE ss1) }
-
-arithSeqE :: RangeQ -> ExpQ
-arithSeqE r = do { r' <- r; return (ArithSeqE r') }
-
-listE :: [ExpQ] -> ExpQ
-listE es = do { es1 <- sequence es; return (ListE es1) }
-
-sigE :: ExpQ -> TypeQ -> ExpQ
-sigE e t = do { e1 <- e; t1 <- t; return (SigE e1 t1) }
-
-recConE :: Name -> [Q (Name,Exp)] -> ExpQ
-recConE c fs = do { flds <- sequence fs; return (RecConE c flds) }
-
-recUpdE :: ExpQ -> [Q (Name,Exp)] -> ExpQ
-recUpdE e fs = do { e1 <- e; flds <- sequence fs; return (RecUpdE e1 flds) }
-
-stringE :: String -> ExpQ
-stringE = litE . stringL
-
-fieldExp :: Name -> ExpQ -> Q (Name, Exp)
-fieldExp s e = do { e' <- e; return (s,e') }
-
--- | @staticE x = [| static x |]@
-staticE :: ExpQ -> ExpQ
-staticE = fmap StaticE
-
-unboundVarE :: Name -> ExpQ
-unboundVarE s = return (UnboundVarE s)
-
-labelE :: String -> ExpQ
-labelE s = return (LabelE s)
-
--- ** 'arithSeqE' Shortcuts
-fromE :: ExpQ -> ExpQ
-fromE x = do { a <- x; return (ArithSeqE (FromR a)) }
-
-fromThenE :: ExpQ -> ExpQ -> ExpQ
-fromThenE x y = do { a <- x; b <- y; return (ArithSeqE (FromThenR a b)) }
-
-fromToE :: ExpQ -> ExpQ -> ExpQ
-fromToE x y = do { a <- x; b <- y; return (ArithSeqE (FromToR a b)) }
-
-fromThenToE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
-fromThenToE x y z = do { a <- x; b <- y; c <- z;
- return (ArithSeqE (FromThenToR a b c)) }
-
+import Language.Haskell.TH.Lib.Internal hiding
+ ( tySynD
+ , dataD
+ , newtypeD
+ , classD
+ , dataInstD
+ , newtypeInstD
+ , dataFamilyD
+ , openTypeFamilyD
+ , closedTypeFamilyD
+ , forallC
+
+ , forallT
+ , sigT
+
+ , plainTV
+ , kindedTV
+ , starK
+ , constraintK
+
+ , noSig
+ , kindSig
+ , tyVarSig
+
+ , Role
+ , InjectivityAnn
+ )
+import Language.Haskell.TH.Syntax
+
+import Control.Monad (liftM2)
+
+-- All definitions below represent the "old" API, since their definitions are
+-- different in Language.Haskell.TH.Lib.Internal. Please think carefully before
+-- deciding to change the APIs of the functions below, as they represent the
+-- public API (as opposed to the Internal module, which has no API promises.)
-------------------------------------------------------------------------------
-- * Dec
-valD :: PatQ -> BodyQ -> [DecQ] -> DecQ
-valD p b ds =
- do { p' <- p
- ; ds' <- sequence ds
- ; b' <- b
- ; return (ValD p' b' ds')
- }
-
-funD :: Name -> [ClauseQ] -> DecQ
-funD nm cs =
- do { cs1 <- sequence cs
- ; return (FunD nm cs1)
- }
-
tySynD :: Name -> [TyVarBndr] -> TypeQ -> DecQ
tySynD tc tvs rhs = do { rhs1 <- rhs; return (TySynD tc tvs rhs1) }
@@ -491,78 +184,6 @@ classD ctxt cls tvs fds decs =
ctxt1 <- ctxt
return $ ClassD ctxt1 cls tvs fds decs1
-instanceD :: CxtQ -> TypeQ -> [DecQ] -> DecQ
-instanceD = instanceWithOverlapD Nothing
-
-instanceWithOverlapD :: Maybe Overlap -> CxtQ -> TypeQ -> [DecQ] -> DecQ
-instanceWithOverlapD o ctxt ty decs =
- do
- ctxt1 <- ctxt
- decs1 <- sequence decs
- ty1 <- ty
- return $ InstanceD o ctxt1 ty1 decs1
-
-
-
-sigD :: Name -> TypeQ -> DecQ
-sigD fun ty = liftM (SigD fun) $ ty
-
-forImpD :: Callconv -> Safety -> String -> Name -> TypeQ -> DecQ
-forImpD cc s str n ty
- = do ty' <- ty
- return $ ForeignD (ImportF cc s str n ty')
-
-infixLD :: Int -> Name -> DecQ
-infixLD prec nm = return (InfixD (Fixity prec InfixL) nm)
-
-infixRD :: Int -> Name -> DecQ
-infixRD prec nm = return (InfixD (Fixity prec InfixR) nm)
-
-infixND :: Int -> Name -> DecQ
-infixND prec nm = return (InfixD (Fixity prec InfixN) nm)
-
-pragInlD :: Name -> Inline -> RuleMatch -> Phases -> DecQ
-pragInlD name inline rm phases
- = return $ PragmaD $ InlineP name inline rm phases
-
-pragSpecD :: Name -> TypeQ -> Phases -> DecQ
-pragSpecD n ty phases
- = do
- ty1 <- ty
- return $ PragmaD $ SpecialiseP n ty1 Nothing phases
-
-pragSpecInlD :: Name -> TypeQ -> Inline -> Phases -> DecQ
-pragSpecInlD n ty inline phases
- = do
- ty1 <- ty
- return $ PragmaD $ SpecialiseP n ty1 (Just inline) phases
-
-pragSpecInstD :: TypeQ -> DecQ
-pragSpecInstD ty
- = do
- ty1 <- ty
- return $ PragmaD $ SpecialiseInstP ty1
-
-pragRuleD :: String -> [RuleBndrQ] -> ExpQ -> ExpQ -> Phases -> DecQ
-pragRuleD n bndrs lhs rhs phases
- = do
- bndrs1 <- sequence bndrs
- lhs1 <- lhs
- rhs1 <- rhs
- return $ PragmaD $ RuleP n bndrs1 lhs1 rhs1 phases
-
-pragAnnD :: AnnTarget -> ExpQ -> DecQ
-pragAnnD target expr
- = do
- exp1 <- expr
- return $ PragmaD $ AnnP target exp1
-
-pragLineD :: Int -> String -> DecQ
-pragLineD line file = return $ PragmaD $ LineP line file
-
-pragCompleteD :: [Name] -> Maybe Name -> DecQ
-pragCompleteD cls mty = return $ PragmaD $ CompleteP cls mty
-
dataInstD :: CxtQ -> Name -> [TypeQ] -> Maybe Kind -> [ConQ] -> [DerivClauseQ]
-> DecQ
dataInstD ctxt tc tys ksig cons derivs =
@@ -583,12 +204,6 @@ newtypeInstD ctxt tc tys ksig con derivs =
derivs1 <- sequence derivs
return (NewtypeInstD ctxt1 tc tys1 ksig con1 derivs1)
-tySynInstD :: Name -> TySynEqnQ -> DecQ
-tySynInstD tc eqn =
- do
- eqn1 <- eqn
- return (TySynInstD tc eqn1)
-
dataFamilyD :: Name -> [TyVarBndr] -> Maybe Kind -> DecQ
dataFamilyD tc tvs kind
= return $ DataFamilyD tc tvs kind
@@ -604,112 +219,9 @@ closedTypeFamilyD tc tvs result injectivity eqns =
do eqns1 <- sequence eqns
return (ClosedTypeFamilyD (TypeFamilyHead tc tvs result injectivity) eqns1)
--- These were deprecated in GHC 8.0 with a plan to remove them in 8.2. If you
--- remove this check please also:
--- 1. remove deprecated functions
--- 2. remove CPP language extension from top of this module
--- 3. remove the FamFlavour data type from Syntax module
--- 4. make sure that all references to FamFlavour are gone from DsMeta,
--- Convert, TcSplice (follows from 3)
-#if __GLASGOW_HASKELL__ >= 804
-#error Remove deprecated familyNoKindD, familyKindD, closedTypeFamilyNoKindD and closedTypeFamilyKindD
-#endif
-
-{-# DEPRECATED familyNoKindD, familyKindD
- "This function will be removed in the next stable release. Use openTypeFamilyD/dataFamilyD instead." #-}
-familyNoKindD :: FamFlavour -> Name -> [TyVarBndr] -> DecQ
-familyNoKindD flav tc tvs =
- case flav of
- TypeFam -> return $ OpenTypeFamilyD (TypeFamilyHead tc tvs NoSig Nothing)
- DataFam -> return $ DataFamilyD tc tvs Nothing
-
-familyKindD :: FamFlavour -> Name -> [TyVarBndr] -> Kind -> DecQ
-familyKindD flav tc tvs k =
- case flav of
- TypeFam ->
- return $ OpenTypeFamilyD (TypeFamilyHead tc tvs (KindSig k) Nothing)
- DataFam -> return $ DataFamilyD tc tvs (Just k)
-
-{-# DEPRECATED closedTypeFamilyNoKindD, closedTypeFamilyKindD
- "This function will be removed in the next stable release. Use closedTypeFamilyD instead." #-}
-closedTypeFamilyNoKindD :: Name -> [TyVarBndr] -> [TySynEqnQ] -> DecQ
-closedTypeFamilyNoKindD tc tvs eqns =
- do eqns1 <- sequence eqns
- return (ClosedTypeFamilyD (TypeFamilyHead tc tvs NoSig Nothing) eqns1)
-
-closedTypeFamilyKindD :: Name -> [TyVarBndr] -> Kind -> [TySynEqnQ] -> DecQ
-closedTypeFamilyKindD tc tvs kind eqns =
- do eqns1 <- sequence eqns
- return (ClosedTypeFamilyD (TypeFamilyHead tc tvs (KindSig kind) Nothing)
- eqns1)
-
-roleAnnotD :: Name -> [Role] -> DecQ
-roleAnnotD name roles = return $ RoleAnnotD name roles
-
-standaloneDerivD :: CxtQ -> TypeQ -> DecQ
-standaloneDerivD = standaloneDerivWithStrategyD Nothing
-
-standaloneDerivWithStrategyD :: Maybe DerivStrategy -> CxtQ -> TypeQ -> DecQ
-standaloneDerivWithStrategyD ds ctxtq tyq =
- do
- ctxt <- ctxtq
- ty <- tyq
- return $ StandaloneDerivD ds ctxt ty
-
-defaultSigD :: Name -> TypeQ -> DecQ
-defaultSigD n tyq =
- do
- ty <- tyq
- return $ DefaultSigD n ty
-
--- | Pattern synonym declaration
-patSynD :: Name -> PatSynArgsQ -> PatSynDirQ -> PatQ -> DecQ
-patSynD name args dir pat = do
- args' <- args
- dir' <- dir
- pat' <- pat
- return (PatSynD name args' dir' pat')
-
--- | Pattern synonym type signature
-patSynSigD :: Name -> TypeQ -> DecQ
-patSynSigD nm ty =
- do ty' <- ty
- return $ PatSynSigD nm ty'
-
-tySynEqn :: [TypeQ] -> TypeQ -> TySynEqnQ
-tySynEqn lhs rhs =
- do
- lhs1 <- sequence lhs
- rhs1 <- rhs
- return (TySynEqn lhs1 rhs1)
-
-cxt :: [PredQ] -> CxtQ
-cxt = sequence
-
-derivClause :: Maybe DerivStrategy -> [PredQ] -> DerivClauseQ
-derivClause ds p = do p' <- cxt p
- return $ DerivClause ds p'
-
-normalC :: Name -> [BangTypeQ] -> ConQ
-normalC con strtys = liftM (NormalC con) $ sequence strtys
-
-recC :: Name -> [VarBangTypeQ] -> ConQ
-recC con varstrtys = liftM (RecC con) $ sequence varstrtys
-
-infixC :: Q (Bang, Type) -> Name -> Q (Bang, Type) -> ConQ
-infixC st1 con st2 = do st1' <- st1
- st2' <- st2
- return $ InfixC st1' con st2'
-
forallC :: [TyVarBndr] -> CxtQ -> ConQ -> ConQ
forallC ns ctxt con = liftM2 (ForallC ns) ctxt con
-gadtC :: [Name] -> [StrictTypeQ] -> TypeQ -> ConQ
-gadtC cons strtys ty = liftM2 (GadtC cons) (sequence strtys) ty
-
-recGadtC :: [Name] -> [VarStrictTypeQ] -> TypeQ -> ConQ
-recGadtC cons varstrtys ty = liftM2 (RecGadtC cons) (sequence varstrtys) ty
-
-------------------------------------------------------------------------------
-- * Type
@@ -719,145 +231,12 @@ forallT tvars ctxt ty = do
ty1 <- ty
return $ ForallT tvars ctxt1 ty1
-varT :: Name -> TypeQ
-varT = return . VarT
-
-conT :: Name -> TypeQ
-conT = return . ConT
-
-infixT :: TypeQ -> Name -> TypeQ -> TypeQ
-infixT t1 n t2 = do t1' <- t1
- t2' <- t2
- return (InfixT t1' n t2')
-
-uInfixT :: TypeQ -> Name -> TypeQ -> TypeQ
-uInfixT t1 n t2 = do t1' <- t1
- t2' <- t2
- return (UInfixT t1' n t2')
-
-parensT :: TypeQ -> TypeQ
-parensT t = do t' <- t
- return (ParensT t')
-
-appT :: TypeQ -> TypeQ -> TypeQ
-appT t1 t2 = do
- t1' <- t1
- t2' <- t2
- return $ AppT t1' t2'
-
-arrowT :: TypeQ
-arrowT = return ArrowT
-
-listT :: TypeQ
-listT = return ListT
-
-litT :: TyLitQ -> TypeQ
-litT l = fmap LitT l
-
-tupleT :: Int -> TypeQ
-tupleT i = return (TupleT i)
-
-unboxedTupleT :: Int -> TypeQ
-unboxedTupleT i = return (UnboxedTupleT i)
-
-unboxedSumT :: SumArity -> TypeQ
-unboxedSumT arity = return (UnboxedSumT arity)
-
sigT :: TypeQ -> Kind -> TypeQ
sigT t k
= do
t' <- t
return $ SigT t' k
-equalityT :: TypeQ
-equalityT = return EqualityT
-
-wildCardT :: TypeQ
-wildCardT = return WildCardT
-
-{-# DEPRECATED classP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please use 'conT' and 'appT'." #-}
-classP :: Name -> [Q Type] -> Q Pred
-classP cla tys
- = do
- tysl <- sequence tys
- return (foldl AppT (ConT cla) tysl)
-
-{-# DEPRECATED equalP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please see 'equalityT'." #-}
-equalP :: TypeQ -> TypeQ -> PredQ
-equalP tleft tright
- = do
- tleft1 <- tleft
- tright1 <- tright
- eqT <- equalityT
- return (foldl AppT eqT [tleft1, tright1])
-
-promotedT :: Name -> TypeQ
-promotedT = return . PromotedT
-
-promotedTupleT :: Int -> TypeQ
-promotedTupleT i = return (PromotedTupleT i)
-
-promotedNilT :: TypeQ
-promotedNilT = return PromotedNilT
-
-promotedConsT :: TypeQ
-promotedConsT = return PromotedConsT
-
-noSourceUnpackedness, sourceNoUnpack, sourceUnpack :: SourceUnpackednessQ
-noSourceUnpackedness = return NoSourceUnpackedness
-sourceNoUnpack = return SourceNoUnpack
-sourceUnpack = return SourceUnpack
-
-noSourceStrictness, sourceLazy, sourceStrict :: SourceStrictnessQ
-noSourceStrictness = return NoSourceStrictness
-sourceLazy = return SourceLazy
-sourceStrict = return SourceStrict
-
-{-# DEPRECATED isStrict
- ["Use 'bang'. See https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0. ",
- "Example usage: 'bang noSourceUnpackedness sourceStrict'"] #-}
-{-# DEPRECATED notStrict
- ["Use 'bang'. See https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0. ",
- "Example usage: 'bang noSourceUnpackedness noSourceStrictness'"] #-}
-{-# DEPRECATED unpacked
- ["Use 'bang'. See https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0. ",
- "Example usage: 'bang sourceUnpack sourceStrict'"] #-}
-isStrict, notStrict, unpacked :: Q Strict
-isStrict = bang noSourceUnpackedness sourceStrict
-notStrict = bang noSourceUnpackedness noSourceStrictness
-unpacked = bang sourceUnpack sourceStrict
-
-bang :: SourceUnpackednessQ -> SourceStrictnessQ -> BangQ
-bang u s = do u' <- u
- s' <- s
- return (Bang u' s')
-
-bangType :: BangQ -> TypeQ -> BangTypeQ
-bangType = liftM2 (,)
-
-varBangType :: Name -> BangTypeQ -> VarBangTypeQ
-varBangType v bt = do (b, t) <- bt
- return (v, b, t)
-
-{-# DEPRECATED strictType
- "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'bangType' instead." #-}
-strictType :: Q Strict -> TypeQ -> StrictTypeQ
-strictType = bangType
-
-{-# DEPRECATED varStrictType
- "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'varBangType' instead." #-}
-varStrictType :: Name -> StrictTypeQ -> VarStrictTypeQ
-varStrictType = varBangType
-
--- * Type Literals
-
-numTyLit :: Integer -> TyLitQ
-numTyLit n = if n >= 0 then return (NumTyLit n)
- else fail ("Negative type-level number: " ++ show n)
-
-strTyLit :: String -> TyLitQ
-strTyLit s = return (StrTyLit s)
-
-------------------------------------------------------------------------------
-- * Kind
@@ -867,24 +246,6 @@ plainTV = PlainTV
kindedTV :: Name -> Kind -> TyVarBndr
kindedTV = KindedTV
-varK :: Name -> Kind
-varK = VarT
-
-conK :: Name -> Kind
-conK = ConT
-
-tupleK :: Int -> Kind
-tupleK = TupleT
-
-arrowK :: Kind
-arrowK = ArrowT
-
-listK :: Kind
-listK = ListT
-
-appK :: Kind -> Kind -> Kind
-appK = AppT
-
starK :: Kind
starK = StarT
@@ -902,104 +263,3 @@ kindSig = KindSig
tyVarSig :: TyVarBndr -> FamilyResultSig
tyVarSig = TyVarSig
-
--------------------------------------------------------------------------------
--- * Injectivity annotation
-
-injectivityAnn :: Name -> [Name] -> InjectivityAnn
-injectivityAnn = TH.InjectivityAnn
-
--------------------------------------------------------------------------------
--- * Role
-
-nominalR, representationalR, phantomR, inferR :: Role
-nominalR = NominalR
-representationalR = RepresentationalR
-phantomR = PhantomR
-inferR = InferR
-
--------------------------------------------------------------------------------
--- * Callconv
-
-cCall, stdCall, cApi, prim, javaScript :: Callconv
-cCall = CCall
-stdCall = StdCall
-cApi = CApi
-prim = Prim
-javaScript = JavaScript
-
--------------------------------------------------------------------------------
--- * Safety
-
-unsafe, safe, interruptible :: Safety
-unsafe = Unsafe
-safe = Safe
-interruptible = Interruptible
-
--------------------------------------------------------------------------------
--- * FunDep
-
-funDep :: [Name] -> [Name] -> FunDep
-funDep = FunDep
-
--------------------------------------------------------------------------------
--- * FamFlavour
-
-typeFam, dataFam :: FamFlavour
-typeFam = TypeFam
-dataFam = DataFam
-
--------------------------------------------------------------------------------
--- * RuleBndr
-ruleVar :: Name -> RuleBndrQ
-ruleVar = return . RuleVar
-
-typedRuleVar :: Name -> TypeQ -> RuleBndrQ
-typedRuleVar n ty = ty >>= return . TypedRuleVar n
-
--------------------------------------------------------------------------------
--- * AnnTarget
-valueAnnotation :: Name -> AnnTarget
-valueAnnotation = ValueAnnotation
-
-typeAnnotation :: Name -> AnnTarget
-typeAnnotation = TypeAnnotation
-
-moduleAnnotation :: AnnTarget
-moduleAnnotation = ModuleAnnotation
-
--------------------------------------------------------------------------------
--- * Pattern Synonyms (sub constructs)
-
-unidir, implBidir :: PatSynDirQ
-unidir = return Unidir
-implBidir = return ImplBidir
-
-explBidir :: [ClauseQ] -> PatSynDirQ
-explBidir cls = do
- cls' <- sequence cls
- return (ExplBidir cls')
-
-prefixPatSyn :: [Name] -> PatSynArgsQ
-prefixPatSyn args = return $ PrefixPatSyn args
-
-recordPatSyn :: [Name] -> PatSynArgsQ
-recordPatSyn sels = return $ RecordPatSyn sels
-
-infixPatSyn :: Name -> Name -> PatSynArgsQ
-infixPatSyn arg1 arg2 = return $ InfixPatSyn arg1 arg2
-
---------------------------------------------------------------
--- * Useful helper function
-
-appsE :: [ExpQ] -> ExpQ
-appsE [] = error "appsE []"
-appsE [x] = x
-appsE (x:y:zs) = appsE ( (appE x y) : zs )
-
--- | Return the Module at the place of splicing. Can be used as an
--- input for 'reifyModule'.
-thisModule :: Q Module
-thisModule = do
- loc <- location
- return $ Module (mkPkgName $ loc_package loc) (mkModName $ loc_module loc)
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
new file mode 100644
index 0000000000..d58ce84f99
--- /dev/null
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
@@ -0,0 +1,936 @@
+-- |
+-- Language.Haskell.TH.Lib.Internal exposes some additional functionality that
+-- is used internally in GHC's integration with Template Haskell. This is not a
+-- part of the public API, and as such, there are no API guarantees for this
+-- module from version to version.
+
+-- Why do we have both Language.Haskell.TH.Lib.Internal and
+-- Language.Haskell.TH.Lib? Ultimately, it's because the functions in the
+-- former (which are tailored for GHC's use) need different type signatures
+-- than the ones in the latter. Syncing up the Internal type signatures would
+-- involve a massive amount of breaking changes, so for the time being, we
+-- relegate as many changes as we can to just the Internal module, where it
+-- is safe to break things.
+
+{-# LANGUAGE CPP #-}
+
+module Language.Haskell.TH.Lib.Internal where
+
+import Language.Haskell.TH.Syntax hiding (Role, InjectivityAnn)
+import qualified Language.Haskell.TH.Syntax as TH
+import Control.Monad( liftM, liftM2 )
+import Data.Word( Word8 )
+
+----------------------------------------------------------
+-- * Type synonyms
+----------------------------------------------------------
+
+type InfoQ = Q Info
+type PatQ = Q Pat
+type FieldPatQ = Q FieldPat
+type ExpQ = Q Exp
+type TExpQ a = Q (TExp a)
+type DecQ = Q Dec
+type DecsQ = Q [Dec]
+type ConQ = Q Con
+type TypeQ = Q Type
+type KindQ = Q Kind
+type TyVarBndrQ = Q TyVarBndr
+type TyLitQ = Q TyLit
+type CxtQ = Q Cxt
+type PredQ = Q Pred
+type DerivClauseQ = Q DerivClause
+type MatchQ = Q Match
+type ClauseQ = Q Clause
+type BodyQ = Q Body
+type GuardQ = Q Guard
+type StmtQ = Q Stmt
+type RangeQ = Q Range
+type SourceStrictnessQ = Q SourceStrictness
+type SourceUnpackednessQ = Q SourceUnpackedness
+type BangQ = Q Bang
+type BangTypeQ = Q BangType
+type VarBangTypeQ = Q VarBangType
+type StrictTypeQ = Q StrictType
+type VarStrictTypeQ = Q VarStrictType
+type FieldExpQ = Q FieldExp
+type RuleBndrQ = Q RuleBndr
+type TySynEqnQ = Q TySynEqn
+type PatSynDirQ = Q PatSynDir
+type PatSynArgsQ = Q PatSynArgs
+type FamilyResultSigQ = Q FamilyResultSig
+
+-- must be defined here for DsMeta to find it
+type Role = TH.Role
+type InjectivityAnn = TH.InjectivityAnn
+
+----------------------------------------------------------
+-- * Lowercase pattern syntax functions
+----------------------------------------------------------
+
+intPrimL :: Integer -> Lit
+intPrimL = IntPrimL
+wordPrimL :: Integer -> Lit
+wordPrimL = WordPrimL
+floatPrimL :: Rational -> Lit
+floatPrimL = FloatPrimL
+doublePrimL :: Rational -> Lit
+doublePrimL = DoublePrimL
+integerL :: Integer -> Lit
+integerL = IntegerL
+charL :: Char -> Lit
+charL = CharL
+charPrimL :: Char -> Lit
+charPrimL = CharPrimL
+stringL :: String -> Lit
+stringL = StringL
+stringPrimL :: [Word8] -> Lit
+stringPrimL = StringPrimL
+rationalL :: Rational -> Lit
+rationalL = RationalL
+
+litP :: Lit -> PatQ
+litP l = return (LitP l)
+
+varP :: Name -> PatQ
+varP v = return (VarP v)
+
+tupP :: [PatQ] -> PatQ
+tupP ps = do { ps1 <- sequence ps; return (TupP ps1)}
+
+unboxedTupP :: [PatQ] -> PatQ
+unboxedTupP ps = do { ps1 <- sequence ps; return (UnboxedTupP ps1)}
+
+unboxedSumP :: PatQ -> SumAlt -> SumArity -> PatQ
+unboxedSumP p alt arity = do { p1 <- p; return (UnboxedSumP p1 alt arity) }
+
+conP :: Name -> [PatQ] -> PatQ
+conP n ps = do ps' <- sequence ps
+ return (ConP n ps')
+infixP :: PatQ -> Name -> PatQ -> PatQ
+infixP p1 n p2 = do p1' <- p1
+ p2' <- p2
+ return (InfixP p1' n p2')
+uInfixP :: PatQ -> Name -> PatQ -> PatQ
+uInfixP p1 n p2 = do p1' <- p1
+ p2' <- p2
+ return (UInfixP p1' n p2')
+parensP :: PatQ -> PatQ
+parensP p = do p' <- p
+ return (ParensP p')
+
+tildeP :: PatQ -> PatQ
+tildeP p = do p' <- p
+ return (TildeP p')
+bangP :: PatQ -> PatQ
+bangP p = do p' <- p
+ return (BangP p')
+asP :: Name -> PatQ -> PatQ
+asP n p = do p' <- p
+ return (AsP n p')
+wildP :: PatQ
+wildP = return WildP
+recP :: Name -> [FieldPatQ] -> PatQ
+recP n fps = do fps' <- sequence fps
+ return (RecP n fps')
+listP :: [PatQ] -> PatQ
+listP ps = do ps' <- sequence ps
+ return (ListP ps')
+sigP :: PatQ -> TypeQ -> PatQ
+sigP p t = do p' <- p
+ t' <- t
+ return (SigP p' t')
+viewP :: ExpQ -> PatQ -> PatQ
+viewP e p = do e' <- e
+ p' <- p
+ return (ViewP e' p')
+
+fieldPat :: Name -> PatQ -> FieldPatQ
+fieldPat n p = do p' <- p
+ return (n, p')
+
+
+-------------------------------------------------------------------------------
+-- * Stmt
+
+bindS :: PatQ -> ExpQ -> StmtQ
+bindS p e = liftM2 BindS p e
+
+letS :: [DecQ] -> StmtQ
+letS ds = do { ds1 <- sequence ds; return (LetS ds1) }
+
+noBindS :: ExpQ -> StmtQ
+noBindS e = do { e1 <- e; return (NoBindS e1) }
+
+parS :: [[StmtQ]] -> StmtQ
+parS sss = do { sss1 <- mapM sequence sss; return (ParS sss1) }
+
+-------------------------------------------------------------------------------
+-- * Range
+
+fromR :: ExpQ -> RangeQ
+fromR x = do { a <- x; return (FromR a) }
+
+fromThenR :: ExpQ -> ExpQ -> RangeQ
+fromThenR x y = do { a <- x; b <- y; return (FromThenR a b) }
+
+fromToR :: ExpQ -> ExpQ -> RangeQ
+fromToR x y = do { a <- x; b <- y; return (FromToR a b) }
+
+fromThenToR :: ExpQ -> ExpQ -> ExpQ -> RangeQ
+fromThenToR x y z = do { a <- x; b <- y; c <- z;
+ return (FromThenToR a b c) }
+-------------------------------------------------------------------------------
+-- * Body
+
+normalB :: ExpQ -> BodyQ
+normalB e = do { e1 <- e; return (NormalB e1) }
+
+guardedB :: [Q (Guard,Exp)] -> BodyQ
+guardedB ges = do { ges' <- sequence ges; return (GuardedB ges') }
+
+-------------------------------------------------------------------------------
+-- * Guard
+
+normalG :: ExpQ -> GuardQ
+normalG e = do { e1 <- e; return (NormalG e1) }
+
+normalGE :: ExpQ -> ExpQ -> Q (Guard, Exp)
+normalGE g e = do { g1 <- g; e1 <- e; return (NormalG g1, e1) }
+
+patG :: [StmtQ] -> GuardQ
+patG ss = do { ss' <- sequence ss; return (PatG ss') }
+
+patGE :: [StmtQ] -> ExpQ -> Q (Guard, Exp)
+patGE ss e = do { ss' <- sequence ss;
+ e' <- e;
+ return (PatG ss', e') }
+
+-------------------------------------------------------------------------------
+-- * Match and Clause
+
+-- | Use with 'caseE'
+match :: PatQ -> BodyQ -> [DecQ] -> MatchQ
+match p rhs ds = do { p' <- p;
+ r' <- rhs;
+ ds' <- sequence ds;
+ return (Match p' r' ds') }
+
+-- | Use with 'funD'
+clause :: [PatQ] -> BodyQ -> [DecQ] -> ClauseQ
+clause ps r ds = do { ps' <- sequence ps;
+ r' <- r;
+ ds' <- sequence ds;
+ return (Clause ps' r' ds') }
+
+
+---------------------------------------------------------------------------
+-- * Exp
+
+-- | Dynamically binding a variable (unhygenic)
+dyn :: String -> ExpQ
+dyn s = return (VarE (mkName s))
+
+varE :: Name -> ExpQ
+varE s = return (VarE s)
+
+conE :: Name -> ExpQ
+conE s = return (ConE s)
+
+litE :: Lit -> ExpQ
+litE c = return (LitE c)
+
+appE :: ExpQ -> ExpQ -> ExpQ
+appE x y = do { a <- x; b <- y; return (AppE a b)}
+
+appTypeE :: ExpQ -> TypeQ -> ExpQ
+appTypeE x t = do { a <- x; s <- t; return (AppTypeE a s) }
+
+parensE :: ExpQ -> ExpQ
+parensE x = do { x' <- x; return (ParensE x') }
+
+uInfixE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+uInfixE x s y = do { x' <- x; s' <- s; y' <- y;
+ return (UInfixE x' s' y') }
+
+infixE :: Maybe ExpQ -> ExpQ -> Maybe ExpQ -> ExpQ
+infixE (Just x) s (Just y) = do { a <- x; s' <- s; b <- y;
+ return (InfixE (Just a) s' (Just b))}
+infixE Nothing s (Just y) = do { s' <- s; b <- y;
+ return (InfixE Nothing s' (Just b))}
+infixE (Just x) s Nothing = do { a <- x; s' <- s;
+ return (InfixE (Just a) s' Nothing)}
+infixE Nothing s Nothing = do { s' <- s; return (InfixE Nothing s' Nothing) }
+
+infixApp :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+infixApp x y z = infixE (Just x) y (Just z)
+sectionL :: ExpQ -> ExpQ -> ExpQ
+sectionL x y = infixE (Just x) y Nothing
+sectionR :: ExpQ -> ExpQ -> ExpQ
+sectionR x y = infixE Nothing x (Just y)
+
+lamE :: [PatQ] -> ExpQ -> ExpQ
+lamE ps e = do ps' <- sequence ps
+ e' <- e
+ return (LamE ps' e')
+
+-- | Single-arg lambda
+lam1E :: PatQ -> ExpQ -> ExpQ
+lam1E p e = lamE [p] e
+
+lamCaseE :: [MatchQ] -> ExpQ
+lamCaseE ms = sequence ms >>= return . LamCaseE
+
+tupE :: [ExpQ] -> ExpQ
+tupE es = do { es1 <- sequence es; return (TupE es1)}
+
+unboxedTupE :: [ExpQ] -> ExpQ
+unboxedTupE es = do { es1 <- sequence es; return (UnboxedTupE es1)}
+
+unboxedSumE :: ExpQ -> SumAlt -> SumArity -> ExpQ
+unboxedSumE e alt arity = do { e1 <- e; return (UnboxedSumE e1 alt arity) }
+
+condE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+condE x y z = do { a <- x; b <- y; c <- z; return (CondE a b c)}
+
+multiIfE :: [Q (Guard, Exp)] -> ExpQ
+multiIfE alts = sequence alts >>= return . MultiIfE
+
+letE :: [DecQ] -> ExpQ -> ExpQ
+letE ds e = do { ds2 <- sequence ds; e2 <- e; return (LetE ds2 e2) }
+
+caseE :: ExpQ -> [MatchQ] -> ExpQ
+caseE e ms = do { e1 <- e; ms1 <- sequence ms; return (CaseE e1 ms1) }
+
+doE :: [StmtQ] -> ExpQ
+doE ss = do { ss1 <- sequence ss; return (DoE ss1) }
+
+compE :: [StmtQ] -> ExpQ
+compE ss = do { ss1 <- sequence ss; return (CompE ss1) }
+
+arithSeqE :: RangeQ -> ExpQ
+arithSeqE r = do { r' <- r; return (ArithSeqE r') }
+
+listE :: [ExpQ] -> ExpQ
+listE es = do { es1 <- sequence es; return (ListE es1) }
+
+sigE :: ExpQ -> TypeQ -> ExpQ
+sigE e t = do { e1 <- e; t1 <- t; return (SigE e1 t1) }
+
+recConE :: Name -> [Q (Name,Exp)] -> ExpQ
+recConE c fs = do { flds <- sequence fs; return (RecConE c flds) }
+
+recUpdE :: ExpQ -> [Q (Name,Exp)] -> ExpQ
+recUpdE e fs = do { e1 <- e; flds <- sequence fs; return (RecUpdE e1 flds) }
+
+stringE :: String -> ExpQ
+stringE = litE . stringL
+
+fieldExp :: Name -> ExpQ -> Q (Name, Exp)
+fieldExp s e = do { e' <- e; return (s,e') }
+
+-- | @staticE x = [| static x |]@
+staticE :: ExpQ -> ExpQ
+staticE = fmap StaticE
+
+unboundVarE :: Name -> ExpQ
+unboundVarE s = return (UnboundVarE s)
+
+labelE :: String -> ExpQ
+labelE s = return (LabelE s)
+
+-- ** 'arithSeqE' Shortcuts
+fromE :: ExpQ -> ExpQ
+fromE x = do { a <- x; return (ArithSeqE (FromR a)) }
+
+fromThenE :: ExpQ -> ExpQ -> ExpQ
+fromThenE x y = do { a <- x; b <- y; return (ArithSeqE (FromThenR a b)) }
+
+fromToE :: ExpQ -> ExpQ -> ExpQ
+fromToE x y = do { a <- x; b <- y; return (ArithSeqE (FromToR a b)) }
+
+fromThenToE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+fromThenToE x y z = do { a <- x; b <- y; c <- z;
+ return (ArithSeqE (FromThenToR a b c)) }
+
+
+-------------------------------------------------------------------------------
+-- * Dec
+
+valD :: PatQ -> BodyQ -> [DecQ] -> DecQ
+valD p b ds =
+ do { p' <- p
+ ; ds' <- sequence ds
+ ; b' <- b
+ ; return (ValD p' b' ds')
+ }
+
+funD :: Name -> [ClauseQ] -> DecQ
+funD nm cs =
+ do { cs1 <- sequence cs
+ ; return (FunD nm cs1)
+ }
+
+tySynD :: Name -> [TyVarBndrQ] -> TypeQ -> DecQ
+tySynD tc tvs rhs =
+ do { tvs1 <- sequenceA tvs
+ ; rhs1 <- rhs
+ ; return (TySynD tc tvs1 rhs1)
+ }
+
+dataD :: CxtQ -> Name -> [TyVarBndrQ] -> Maybe KindQ -> [ConQ]
+ -> [DerivClauseQ] -> DecQ
+dataD ctxt tc tvs ksig cons derivs =
+ do
+ ctxt1 <- ctxt
+ tvs1 <- sequenceA tvs
+ ksig1 <- sequenceA ksig
+ cons1 <- sequence cons
+ derivs1 <- sequence derivs
+ return (DataD ctxt1 tc tvs1 ksig1 cons1 derivs1)
+
+newtypeD :: CxtQ -> Name -> [TyVarBndrQ] -> Maybe KindQ -> ConQ
+ -> [DerivClauseQ] -> DecQ
+newtypeD ctxt tc tvs ksig con derivs =
+ do
+ ctxt1 <- ctxt
+ tvs1 <- sequenceA tvs
+ ksig1 <- sequenceA ksig
+ con1 <- con
+ derivs1 <- sequence derivs
+ return (NewtypeD ctxt1 tc tvs1 ksig1 con1 derivs1)
+
+classD :: CxtQ -> Name -> [TyVarBndrQ] -> [FunDep] -> [DecQ] -> DecQ
+classD ctxt cls tvs fds decs =
+ do
+ tvs1 <- sequenceA tvs
+ decs1 <- sequenceA decs
+ ctxt1 <- ctxt
+ return $ ClassD ctxt1 cls tvs1 fds decs1
+
+instanceD :: CxtQ -> TypeQ -> [DecQ] -> DecQ
+instanceD = instanceWithOverlapD Nothing
+
+instanceWithOverlapD :: Maybe Overlap -> CxtQ -> TypeQ -> [DecQ] -> DecQ
+instanceWithOverlapD o ctxt ty decs =
+ do
+ ctxt1 <- ctxt
+ decs1 <- sequence decs
+ ty1 <- ty
+ return $ InstanceD o ctxt1 ty1 decs1
+
+
+
+sigD :: Name -> TypeQ -> DecQ
+sigD fun ty = liftM (SigD fun) $ ty
+
+forImpD :: Callconv -> Safety -> String -> Name -> TypeQ -> DecQ
+forImpD cc s str n ty
+ = do ty' <- ty
+ return $ ForeignD (ImportF cc s str n ty')
+
+infixLD :: Int -> Name -> DecQ
+infixLD prec nm = return (InfixD (Fixity prec InfixL) nm)
+
+infixRD :: Int -> Name -> DecQ
+infixRD prec nm = return (InfixD (Fixity prec InfixR) nm)
+
+infixND :: Int -> Name -> DecQ
+infixND prec nm = return (InfixD (Fixity prec InfixN) nm)
+
+pragInlD :: Name -> Inline -> RuleMatch -> Phases -> DecQ
+pragInlD name inline rm phases
+ = return $ PragmaD $ InlineP name inline rm phases
+
+pragSpecD :: Name -> TypeQ -> Phases -> DecQ
+pragSpecD n ty phases
+ = do
+ ty1 <- ty
+ return $ PragmaD $ SpecialiseP n ty1 Nothing phases
+
+pragSpecInlD :: Name -> TypeQ -> Inline -> Phases -> DecQ
+pragSpecInlD n ty inline phases
+ = do
+ ty1 <- ty
+ return $ PragmaD $ SpecialiseP n ty1 (Just inline) phases
+
+pragSpecInstD :: TypeQ -> DecQ
+pragSpecInstD ty
+ = do
+ ty1 <- ty
+ return $ PragmaD $ SpecialiseInstP ty1
+
+pragRuleD :: String -> [RuleBndrQ] -> ExpQ -> ExpQ -> Phases -> DecQ
+pragRuleD n bndrs lhs rhs phases
+ = do
+ bndrs1 <- sequence bndrs
+ lhs1 <- lhs
+ rhs1 <- rhs
+ return $ PragmaD $ RuleP n bndrs1 lhs1 rhs1 phases
+
+pragAnnD :: AnnTarget -> ExpQ -> DecQ
+pragAnnD target expr
+ = do
+ exp1 <- expr
+ return $ PragmaD $ AnnP target exp1
+
+pragLineD :: Int -> String -> DecQ
+pragLineD line file = return $ PragmaD $ LineP line file
+
+pragCompleteD :: [Name] -> Maybe Name -> DecQ
+pragCompleteD cls mty = return $ PragmaD $ CompleteP cls mty
+
+dataInstD :: CxtQ -> Name -> [TypeQ] -> Maybe KindQ -> [ConQ]
+ -> [DerivClauseQ] -> DecQ
+dataInstD ctxt tc tys ksig cons derivs =
+ do
+ ctxt1 <- ctxt
+ tys1 <- sequenceA tys
+ ksig1 <- sequenceA ksig
+ cons1 <- sequenceA cons
+ derivs1 <- sequenceA derivs
+ return (DataInstD ctxt1 tc tys1 ksig1 cons1 derivs1)
+
+newtypeInstD :: CxtQ -> Name -> [TypeQ] -> Maybe KindQ -> ConQ
+ -> [DerivClauseQ] -> DecQ
+newtypeInstD ctxt tc tys ksig con derivs =
+ do
+ ctxt1 <- ctxt
+ tys1 <- sequenceA tys
+ ksig1 <- sequenceA ksig
+ con1 <- con
+ derivs1 <- sequence derivs
+ return (NewtypeInstD ctxt1 tc tys1 ksig1 con1 derivs1)
+
+tySynInstD :: Name -> TySynEqnQ -> DecQ
+tySynInstD tc eqn =
+ do
+ eqn1 <- eqn
+ return (TySynInstD tc eqn1)
+
+dataFamilyD :: Name -> [TyVarBndrQ] -> Maybe KindQ -> DecQ
+dataFamilyD tc tvs kind =
+ do tvs' <- sequenceA tvs
+ kind' <- sequenceA kind
+ return $ DataFamilyD tc tvs' kind'
+
+openTypeFamilyD :: Name -> [TyVarBndrQ] -> FamilyResultSigQ
+ -> Maybe InjectivityAnn -> DecQ
+openTypeFamilyD tc tvs res inj =
+ do tvs' <- sequenceA tvs
+ res' <- res
+ return $ OpenTypeFamilyD (TypeFamilyHead tc tvs' res' inj)
+
+closedTypeFamilyD :: Name -> [TyVarBndrQ] -> FamilyResultSigQ
+ -> Maybe InjectivityAnn -> [TySynEqnQ] -> DecQ
+closedTypeFamilyD tc tvs result injectivity eqns =
+ do tvs1 <- sequenceA tvs
+ result1 <- result
+ eqns1 <- sequenceA eqns
+ return (ClosedTypeFamilyD (TypeFamilyHead tc tvs1 result1 injectivity) eqns1)
+
+-- These were deprecated in GHC 8.0 with a plan to remove them in 8.2. If you
+-- remove this check please also:
+-- 1. remove deprecated functions
+-- 2. remove CPP language extension from top of this module
+-- 3. remove the FamFlavour data type from Syntax module
+-- 4. make sure that all references to FamFlavour are gone from DsMeta,
+-- Convert, TcSplice (follows from 3)
+#if __GLASGOW_HASKELL__ >= 804
+#error Remove deprecated familyNoKindD, familyKindD, closedTypeFamilyNoKindD and closedTypeFamilyKindD
+#endif
+
+{-# DEPRECATED familyNoKindD, familyKindD
+ "This function will be removed in the next stable release. Use openTypeFamilyD/dataFamilyD instead." #-}
+familyNoKindD :: FamFlavour -> Name -> [TyVarBndr] -> DecQ
+familyNoKindD flav tc tvs =
+ case flav of
+ TypeFam -> return $ OpenTypeFamilyD (TypeFamilyHead tc tvs NoSig Nothing)
+ DataFam -> return $ DataFamilyD tc tvs Nothing
+
+familyKindD :: FamFlavour -> Name -> [TyVarBndr] -> Kind -> DecQ
+familyKindD flav tc tvs k =
+ case flav of
+ TypeFam ->
+ return $ OpenTypeFamilyD (TypeFamilyHead tc tvs (KindSig k) Nothing)
+ DataFam -> return $ DataFamilyD tc tvs (Just k)
+
+{-# DEPRECATED closedTypeFamilyNoKindD, closedTypeFamilyKindD
+ "This function will be removed in the next stable release. Use closedTypeFamilyD instead." #-}
+closedTypeFamilyNoKindD :: Name -> [TyVarBndr] -> [TySynEqnQ] -> DecQ
+closedTypeFamilyNoKindD tc tvs eqns =
+ do eqns1 <- sequence eqns
+ return (ClosedTypeFamilyD (TypeFamilyHead tc tvs NoSig Nothing) eqns1)
+
+closedTypeFamilyKindD :: Name -> [TyVarBndr] -> Kind -> [TySynEqnQ] -> DecQ
+closedTypeFamilyKindD tc tvs kind eqns =
+ do eqns1 <- sequence eqns
+ return (ClosedTypeFamilyD (TypeFamilyHead tc tvs (KindSig kind) Nothing)
+ eqns1)
+
+roleAnnotD :: Name -> [Role] -> DecQ
+roleAnnotD name roles = return $ RoleAnnotD name roles
+
+standaloneDerivD :: CxtQ -> TypeQ -> DecQ
+standaloneDerivD = standaloneDerivWithStrategyD Nothing
+
+standaloneDerivWithStrategyD :: Maybe DerivStrategy -> CxtQ -> TypeQ -> DecQ
+standaloneDerivWithStrategyD ds ctxtq tyq =
+ do
+ ctxt <- ctxtq
+ ty <- tyq
+ return $ StandaloneDerivD ds ctxt ty
+
+defaultSigD :: Name -> TypeQ -> DecQ
+defaultSigD n tyq =
+ do
+ ty <- tyq
+ return $ DefaultSigD n ty
+
+-- | Pattern synonym declaration
+patSynD :: Name -> PatSynArgsQ -> PatSynDirQ -> PatQ -> DecQ
+patSynD name args dir pat = do
+ args' <- args
+ dir' <- dir
+ pat' <- pat
+ return (PatSynD name args' dir' pat')
+
+-- | Pattern synonym type signature
+patSynSigD :: Name -> TypeQ -> DecQ
+patSynSigD nm ty =
+ do ty' <- ty
+ return $ PatSynSigD nm ty'
+
+tySynEqn :: [TypeQ] -> TypeQ -> TySynEqnQ
+tySynEqn lhs rhs =
+ do
+ lhs1 <- sequence lhs
+ rhs1 <- rhs
+ return (TySynEqn lhs1 rhs1)
+
+cxt :: [PredQ] -> CxtQ
+cxt = sequence
+
+derivClause :: Maybe DerivStrategy -> [PredQ] -> DerivClauseQ
+derivClause ds p = do p' <- cxt p
+ return $ DerivClause ds p'
+
+normalC :: Name -> [BangTypeQ] -> ConQ
+normalC con strtys = liftM (NormalC con) $ sequence strtys
+
+recC :: Name -> [VarBangTypeQ] -> ConQ
+recC con varstrtys = liftM (RecC con) $ sequence varstrtys
+
+infixC :: Q (Bang, Type) -> Name -> Q (Bang, Type) -> ConQ
+infixC st1 con st2 = do st1' <- st1
+ st2' <- st2
+ return $ InfixC st1' con st2'
+
+forallC :: [TyVarBndrQ] -> CxtQ -> ConQ -> ConQ
+forallC ns ctxt con = do
+ ns' <- sequenceA ns
+ ctxt' <- ctxt
+ con' <- con
+ pure $ ForallC ns' ctxt' con'
+
+gadtC :: [Name] -> [StrictTypeQ] -> TypeQ -> ConQ
+gadtC cons strtys ty = liftM2 (GadtC cons) (sequence strtys) ty
+
+recGadtC :: [Name] -> [VarStrictTypeQ] -> TypeQ -> ConQ
+recGadtC cons varstrtys ty = liftM2 (RecGadtC cons) (sequence varstrtys) ty
+
+-------------------------------------------------------------------------------
+-- * Type
+
+forallT :: [TyVarBndrQ] -> CxtQ -> TypeQ -> TypeQ
+forallT tvars ctxt ty = do
+ tvars1 <- sequenceA tvars
+ ctxt1 <- ctxt
+ ty1 <- ty
+ return $ ForallT tvars1 ctxt1 ty1
+
+varT :: Name -> TypeQ
+varT = return . VarT
+
+conT :: Name -> TypeQ
+conT = return . ConT
+
+infixT :: TypeQ -> Name -> TypeQ -> TypeQ
+infixT t1 n t2 = do t1' <- t1
+ t2' <- t2
+ return (InfixT t1' n t2')
+
+uInfixT :: TypeQ -> Name -> TypeQ -> TypeQ
+uInfixT t1 n t2 = do t1' <- t1
+ t2' <- t2
+ return (UInfixT t1' n t2')
+
+parensT :: TypeQ -> TypeQ
+parensT t = do t' <- t
+ return (ParensT t')
+
+appT :: TypeQ -> TypeQ -> TypeQ
+appT t1 t2 = do
+ t1' <- t1
+ t2' <- t2
+ return $ AppT t1' t2'
+
+arrowT :: TypeQ
+arrowT = return ArrowT
+
+listT :: TypeQ
+listT = return ListT
+
+litT :: TyLitQ -> TypeQ
+litT l = fmap LitT l
+
+tupleT :: Int -> TypeQ
+tupleT i = return (TupleT i)
+
+unboxedTupleT :: Int -> TypeQ
+unboxedTupleT i = return (UnboxedTupleT i)
+
+unboxedSumT :: SumArity -> TypeQ
+unboxedSumT arity = return (UnboxedSumT arity)
+
+sigT :: TypeQ -> KindQ -> TypeQ
+sigT t k
+ = do
+ t' <- t
+ k' <- k
+ return $ SigT t' k'
+
+equalityT :: TypeQ
+equalityT = return EqualityT
+
+wildCardT :: TypeQ
+wildCardT = return WildCardT
+
+{-# DEPRECATED classP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please use 'conT' and 'appT'." #-}
+classP :: Name -> [Q Type] -> Q Pred
+classP cla tys
+ = do
+ tysl <- sequence tys
+ return (foldl AppT (ConT cla) tysl)
+
+{-# DEPRECATED equalP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please see 'equalityT'." #-}
+equalP :: TypeQ -> TypeQ -> PredQ
+equalP tleft tright
+ = do
+ tleft1 <- tleft
+ tright1 <- tright
+ eqT <- equalityT
+ return (foldl AppT eqT [tleft1, tright1])
+
+promotedT :: Name -> TypeQ
+promotedT = return . PromotedT
+
+promotedTupleT :: Int -> TypeQ
+promotedTupleT i = return (PromotedTupleT i)
+
+promotedNilT :: TypeQ
+promotedNilT = return PromotedNilT
+
+promotedConsT :: TypeQ
+promotedConsT = return PromotedConsT
+
+noSourceUnpackedness, sourceNoUnpack, sourceUnpack :: SourceUnpackednessQ
+noSourceUnpackedness = return NoSourceUnpackedness
+sourceNoUnpack = return SourceNoUnpack
+sourceUnpack = return SourceUnpack
+
+noSourceStrictness, sourceLazy, sourceStrict :: SourceStrictnessQ
+noSourceStrictness = return NoSourceStrictness
+sourceLazy = return SourceLazy
+sourceStrict = return SourceStrict
+
+{-# DEPRECATED isStrict
+ ["Use 'bang'. See https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0. ",
+ "Example usage: 'bang noSourceUnpackedness sourceStrict'"] #-}
+{-# DEPRECATED notStrict
+ ["Use 'bang'. See https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0. ",
+ "Example usage: 'bang noSourceUnpackedness noSourceStrictness'"] #-}
+{-# DEPRECATED unpacked
+ ["Use 'bang'. See https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0. ",
+ "Example usage: 'bang sourceUnpack sourceStrict'"] #-}
+isStrict, notStrict, unpacked :: Q Strict
+isStrict = bang noSourceUnpackedness sourceStrict
+notStrict = bang noSourceUnpackedness noSourceStrictness
+unpacked = bang sourceUnpack sourceStrict
+
+bang :: SourceUnpackednessQ -> SourceStrictnessQ -> BangQ
+bang u s = do u' <- u
+ s' <- s
+ return (Bang u' s')
+
+bangType :: BangQ -> TypeQ -> BangTypeQ
+bangType = liftM2 (,)
+
+varBangType :: Name -> BangTypeQ -> VarBangTypeQ
+varBangType v bt = do (b, t) <- bt
+ return (v, b, t)
+
+{-# DEPRECATED strictType
+ "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'bangType' instead." #-}
+strictType :: Q Strict -> TypeQ -> StrictTypeQ
+strictType = bangType
+
+{-# DEPRECATED varStrictType
+ "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'varBangType' instead." #-}
+varStrictType :: Name -> StrictTypeQ -> VarStrictTypeQ
+varStrictType = varBangType
+
+-- * Type Literals
+
+numTyLit :: Integer -> TyLitQ
+numTyLit n = if n >= 0 then return (NumTyLit n)
+ else fail ("Negative type-level number: " ++ show n)
+
+strTyLit :: String -> TyLitQ
+strTyLit s = return (StrTyLit s)
+
+-------------------------------------------------------------------------------
+-- * Kind
+
+plainTV :: Name -> TyVarBndrQ
+plainTV = pure . PlainTV
+
+kindedTV :: Name -> KindQ -> TyVarBndrQ
+kindedTV n = fmap (KindedTV n)
+
+varK :: Name -> Kind
+varK = VarT
+
+conK :: Name -> Kind
+conK = ConT
+
+tupleK :: Int -> Kind
+tupleK = TupleT
+
+arrowK :: Kind
+arrowK = ArrowT
+
+listK :: Kind
+listK = ListT
+
+appK :: Kind -> Kind -> Kind
+appK = AppT
+
+starK :: KindQ
+starK = pure StarT
+
+constraintK :: KindQ
+constraintK = pure ConstraintT
+
+-------------------------------------------------------------------------------
+-- * Type family result
+
+noSig :: FamilyResultSigQ
+noSig = pure NoSig
+
+kindSig :: KindQ -> FamilyResultSigQ
+kindSig = fmap KindSig
+
+tyVarSig :: TyVarBndrQ -> FamilyResultSigQ
+tyVarSig = fmap TyVarSig
+
+-------------------------------------------------------------------------------
+-- * Injectivity annotation
+
+injectivityAnn :: Name -> [Name] -> InjectivityAnn
+injectivityAnn = TH.InjectivityAnn
+
+-------------------------------------------------------------------------------
+-- * Role
+
+nominalR, representationalR, phantomR, inferR :: Role
+nominalR = NominalR
+representationalR = RepresentationalR
+phantomR = PhantomR
+inferR = InferR
+
+-------------------------------------------------------------------------------
+-- * Callconv
+
+cCall, stdCall, cApi, prim, javaScript :: Callconv
+cCall = CCall
+stdCall = StdCall
+cApi = CApi
+prim = Prim
+javaScript = JavaScript
+
+-------------------------------------------------------------------------------
+-- * Safety
+
+unsafe, safe, interruptible :: Safety
+unsafe = Unsafe
+safe = Safe
+interruptible = Interruptible
+
+-------------------------------------------------------------------------------
+-- * FunDep
+
+funDep :: [Name] -> [Name] -> FunDep
+funDep = FunDep
+
+-------------------------------------------------------------------------------
+-- * FamFlavour
+
+typeFam, dataFam :: FamFlavour
+typeFam = TypeFam
+dataFam = DataFam
+
+-------------------------------------------------------------------------------
+-- * RuleBndr
+ruleVar :: Name -> RuleBndrQ
+ruleVar = return . RuleVar
+
+typedRuleVar :: Name -> TypeQ -> RuleBndrQ
+typedRuleVar n ty = ty >>= return . TypedRuleVar n
+
+-------------------------------------------------------------------------------
+-- * AnnTarget
+valueAnnotation :: Name -> AnnTarget
+valueAnnotation = ValueAnnotation
+
+typeAnnotation :: Name -> AnnTarget
+typeAnnotation = TypeAnnotation
+
+moduleAnnotation :: AnnTarget
+moduleAnnotation = ModuleAnnotation
+
+-------------------------------------------------------------------------------
+-- * Pattern Synonyms (sub constructs)
+
+unidir, implBidir :: PatSynDirQ
+unidir = return Unidir
+implBidir = return ImplBidir
+
+explBidir :: [ClauseQ] -> PatSynDirQ
+explBidir cls = do
+ cls' <- sequence cls
+ return (ExplBidir cls')
+
+prefixPatSyn :: [Name] -> PatSynArgsQ
+prefixPatSyn args = return $ PrefixPatSyn args
+
+recordPatSyn :: [Name] -> PatSynArgsQ
+recordPatSyn sels = return $ RecordPatSyn sels
+
+infixPatSyn :: Name -> Name -> PatSynArgsQ
+infixPatSyn arg1 arg2 = return $ InfixPatSyn arg1 arg2
+
+--------------------------------------------------------------
+-- * Useful helper function
+
+appsE :: [ExpQ] -> ExpQ
+appsE [] = error "appsE []"
+appsE [x] = x
+appsE (x:y:zs) = appsE ( (appE x y) : zs )
+
+-- | Return the Module at the place of splicing. Can be used as an
+-- input for 'reifyModule'.
+thisModule :: Q Module
+thisModule = do
+ loc <- location
+ return $ Module (mkPkgName $ loc_package loc) (mkModName $ loc_module loc)
diff --git a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
index 696c4454c7..e6c33029ab 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
@@ -689,11 +689,11 @@ pprParendType (UnboxedSumT arity) = hashParens $ hcat $ replicate (arity-1) bar
pprParendType ArrowT = parens (text "->")
pprParendType ListT = text "[]"
pprParendType (LitT l) = pprTyLit l
-pprParendType (PromotedT c) = text "'" <> ppr c
+pprParendType (PromotedT c) = text "'" <> pprName' Applied c
pprParendType (PromotedTupleT 0) = text "'()"
pprParendType (PromotedTupleT n) = quoteParens (hcat (replicate (n-1) comma))
pprParendType PromotedNilT = text "'[]"
-pprParendType PromotedConsT = text "(':)"
+pprParendType PromotedConsT = text "'(:)"
pprParendType StarT = char '*'
pprParendType ConstraintT = text "Constraint"
pprParendType (SigT ty k) = parens (ppr ty <+> text "::" <+> ppr k)
diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
index 14aeaeb380..b8e1601456 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
@@ -1,14 +1,10 @@
-{-# LANGUAGE CPP, DeriveDataTypeable,
+{-# LANGUAGE DeriveDataTypeable,
DeriveGeneric, FlexibleInstances, DefaultSignatures,
RankNTypes, RoleAnnotations, ScopedTypeVariables,
Trustworthy #-}
{-# OPTIONS_GHC -fno-warn-inline-rule-shadowing #-}
-#if MIN_VERSION_base(4,9,0)
-# define HAS_MONADFAIL 1
-#endif
-
-----------------------------------------------------------------------------
-- |
-- Module : Language.Haskell.Syntax
@@ -34,6 +30,7 @@ import Data.Data hiding (Fixity(..))
import Data.IORef
import System.IO.Unsafe ( unsafePerformIO )
import Control.Monad (liftM)
+import Control.Monad.IO.Class (MonadIO (..))
import System.IO ( hPutStrLn, stderr )
import Data.Char ( isAlpha, isAlphaNum, isUpper )
import Data.Int
@@ -45,9 +42,7 @@ import GHC.ForeignSrcLang.Type
import Language.Haskell.TH.LanguageExtensions
import Numeric.Natural
-#if HAS_MONADFAIL
import qualified Control.Monad.Fail as Fail
-#endif
-----------------------------------------------------
--
@@ -55,11 +50,7 @@ import qualified Control.Monad.Fail as Fail
--
-----------------------------------------------------
-#if HAS_MONADFAIL
-class Fail.MonadFail m => Quasi m where
-#else
-class Monad m => Quasi m where
-#endif
+class (MonadIO m, Fail.MonadFail m) => Quasi m where
qNewName :: String -> m Name
-- ^ Fresh names
@@ -88,6 +79,7 @@ class Monad m => Quasi m where
qLocation :: m Loc
qRunIO :: IO a -> m a
+ qRunIO = liftIO
-- ^ Input/output (dangerous)
qAddDependentFile :: FilePath -> m ()
@@ -142,8 +134,6 @@ instance Quasi IO where
qIsExtEnabled _ = badIO "isExtEnabled"
qExtsEnabled = badIO "extsEnabled"
- qRunIO m = m
-
badIO :: String -> IO a
badIO op = do { qReport True ("Can't do `" ++ op ++ "' in the IO monad")
; fail "Template Haskell failure" }
@@ -179,14 +169,10 @@ runQ (Q m) = m
instance Monad Q where
Q m >>= k = Q (m >>= \x -> unQ (k x))
(>>) = (*>)
-#if !HAS_MONADFAIL
- fail s = report True s >> Q (fail "Q monad failure")
-#else
fail = Fail.fail
instance Fail.MonadFail Q where
fail s = report True s >> Q (Fail.fail "Q monad failure")
-#endif
instance Functor Q where
fmap f (Q x) = Q (fmap f x)
@@ -508,6 +494,9 @@ isExtEnabled ext = Q (qIsExtEnabled ext)
extsEnabled :: Q [Extension]
extsEnabled = Q qExtsEnabled
+instance MonadIO Q where
+ liftIO = runIO
+
instance Quasi Q where
qNewName = newName
qReport = report
@@ -521,7 +510,6 @@ instance Quasi Q where
qReifyConStrictness = reifyConStrictness
qLookupName = lookupName
qLocation = location
- qRunIO = runIO
qAddDependentFile = addDependentFile
qAddTopDecls = addTopDecls
qAddForeignFile = addForeignFile
diff --git a/libraries/template-haskell/changelog.md b/libraries/template-haskell/changelog.md
index 8eddedce3d..e003f1b47e 100644
--- a/libraries/template-haskell/changelog.md
+++ b/libraries/template-haskell/changelog.md
@@ -6,6 +6,19 @@
* Add support for overloaded labels. Introduces `labelE :: String -> ExpQ`.
+ * Add `KindQ`, `TyVarBndrQ`, and `FamilyResultSigQ` aliases to
+ `Language.Haskell.TH.Lib`.
+
+ * Add `Language.Haskell.TH.Lib.Internal` module, which exposes some
+ additional functionality that is used internally in GHC's integration
+ with Template Haskell. This is not a part of the public API, and as
+ such, there are no API guarantees for this module from version to version.
+
+ * `MonadIO` is now a superclass of `Quasi`, `qRunIO` has a default
+ implementation `qRunIO = liftIO`
+
+ * Add `MonadIO Q` instance
+
## 2.12.0.0 *TBA*
* Bundled with GHC *TBA*
diff --git a/libraries/template-haskell/template-haskell.cabal b/libraries/template-haskell/template-haskell.cabal
index dfb3b079b3..fcfa448b91 100644
--- a/libraries/template-haskell/template-haskell.cabal
+++ b/libraries/template-haskell/template-haskell.cabal
@@ -45,6 +45,8 @@ Library
Language.Haskell.TH.Syntax
Language.Haskell.TH.LanguageExtensions
+ Language.Haskell.TH.Lib.Internal
+
other-modules:
Language.Haskell.TH.Lib.Map
diff --git a/libraries/text b/libraries/text
new file mode 160000
+Subproject 81f9de11424b79e075d0d22cee23ce9ad90b506
diff --git a/libraries/unix b/libraries/unix
-Subproject fcaa530a8fdd3897353bdf246752a91d675aad4
+Subproject 063aea3fbc5a8caa03d0deb9a887763006ab86d
diff --git a/mk/warnings.mk b/mk/warnings.mk
index af5f4f51d9..16d13a28ba 100644
--- a/mk/warnings.mk
+++ b/mk/warnings.mk
@@ -114,6 +114,11 @@ libraries/transformers_dist-install_EXTRA_HC_OPTS += -Wno-unused-matches -Wno-un
libraries/transformers_dist-install_EXTRA_HC_OPTS += -Wno-redundant-constraints
libraries/transformers_dist-install_EXTRA_HC_OPTS += -Wno-orphans
+# parsec has various warnings
+libraries/parsec_dist-install_EXTRA_HC_OPTS += -Wno-name-shadowing -Wno-unused-matches
+libraries/parsec_dist-install_EXTRA_HC_OPTS += -Wno-unused-do-bind -Wno-missing-signatures
+libraries/parsec_dist-install_EXTRA_HC_OPTS += -Wno-unused-imports -Wno-type-defaults
+
# Turn of trustworthy-safe warning
libraries/base_dist-install_EXTRA_HC_OPTS += -Wno-trustworthy-safe
libraries/ghc-prim_dist-install_EXTRA_HC_OPTS += -Wno-trustworthy-safe
diff --git a/packages b/packages
index 6ee80712f2..a44e31687e 100644
--- a/packages
+++ b/packages
@@ -52,9 +52,12 @@ libraries/directory - - ssh://g
libraries/filepath - - ssh://git@github.com/haskell/filepath.git
libraries/haskeline - - https://github.com/judah/haskeline.git
libraries/hpc - - -
+libraries/mtl - - https://github.com/ekmett/mtl.git
+libraries/parsec - - https://github.com/haskell/parsec.git
libraries/pretty - - https://github.com/haskell/pretty.git
libraries/process - - ssh://git@github.com/haskell/process.git
libraries/terminfo - - https://github.com/judah/terminfo.git
+libraries/text - - https://github.com/bos/text.git
libraries/time - - https://github.com/haskell/time.git
libraries/transformers - - https://git.haskell.org/darcs-mirrors/transformers.git
libraries/unix - - ssh://git@github.com/haskell/unix.git
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index 43801b8944..cb6a13c897 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -171,7 +171,7 @@ doingRetainerProfiling( void )
}
#endif /* PROFILING */
-// Precesses a closure 'c' being destroyed whose size is 'size'.
+// Processes a closure 'c' being destroyed whose size is 'size'.
// Make sure that LDV_recordDead() is not invoked on 'inherently used' closures
// such as TSO; they should not be involved in computing dragNew or voidNew.
//
diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c
index 6f1ab79691..f5e96a2c43 100644
--- a/rts/RaiseAsync.c
+++ b/rts/RaiseAsync.c
@@ -108,7 +108,7 @@ suspendComputation (Capability *cap, StgTSO *tso, StgUpdateFrame *stop_here)
yourself using throwTo, the exception would actually immediately
be delivered. This is because throwTo itself is considered an
interruptible point, so the exception is always deliverable. Thus,
- ordinarily, we never end up with a message to onesself in the
+ ordinarily, we never end up with a message to oneself in the
blocked_exceptions queue.
- In the case of a StackOverflow, we don't actually care about the
diff --git a/rts/RetainerProfile.c b/rts/RetainerProfile.c
index 6ca09fc43e..1d5e9230c9 100644
--- a/rts/RetainerProfile.c
+++ b/rts/RetainerProfile.c
@@ -1755,11 +1755,11 @@ static void
computeRetainerSet( void )
{
StgWeak *weak;
- RetainerSet *rtl;
uint32_t g, n;
StgPtr ml;
bdescr *bd;
#if defined(DEBUG_RETAINER)
+ RetainerSet *rtl;
RetainerSet tmpRetainerSet;
#endif
@@ -1801,9 +1801,9 @@ computeRetainerSet( void )
for (ml = bd->start; ml < bd->free; ml++) {
maybeInitRetainerSet((StgClosure *)*ml);
- rtl = retainerSetOf((StgClosure *)*ml);
#if defined(DEBUG_RETAINER)
+ rtl = retainerSetOf((StgClosure *)*ml);
if (rtl == NULL) {
// first visit to *ml
// This is a violation of the interface rule!
diff --git a/rts/RetainerSet.h b/rts/RetainerSet.h
index 52f12dc155..1b4dec0b3e 100644
--- a/rts/RetainerSet.h
+++ b/rts/RetainerSet.h
@@ -67,7 +67,7 @@ typedef struct _RetainerSet {
struct _RetainerSet *link; // link to the next retainer set in the bucket
int id; // unique id of this retainer set (used when printing)
// Its absolute value is interpreted as its true id; if id is
- // negative, it indicates that this retainer set has had a postive
+ // negative, it indicates that this retainer set has had a positive
// cost after some retainer profiling.
retainer element[0]; // elements of this retainer set
// do not put anything below here!
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index 7b10d2a67d..06d59f0550 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -46,12 +46,11 @@ int rts_argc = 0; /* ditto */
char **rts_argv = NULL;
int rts_argv_size = 0;
#if defined(mingw32_HOST_OS)
-// On Windows, we want to use GetCommandLineW rather than argc/argv,
-// but we need to mutate the command line arguments for withProgName and
-// friends. The System.Environment module achieves that using this bit of
-// shared state:
-int win32_prog_argc = 0;
-wchar_t **win32_prog_argv = NULL;
+// On Windows hs_main uses GetCommandLineW to get Unicode arguments and
+// passes them along UTF8 encoded as argv. We store them here in order to
+// free them on exit.
+int win32_full_utf8_argc = 0;
+char** win32_utf8_argv = NULL;
#endif
// The global rtsConfig, set from the RtsConfig supplied by the call
@@ -111,6 +110,9 @@ static void read_trace_flags(const char *arg);
static void errorUsage (void) GNU_ATTRIBUTE(__noreturn__);
+#if defined(mingw32_HOST_OS)
+static char** win32_full_utf8_argv;
+#endif
static char * copyArg (char *arg);
static char ** copyArgv (int argc, char *argv[]);
static void freeArgv (int argc, char *argv[]);
@@ -446,6 +448,66 @@ usage_text[] = {
0
};
+/**
+Note [Windows Unicode Arguments]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+On Windows argv is usually encoded in the current Codepage which might not
+support unicode.
+
+Instead of ignoring the arguments to hs_init we expect them to be utf-8
+encoded when coming from a custom main function. In the regular hs_main we
+get the unicode arguments from the windows API and pass them along utf8
+encoded instead.
+
+This reduces special casing of arguments in later parts of the RTS and base
+libraries to dealing with slash differences and using utf8 instead of the
+current locale on Windows when decoding arguments.
+
+*/
+
+#if defined(mingw32_HOST_OS)
+//Allocate a buffer and return the string utf8 encoded.
+char* lpcwstrToUTF8(const wchar_t* utf16_str)
+{
+ //Check the utf8 encoded size first
+ int res = WideCharToMultiByte(CP_UTF8, 0, utf16_str, -1, NULL, 0,
+ NULL, NULL);
+ if (res == 0) {
+ return NULL;
+ }
+ char* buffer = (char*) stgMallocBytes((size_t)res, "getUTF8Args 2");
+ res = WideCharToMultiByte(CP_UTF8, 0, utf16_str, -1, buffer, res,
+ NULL, NULL);
+ return buffer;
+}
+
+char** getUTF8Args(int* argc)
+{
+ LPCWSTR cmdLine = GetCommandLineW();
+ LPWSTR* argvw = CommandLineToArgvW(cmdLine, argc);
+
+ // We create two argument arrays, one which is later permutated by the RTS
+ // instead of the main argv.
+ // The other one is used to free the allocted memory later.
+ char** argv = (char**) stgMallocBytes(sizeof(char*) * (*argc + 1),
+ "getUTF8Args 1");
+ win32_full_utf8_argv = (char**) stgMallocBytes(sizeof(char*) * (*argc + 1),
+ "getUTF8Args 1");
+
+ for (int i = 0; i < *argc; i++)
+ {
+ argv[i] = lpcwstrToUTF8(argvw[i]);
+ }
+ argv[*argc] = NULL;
+ memcpy(win32_full_utf8_argv, argv, sizeof(char*) * (*argc + 1));
+
+ LocalFree(argvw);
+ win32_utf8_argv = argv;
+ win32_full_utf8_argc = *argc;
+ return argv;
+}
+#endif
+
STATIC_INLINE bool strequal(const char *a, const char * b)
{
return(strcmp(a, b) == 0);
@@ -514,12 +576,8 @@ static void errorRtsOptsDisabled(const char *s)
- rtsConfig (global) contains the supplied RtsConfig
- On Windows getArgs ignores argv and instead takes the arguments directly
- from the WinAPI and removes any which would have been parsed by the RTS.
-
- If the handling of which arguments are passed to the Haskell side changes
- these changes have to be synchronized with getArgs in base. See #13287 and
- Note [Ignore hs_init argv] in System.Environment.
+ On Windows argv is assumed to be utf8 encoded for unicode compatibility.
+ See Note [Windows Unicode Arguments]
-------------------------------------------------------------------------- */
@@ -557,6 +615,8 @@ void setupRtsFlags (int *argc, char *argv[], RtsConfig rts_config)
// process arguments from the GHCRTS environment variable next
// (arguments from the command line override these).
+ // If we ignore all non-builtin rtsOpts we skip these.
+ if(rtsConfig.rts_opts_enabled != RtsOptsIgnoreAll)
{
char *ghc_rts = getenv("GHCRTS");
@@ -573,33 +633,44 @@ void setupRtsFlags (int *argc, char *argv[], RtsConfig rts_config)
}
}
- // Split arguments (argv) into PGM (argv) and RTS (rts_argv) parts
- // argv[0] must be PGM argument -- leave in argv
- //
- for (mode = PGM; arg < total_arg; arg++) {
- // The '--RTS' argument disables all future +RTS ... -RTS processing.
- if (strequal("--RTS", argv[arg])) {
- arg++;
- break;
- }
- // The '--' argument is passed through to the program, but
- // disables all further +RTS ... -RTS processing.
- else if (strequal("--", argv[arg])) {
- break;
- }
- else if (strequal("+RTS", argv[arg])) {
- mode = RTS;
- }
- else if (strequal("-RTS", argv[arg])) {
- mode = PGM;
- }
- else if (mode == RTS) {
- appendRtsArg(copyArg(argv[arg]));
- }
- else {
- argv[(*argc)++] = argv[arg];
+
+ // If we ignore all commandline rtsOpts we skip processing of argv by
+ // the RTS completely
+ if(!(rtsConfig.rts_opts_enabled == RtsOptsIgnoreAll ||
+ rtsConfig.rts_opts_enabled == RtsOptsIgnore)
+ )
+ {
+ // Split arguments (argv) into PGM (argv) and RTS (rts_argv) parts
+ // argv[0] must be PGM argument -- leave in argv
+ //
+ for (mode = PGM; arg < total_arg; arg++) {
+ // The '--RTS' argument disables all future
+ // +RTS ... -RTS processing.
+ if (strequal("--RTS", argv[arg])) {
+ arg++;
+ break;
+ }
+ // The '--' argument is passed through to the program, but
+ // disables all further +RTS ... -RTS processing.
+ else if (strequal("--", argv[arg])) {
+ break;
+ }
+ else if (strequal("+RTS", argv[arg])) {
+ mode = RTS;
+ }
+ else if (strequal("-RTS", argv[arg])) {
+ mode = PGM;
+ }
+ else if (mode == RTS) {
+ appendRtsArg(copyArg(argv[arg]));
+ }
+ else {
+ argv[(*argc)++] = argv[arg];
+ }
}
+
}
+
// process remaining program arguments
for (; arg < total_arg; arg++) {
argv[(*argc)++] = argv[arg];
@@ -2040,48 +2111,18 @@ void freeWin32ProgArgv (void);
void
freeWin32ProgArgv (void)
{
- int i;
-
- if (win32_prog_argv != NULL) {
- for (i = 0; i < win32_prog_argc; i++) {
- stgFree(win32_prog_argv[i]);
- }
- stgFree(win32_prog_argv);
+ if(win32_utf8_argv == NULL) {
+ return;
+ }
+ else
+ {
+ freeArgv(win32_full_utf8_argc, win32_full_utf8_argv);
+ stgFree(win32_utf8_argv);
}
- win32_prog_argc = 0;
- win32_prog_argv = NULL;
-}
-void
-getWin32ProgArgv(int *argc, wchar_t **argv[])
-{
- *argc = win32_prog_argc;
- *argv = win32_prog_argv;
}
-void
-setWin32ProgArgv(int argc, wchar_t *argv[])
-{
- int i;
-
- freeWin32ProgArgv();
-
- win32_prog_argc = argc;
- if (argv == NULL) {
- win32_prog_argv = NULL;
- return;
- }
-
- win32_prog_argv = stgCallocBytes(argc + 1, sizeof (wchar_t *),
- "setWin32ProgArgv 1");
- for (i = 0; i < argc; i++) {
- win32_prog_argv[i] = stgMallocBytes((wcslen(argv[i]) + 1) * sizeof(wchar_t),
- "setWin32ProgArgv 2");
- wcscpy(win32_prog_argv[i], argv[i]);
- }
- win32_prog_argv[argc] = NULL;
-}
#endif
/* ----------------------------------------------------------------------------
diff --git a/rts/RtsFlags.h b/rts/RtsFlags.h
index 71ad219d29..c36c64a63b 100644
--- a/rts/RtsFlags.h
+++ b/rts/RtsFlags.h
@@ -13,6 +13,11 @@
/* Routines that operate-on/to-do-with RTS flags: */
+#if defined(mingw32_HOST_OS)
+//The returned buffer has to be freed with stgFree()
+char* lpcwstrToUTF8(const wchar_t* utf16_str);
+char** getUTF8Args(int* argc);
+#endif
void initRtsFlagsDefaults (void);
void setupRtsFlags (int *argc, char *argv[], RtsConfig rtsConfig);
void freeRtsArgs (void);
diff --git a/rts/RtsMain.c b/rts/RtsMain.c
index d9f05576a0..57c38742b6 100644
--- a/rts/RtsMain.c
+++ b/rts/RtsMain.c
@@ -13,6 +13,7 @@
#include "RtsAPI.h"
#include "RtsUtils.h"
+#include "RtsFlags.h"
#include "Prelude.h"
#include "Task.h"
#include "Excn.h"
@@ -48,6 +49,16 @@ int hs_main ( int argc, char *argv[], // program args
int exit_status;
SchedulerStatus status;
+ // See Note: [Windows Unicode Arguments] in rts/RtsFlags.c
+ #if defined(mingw32_HOST_OS)
+ {
+ argv = getUTF8Args(&argc);
+ }
+ #endif
+
+
+
+
hs_init_ghc(&argc, &argv, rts_config);
// kick off the computation by creating the main thread with a pointer
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
index 71a842d0a9..e4ca6b906d 100644
--- a/rts/RtsStartup.c
+++ b/rts/RtsStartup.c
@@ -179,7 +179,33 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
if (argc == NULL || argv == NULL) {
// Use a default for argc & argv if either is not supplied
int my_argc = 1;
+ #if defined(mingw32_HOST_OS)
+ //Retry larger buffer sizes on error up to about the NTFS length limit.
+ wchar_t* pathBuf;
+ char *my_argv[2] = { NULL, NULL };
+ for(DWORD maxLength = MAX_PATH; maxLength <= 33280; maxLength *= 2)
+ {
+ pathBuf = (wchar_t*) stgMallocBytes(sizeof(wchar_t) * maxLength,
+ "hs_init_ghc: GetModuleFileName");
+ DWORD pathLength = GetModuleFileNameW(NULL, pathBuf, maxLength);
+ if(GetLastError() == ERROR_INSUFFICIENT_BUFFER || pathLength == 0) {
+ stgFree(pathBuf);
+ pathBuf = NULL;
+ } else {
+ break;
+ }
+ }
+ if(pathBuf == NULL) {
+ my_argv[0] = "<unknown>";
+ } else {
+ my_argv[0] = lpcwstrToUTF8(pathBuf);
+ stgFree(pathBuf);
+ }
+
+
+ #else
char *my_argv[] = { "<unknown>", NULL };
+ #endif
setFullProgArgv(my_argc,my_argv);
setupRtsFlags(&my_argc, my_argv, rts_config);
} else {
diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c
index 11b1437f77..e80a4955f0 100644
--- a/rts/RtsSymbols.c
+++ b/rts/RtsSymbols.c
@@ -97,8 +97,6 @@
SymI_HasProto(stg_asyncReadzh) \
SymI_HasProto(stg_asyncWritezh) \
SymI_HasProto(stg_asyncDoProczh) \
- SymI_HasProto(getWin32ProgArgv) \
- SymI_HasProto(setWin32ProgArgv) \
SymI_HasProto(rts_InstallConsoleEvent) \
SymI_HasProto(rts_ConsoleHandlerDone) \
SymI_HasProto(atexit) \
diff --git a/rules/sdist-ghc-file.mk b/rules/sdist-ghc-file.mk
index 9ea0b6521a..d6a70e10fb 100644
--- a/rules/sdist-ghc-file.mk
+++ b/rules/sdist-ghc-file.mk
@@ -44,3 +44,34 @@ sdist_$1_$2_$4 : $1/$2/build/$4.hs
# didn't generate all package-data.mk files.
$$(eval $$(call hs-suffix-rules-srcdir,$1,$2,$3))
endef
+
+# -----------------------------------------------------------------------------
+# Variant of sdist-ghc-file whose `$3`-argument is interpreted
+# differently in a more appropriate way for cabal-packages
+
+define sdist-ghc-file2
+# $1 = dir
+# $2 = distdir
+# $3 = moduledir
+# $4 = filename
+# $5 = extension
+
+.PHONY: sdist_$1_$2_$4
+
+# We should do this before creating the `sdist-ghc` tarball, or when just
+# running `make sdist-ghc-prep`.
+sdist-ghc-prep : sdist_$1_$2_$4
+
+# But first create SRC_DIST_GHC_DIR.
+sdist_$1_$2_$4 : sdist-ghc-prep-tree
+
+# Generate the .hs files if they don't exist yet, then do actual copying and
+# moving.
+sdist_$1_$2_$4 : $1/$2/build/$3/$4.hs
+ "$(CP)" $1/$2/build/$3/$4.hs $(SRC_DIST_GHC_DIR)/$1/$3
+ mv $(SRC_DIST_GHC_DIR)/$1/$3/$4.$5 $(SRC_DIST_GHC_DIR)/$1/$3/$4.$5.source
+
+# And make sure the rules for generating the .hs files exist, even when we
+# didn't generate all package-data.mk files.
+$$(eval $$(call hs-suffix-rules-srcdir,$1,$2,$3))
+endef
diff --git a/testsuite/driver/junit.py b/testsuite/driver/junit.py
new file mode 100644
index 0000000000..01a5f47acc
--- /dev/null
+++ b/testsuite/driver/junit.py
@@ -0,0 +1,38 @@
+from datetime import datetime
+import xml.etree.ElementTree as ET
+
+def junit(t):
+ testsuites = ET.Element('testsuites')
+ testsuite = ET.SubElement(testsuites, 'testsuite',
+ id = "0",
+ package = 'ghc',
+ tests = str(t.total_tests),
+ failures = str(len(t.unexpected_failures) + len(t.unexpected_stat_failures)),
+ errors = str(len(t.framework_failures)),
+ timestamp = datetime.now().isoformat())
+
+ for result, group in [('stat failure', t.unexpected_stat_failures),
+ ('unexpected failure', t.unexpected_failures)]:
+ for (directory, testname, reason, way) in group:
+ testcase = ET.SubElement(testsuite, 'testcase',
+ classname = testname,
+ name = way)
+ result = ET.SubElement(testcase, 'failure',
+ type = result,
+ message = reason)
+
+ for (directory, testname, reason, way) in t.framework_failures:
+ testcase = ET.SubElement(testsuite, 'testcase',
+ classname = testname,
+ name = way)
+ result = ET.SubElement(testcase, 'error',
+ type = "framework failure",
+ message = reason)
+
+ for (directory, testname, way) in t.expected_passes:
+ testcase = ET.SubElement(testsuite, 'testcase',
+ classname = testname,
+ name = way)
+
+ return ET.ElementTree(testsuites)
+
diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py
index 7e4f375a2c..3e03ed306c 100644
--- a/testsuite/driver/runtests.py
+++ b/testsuite/driver/runtests.py
@@ -6,11 +6,11 @@
from __future__ import print_function
+import argparse
import signal
import sys
import os
import string
-import getopt
import shutil
import tempfile
import time
@@ -26,6 +26,7 @@ import subprocess
from testutil import *
from testglobals import *
+from junit import junit
# Readline sometimes spews out ANSI escapes for some values of TERM,
# which result in test failures. Thus set TERM to a nice, simple, safe
@@ -41,81 +42,61 @@ def signal_handler(signal, frame):
# -----------------------------------------------------------------------------
# cmd-line options
-long_options = [
- "configfile=", # config file
- "config=", # config field
- "rootdir=", # root of tree containing tests (default: .)
- "summary-file=", # file in which to save the (human-readable) summary
- "no-print-summary=", # should we print the summary?
- "only=", # just this test (can be give multiple --only= flags)
- "way=", # just this way
- "skipway=", # skip this way
- "threads=", # threads to run simultaneously
- "check-files-written", # check files aren't written by multiple tests
- "verbose=", # verbose (0,1,2 so far)
- "skip-perf-tests", # skip performance tests
- ]
-
-opts, args = getopt.getopt(sys.argv[1:], "e:", long_options)
-
-for opt,arg in opts:
- if opt == '--configfile':
- exec(open(arg).read())
-
- # -e is a string to execute from the command line. For example:
- # testframe -e 'config.compiler=ghc-5.04'
- if opt == '-e':
- exec(arg)
-
- if opt == '--config':
- field, value = arg.split('=', 1)
- setattr(config, field, value)
-
- if opt == '--rootdir':
- config.rootdirs.append(arg)
-
- if opt == '--summary-file':
- config.summary_file = arg
-
- if opt == '--no-print-summary':
- config.no_print_summary = True
-
- if opt == '--only':
- config.run_only_some_tests = True
- config.only.add(arg)
-
- if opt == '--way':
- if (arg not in config.run_ways and arg not in config.compile_ways and arg not in config.other_ways):
- sys.stderr.write("ERROR: requested way \'" +
- arg + "\' does not exist\n")
- sys.exit(1)
- config.cmdline_ways = [arg] + config.cmdline_ways
- if (arg in config.other_ways):
- config.run_ways = [arg] + config.run_ways
- config.compile_ways = [arg] + config.compile_ways
-
- if opt == '--skipway':
- if (arg not in config.run_ways and arg not in config.compile_ways and arg not in config.other_ways):
- sys.stderr.write("ERROR: requested way \'" +
- arg + "\' does not exist\n")
- sys.exit(1)
- config.other_ways = [w for w in config.other_ways if w != arg]
- config.run_ways = [w for w in config.run_ways if w != arg]
- config.compile_ways = [w for w in config.compile_ways if w != arg]
-
- if opt == '--threads':
- config.threads = int(arg)
- config.use_threads = 1
-
- if opt == '--skip-perf-tests':
- config.skip_perf_tests = True
-
- if opt == '--verbose':
- if arg not in ["0","1","2","3","4","5"]:
- sys.stderr.write("ERROR: requested verbosity %s not supported, use 0,1,2,3,4 or 5" % arg)
- sys.exit(1)
- config.verbose = int(arg)
-
+parser = argparse.ArgumentParser(description="GHC's testsuite driver")
+
+parser.add_argument("-e", action='append', help="A string to execute from the command line.")
+parser.add_argument("--config-file", action="append", help="config file")
+parser.add_argument("--config", action='append', help="config field")
+parser.add_argument("--rootdir", action='append', help="root of tree containing tests (default: .)")
+parser.add_argument("--summary-file", help="file in which to save the (human-readable) summary")
+parser.add_argument("--no-print-summary", action="store_true", help="should we print the summary?")
+parser.add_argument("--only", action="append", help="just this test (can be give multiple --only= flags)")
+parser.add_argument("--way", choices=config.run_ways+config.compile_ways+config.other_ways, help="just this way")
+parser.add_argument("--skipway", action="append", choices=config.run_ways+config.compile_ways+config.other_ways, help="skip this way")
+parser.add_argument("--threads", type=int, help="threads to run simultaneously")
+parser.add_argument("--check-files-written", help="check files aren't written by multiple tests") # NOTE: This doesn't seem to exist?
+parser.add_argument("--verbose", type=int, choices=[0,1,2,3,4,5], help="verbose (Values 0 through 5 accepted)")
+parser.add_argument("--skip-perf-tests", action="store_true", help="skip performance tests")
+parser.add_argument("--junit", type=argparse.FileType('wb'), help="output testsuite summary in JUnit format")
+
+args = parser.parse_args()
+
+for e in args.e:
+ exec(e)
+
+for arg in args.config_file:
+ exec(open(arg).read())
+
+for arg in args.config:
+ field, value = arg.split('=', 1)
+ setattr(config, field, value)
+
+config.rootdirs = args.rootdir
+config.summary_file = args.summary_file
+config.no_print_summary = args.no_print_summary
+
+if args.only:
+ config.only = args.only
+ config.run_only_some_tests = True
+
+if args.way:
+ config.cmdline_ways = [args.way] + config.cmdline_ways
+ if (args.way in config.other_ways):
+ config.run_ways = [args.way] + config.run_ways
+ config.compile_ways = [args.way] + config.compile_ways
+
+if args.skipway:
+ config.other_ways = [w for w in config.other_ways if w != args.skipway]
+ config.run_ways = [w for w in config.run_ways if w != args.skipway]
+ config.compile_ways = [w for w in config.compile_ways if w != args.skipway]
+
+if args.threads:
+ config.threads = args.threads
+ config.use_threads = True
+
+if args.verbose:
+ config.verbose = args.verbose
+config.skip_perf_tests = args.skip_perf_tests
config.cygwin = False
config.msys = False
@@ -326,10 +307,13 @@ else:
summary(t, sys.stdout, config.no_print_summary)
- if config.summary_file != '':
+ if config.summary_file:
with open(config.summary_file, 'w') as file:
summary(t, file)
+ if args.junit:
+ junit(t).write(args.junit)
+
cleanup_and_exit(0)
# Note [Running tests in /tmp]
diff --git a/testsuite/driver/testglobals.py b/testsuite/driver/testglobals.py
index fc050e6908..5e7142d9c8 100644
--- a/testsuite/driver/testglobals.py
+++ b/testsuite/driver/testglobals.py
@@ -140,6 +140,7 @@ class TestRun:
self.framework_failures = []
self.framework_warnings = []
+ self.expected_passes = []
self.unexpected_passes = []
self.unexpected_failures = []
self.unexpected_stat_failures = []
diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py
index 26e3d17679..15c773e3f7 100644
--- a/testsuite/driver/testlib.py
+++ b/testsuite/driver/testlib.py
@@ -863,6 +863,7 @@ def do_test(name, way, func, args, files):
if passFail == 'pass':
if _expect_pass(way):
+ t.expected_passes.append((directory, name, way))
t.n_expected_passes += 1
else:
if_verbose(1, '*** unexpected pass for %s' % full_name)
diff --git a/testsuite/mk/test.mk b/testsuite/mk/test.mk
index a44e200d49..a21c4bb16b 100644
--- a/testsuite/mk/test.mk
+++ b/testsuite/mk/test.mk
@@ -73,7 +73,7 @@ else
dllext = .so
endif
-RUNTEST_OPTS += -e ghc_compiler_always_flags="'$(TEST_HC_OPTS)'"
+RUNTEST_OPTS += -e "ghc_compiler_always_flags='$(TEST_HC_OPTS)'"
RUNTEST_OPTS += -e config.compiler_debugged=$(GhcDebugged)
@@ -214,7 +214,7 @@ endif
RUNTEST_OPTS += \
--rootdir=. \
- --configfile=$(CONFIG) \
+ --config-file=$(CONFIG) \
-e 'config.confdir="$(CONFIGDIR)"' \
-e 'config.platform="$(TARGETPLATFORM)"' \
-e 'config.os="$(TargetOS_CPP)"' \
@@ -246,13 +246,17 @@ RUNTEST_OPTS += \
RUNTEST_OPTS += -e "config.stage=$(GhcStage)"
+ifneq "$(JUNIT_FILE)" ""
+RUNTEST_OPTS += \
+ --junit "$(JUNIT_FILE)"
+endif
ifneq "$(SUMMARY_FILE)" ""
RUNTEST_OPTS += \
--summary-file "$(SUMMARY_FILE)"
endif
ifeq "$(NO_PRINT_SUMMARY)" "YES"
RUNTEST_OPTS += \
- --no-print-summary 1
+ --no-print-summary
endif
RUNTEST_OPTS += \
diff --git a/testsuite/tests/dependent/should_compile/T12176.hs b/testsuite/tests/dependent/should_compile/T12176.hs
new file mode 100644
index 0000000000..0e340068a7
--- /dev/null
+++ b/testsuite/tests/dependent/should_compile/T12176.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE RankNTypes, TypeInType, GADTs, TypeFamilies #-}
+
+module T12176 where
+
+import Data.Kind
+
+data Proxy :: forall k. k -> Type where
+ MkProxy :: forall k (a :: k). Proxy a
+
+data X where
+ MkX :: forall (k :: Type) (a :: k). Proxy a -> X
+
+type Expr = (MkX :: forall (a :: Bool). Proxy a -> X)
+
+type family Foo (x :: forall (a :: k). Proxy a -> X) where
+ Foo (MkX :: forall (a :: k). Proxy a -> X) = (MkProxy :: Proxy k)
+
+type Bug = Foo Expr -- this failed with #12176
diff --git a/testsuite/tests/dependent/should_compile/all.T b/testsuite/tests/dependent/should_compile/all.T
index 8a9b221a4e..b854f1d9e7 100644
--- a/testsuite/tests/dependent/should_compile/all.T
+++ b/testsuite/tests/dependent/should_compile/all.T
@@ -24,3 +24,4 @@ test('T11719', normal, compile, [''])
test('T11966', normal, compile, [''])
test('T12442', normal, compile, [''])
test('T13538', normal, compile, [''])
+test('T12176', normal, compile, [''])
diff --git a/testsuite/tests/dependent/should_fail/T11471.hs b/testsuite/tests/dependent/should_fail/T11471.hs
index 19025db22b..ae09ae07bb 100644
--- a/testsuite/tests/dependent/should_fail/T11471.hs
+++ b/testsuite/tests/dependent/should_fail/T11471.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE MagicHash, PolyKinds, TypeFamilies #-}
+{-# LANGUAGE MagicHash, PolyKinds, TypeFamilies, AllowAmbiguousTypes #-}
module T11471 where
diff --git a/testsuite/tests/dependent/should_fail/T11471.stderr b/testsuite/tests/dependent/should_fail/T11471.stderr
index 80c5fc606c..640ae6c754 100644
--- a/testsuite/tests/dependent/should_fail/T11471.stderr
+++ b/testsuite/tests/dependent/should_fail/T11471.stderr
@@ -1,19 +1,22 @@
T11471.hs:15:10: error:
• Couldn't match a lifted type with an unlifted type
- Expected type: Proxy Int#
+ When matching types
+ a :: *
+ Int# :: TYPE 'IntRep
+ Expected type: Proxy a
Actual type: Proxy Int#
- Use -fprint-explicit-kinds to see the kind arguments
• In the first argument of ‘f’, namely ‘(undefined :: Proxy Int#)’
In the expression: f (undefined :: Proxy Int#) 3#
In an equation for ‘bad’: bad = f (undefined :: Proxy Int#) 3#
+ • Relevant bindings include bad :: F a (bound at T11471.hs:15:1)
T11471.hs:15:35: error:
• Couldn't match a lifted type with an unlifted type
When matching types
- F Int# :: *
+ F a :: *
Int# :: TYPE 'IntRep
• In the second argument of ‘f’, namely ‘3#’
In the expression: f (undefined :: Proxy Int#) 3#
In an equation for ‘bad’: bad = f (undefined :: Proxy Int#) 3#
- • Relevant bindings include bad :: F Int# (bound at T11471.hs:15:1)
+ • Relevant bindings include bad :: F a (bound at T11471.hs:15:1)
diff --git a/testsuite/tests/dependent/should_fail/T13135.hs b/testsuite/tests/dependent/should_fail/T13135.hs
index c39b3f5842..772ac78bfa 100644
--- a/testsuite/tests/dependent/should_fail/T13135.hs
+++ b/testsuite/tests/dependent/should_fail/T13135.hs
@@ -62,7 +62,7 @@ arrLen = smartSym sym where
-{- The original bug was a familure to subsitute
+{- The original bug was a failure to substitute
properly during type-function improvement.
--------------------------------------
diff --git a/testsuite/tests/dependent/should_fail/T13601.hs b/testsuite/tests/dependent/should_fail/T13601.hs
new file mode 100644
index 0000000000..5e98c7a657
--- /dev/null
+++ b/testsuite/tests/dependent/should_fail/T13601.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE TypeFamilies, DataKinds, TypeInType #-}
+
+import GHC.Exts
+import Prelude (Bool(True,False),Integer,Ordering,undefined)
+import qualified Prelude
+import Data.Kind
+
+--------------------
+-- class hierarchy
+
+type family
+ Rep (rep :: RuntimeRep) :: RuntimeRep where
+ -- Rep IntRep = IntRep
+ -- Rep DoubleRep = IntRep
+ -- Rep PtrRepUnlifted = IntRep
+ -- Rep PtrRepLifted = PtrRepLifted
+
+class Boolean (Logic a) => Eq (a :: TYPE rep) where
+ type Logic (a :: TYPE rep) :: TYPE (Rep rep)
+ (==) :: a -> a -> Logic a
+
+class Eq a => POrd (a :: TYPE rep) where
+ inf :: a -> a -> a
+
+class POrd a => MinBound (a :: TYPE rep) where
+ minBound :: () -> a
+
+class POrd a => Lattice (a :: TYPE rep) where
+ sup :: a -> a -> a
+
+class (Lattice a, MinBound a) => Bounded (a :: TYPE rep) where
+ maxBound :: () -> a
+
+class Bounded a => Complemented (a :: TYPE rep) where
+ not :: a -> a
+
+class Bounded a => Heyting (a :: TYPE rep) where
+ infixr 3 ==>
+ (==>) :: a -> a -> a
+
+class (Complemented a, Heyting a) => Boolean a
+
+(||) :: Boolean a => a -> a -> a
+(||) = sup
+
+(&&) :: Boolean a => a -> a -> a
+(&&) = inf
diff --git a/testsuite/tests/dependent/should_fail/T13601.stderr b/testsuite/tests/dependent/should_fail/T13601.stderr
new file mode 100644
index 0000000000..c1c9803e5a
--- /dev/null
+++ b/testsuite/tests/dependent/should_fail/T13601.stderr
@@ -0,0 +1,6 @@
+
+T13601.hs:18:16: error:
+ • Expected kind ‘TYPE (Rep 'LiftedRep)’,
+ but ‘Logic a’ has kind ‘TYPE (Rep rep)’
+ • In the first argument of ‘Boolean’, namely ‘(Logic a)’
+ In the class declaration for ‘Eq’
diff --git a/testsuite/tests/dependent/should_fail/T13780a.hs b/testsuite/tests/dependent/should_fail/T13780a.hs
new file mode 100644
index 0000000000..1f7c95c40a
--- /dev/null
+++ b/testsuite/tests/dependent/should_fail/T13780a.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeInType #-}
+module T13780a where
+
+data family Sing (a :: k)
+
+data Foo a = a ~ Bool => MkFoo
+data instance Sing (z :: Foo a) = (z ~ MkFoo) => SMkFoo
diff --git a/testsuite/tests/dependent/should_fail/T13780a.stderr b/testsuite/tests/dependent/should_fail/T13780a.stderr
new file mode 100644
index 0000000000..3b113bd89e
--- /dev/null
+++ b/testsuite/tests/dependent/should_fail/T13780a.stderr
@@ -0,0 +1,6 @@
+
+T13780a.hs:9:40: error:
+ • Expected kind ‘Foo a’, but ‘MkFoo’ has kind ‘Foo Bool’
+ • In the second argument of ‘(~)’, namely ‘MkFoo’
+ In the definition of data constructor ‘SMkFoo’
+ In the data instance declaration for ‘Sing’
diff --git a/testsuite/tests/dependent/should_fail/T13780b.hs b/testsuite/tests/dependent/should_fail/T13780b.hs
new file mode 100644
index 0000000000..238e7a1af9
--- /dev/null
+++ b/testsuite/tests/dependent/should_fail/T13780b.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeInType #-}
+module T13780b where
+
+data family Sing (a :: k)
+
+data instance Sing (z :: Bool) =
+ z ~ False => SFalse
+ | z ~ True => STrue
diff --git a/testsuite/tests/dependent/should_fail/T13780c.hs b/testsuite/tests/dependent/should_fail/T13780c.hs
new file mode 100644
index 0000000000..eee6436237
--- /dev/null
+++ b/testsuite/tests/dependent/should_fail/T13780c.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeInType #-}
+module T13780c where
+
+import Data.Kind
+import T13780b
+
+type family ElimBool (p :: Bool -> Type) (b :: Bool) (s :: Sing b)
+ (pFalse :: p False) (pTrue :: p True) :: p b where
+ ElimBool _ _ SFalse pFalse _ = pFalse
+ ElimBool _ _ STrue _ pTrue = pTrue
diff --git a/testsuite/tests/dependent/should_fail/T13780c.stderr b/testsuite/tests/dependent/should_fail/T13780c.stderr
new file mode 100644
index 0000000000..f91d7a3236
--- /dev/null
+++ b/testsuite/tests/dependent/should_fail/T13780c.stderr
@@ -0,0 +1,12 @@
+[1 of 2] Compiling T13780b ( T13780b.hs, T13780b.o )
+[2 of 2] Compiling T13780c ( T13780c.hs, T13780c.o )
+
+T13780c.hs:11:16: error:
+ • Expected kind ‘Sing _’, but ‘SFalse’ has kind ‘Sing 'False’
+ • In the third argument of ‘ElimBool’, namely ‘SFalse’
+ In the type family declaration for ‘ElimBool’
+
+T13780c.hs:12:16: error:
+ • Expected kind ‘Sing _1’, but ‘STrue’ has kind ‘Sing 'True’
+ • In the third argument of ‘ElimBool’, namely ‘STrue’
+ In the type family declaration for ‘ElimBool’
diff --git a/testsuite/tests/dependent/should_fail/all.T b/testsuite/tests/dependent/should_fail/all.T
index c648f9ed1d..4eb426419d 100644
--- a/testsuite/tests/dependent/should_fail/all.T
+++ b/testsuite/tests/dependent/should_fail/all.T
@@ -1,5 +1,5 @@
test('DepFail1', normal, compile_fail, [''])
-test('RAE_T32a', normal, compile_fail, [''])
+test('RAE_T32a', expect_broken(12919), compile_fail, [''])
test('TypeSkolEscape', normal, compile_fail, [''])
test('BadTelescope', normal, compile_fail, [''])
test('BadTelescope2', normal, compile_fail, [''])
@@ -17,3 +17,7 @@ test('T11471', normal, compile_fail, [''])
test('T12174', normal, compile_fail, [''])
test('T12081', normal, compile_fail, [''])
test('T13135', normal, compile_fail, [''])
+test('T13601', normal, compile_fail, [''])
+test('T13780a', normal, compile_fail, [''])
+test('T13780c', [extra_files(['T13780b.hs'])],
+ multimod_compile_fail, ['T13780c', ''])
diff --git a/testsuite/tests/deriving/should_compile/T13998.hs b/testsuite/tests/deriving/should_compile/T13998.hs
new file mode 100644
index 0000000000..565d4a35f7
--- /dev/null
+++ b/testsuite/tests/deriving/should_compile/T13998.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE GADTs #-}
+
+module T13998 where
+
+import Data.Type.Equality
+
+class EqForall f where
+ eqForall :: f a -> f a -> Bool
+
+class EqForall f => EqForallPoly f where
+ eqForallPoly :: f a -> f b -> Bool
+ default eqForallPoly :: TestEquality f => f a -> f b -> Bool
+ eqForallPoly = defaultEqForallPoly
+
+defaultEqForallPoly :: (TestEquality f, EqForall f) => f a -> f b -> Bool
+defaultEqForallPoly x y = case testEquality x y of
+ Nothing -> False
+ Just Refl -> eqForall x y
+
+
+data Atom = AtomInt | AtomString | AtomBool
+
+data Value (a :: Atom) where
+ ValueInt :: Int -> Value 'AtomInt
+ ValueString :: String -> Value 'AtomString
+ ValueBool :: Bool -> Value 'AtomBool
+
+instance TestEquality Value where
+ testEquality (ValueInt _) (ValueInt _) = Just Refl
+ testEquality (ValueString _) (ValueString _) = Just Refl
+ testEquality (ValueBool _) (ValueBool _) = Just Refl
+ testEquality _ _ = Nothing
+
+instance EqForall Value where
+ eqForall (ValueInt a) (ValueInt b) = a == b
+ eqForall (ValueString a) (ValueString b) = a == b
+ eqForall (ValueBool a) (ValueBool b) = a == b
+
+instance EqForallPoly Value
diff --git a/testsuite/tests/deriving/should_compile/T14045b.hs b/testsuite/tests/deriving/should_compile/T14045b.hs
new file mode 100644
index 0000000000..cb18e36029
--- /dev/null
+++ b/testsuite/tests/deriving/should_compile/T14045b.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE TypeFamilies, KindSignatures, GADTs, GeneralizedNewtypeDeriving #-}
+
+module T14045b where
+
+import Data.Kind ( Type )
+
+data family T a b :: Type
+
+-- newtype instance T Int d = MkT (IO d)
+
+newtype instance T Int :: Type -> Type where
+ MkT :: IO d -> T Int d
+ deriving( Monad, Applicative, Functor )
diff --git a/testsuite/tests/deriving/should_compile/T14094.hs b/testsuite/tests/deriving/should_compile/T14094.hs
new file mode 100644
index 0000000000..29fa693e97
--- /dev/null
+++ b/testsuite/tests/deriving/should_compile/T14094.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# OPTIONS_GHC -Wall #-}
+module Bug where
+
+class C a where
+ type T a
+ data D a
+ m :: a
+
+instance C Int
+deriving instance C Bool
diff --git a/testsuite/tests/deriving/should_compile/T14094.stderr b/testsuite/tests/deriving/should_compile/T14094.stderr
new file mode 100644
index 0000000000..b323a775f5
--- /dev/null
+++ b/testsuite/tests/deriving/should_compile/T14094.stderr
@@ -0,0 +1,26 @@
+
+T14094.hs:12:1: warning: [-Wmissing-methods (in -Wdefault)]
+ • No explicit associated type or default declaration for ‘T’
+ • In the instance declaration for ‘C Int’
+
+T14094.hs:12:1: warning: [-Wmissing-methods (in -Wdefault)]
+ • No explicit associated type or default declaration for ‘D’
+ • In the instance declaration for ‘C Int’
+
+T14094.hs:12:10: warning: [-Wmissing-methods (in -Wdefault)]
+ • No explicit implementation for
+ ‘m’
+ • In the instance declaration for ‘C Int’
+
+T14094.hs:13:1: warning: [-Wmissing-methods (in -Wdefault)]
+ • No explicit associated type or default declaration for ‘T’
+ • In the instance declaration for ‘C Bool’
+
+T14094.hs:13:1: warning: [-Wmissing-methods (in -Wdefault)]
+ • No explicit associated type or default declaration for ‘D’
+ • In the instance declaration for ‘C Bool’
+
+T14094.hs:13:1: warning: [-Wmissing-methods (in -Wdefault)]
+ • No explicit implementation for
+ ‘m’
+ • In the instance declaration for ‘C Bool’
diff --git a/testsuite/tests/deriving/should_compile/all.T b/testsuite/tests/deriving/should_compile/all.T
index 7c7b29070b..65c6d7284e 100644
--- a/testsuite/tests/deriving/should_compile/all.T
+++ b/testsuite/tests/deriving/should_compile/all.T
@@ -93,3 +93,6 @@ test('drv-empty-data', [normalise_errmsg_fun(just_the_deriving)],compile, ['-ddu
test('drv-phantom', [normalise_errmsg_fun(just_the_deriving)],compile, ['-ddump-deriv -dsuppress-uniques'])
test('T13813', normal, compile, [''])
test('T13919', normal, compile, [''])
+test('T13998', normal, compile, [''])
+test('T14045b', normal, compile, [''])
+test('T14094', normal, compile, [''])
diff --git a/testsuite/tests/deriving/should_fail/T10598_fail3.stderr b/testsuite/tests/deriving/should_fail/T10598_fail3.stderr
index a987a4993d..c3f4e123b7 100644
--- a/testsuite/tests/deriving/should_fail/T10598_fail3.stderr
+++ b/testsuite/tests/deriving/should_fail/T10598_fail3.stderr
@@ -1,5 +1,4 @@
-T10598_fail3.hs:1:1: error:
- Generic instances can only be derived in Safe Haskell using the stock strategy.
- In the following instance:
- instance [safe] Generic T
+T10598_fail3.hs:8:36: error:
+ • Generic instances can only be derived in Safe Haskell using the stock strategy.
+ • In the instance declaration for ‘Generic T’
diff --git a/testsuite/tests/deriving/should_fail/T8165_fail2.stderr b/testsuite/tests/deriving/should_fail/T8165_fail2.stderr
index 4c925f52a3..5e19173a33 100644
--- a/testsuite/tests/deriving/should_fail/T8165_fail2.stderr
+++ b/testsuite/tests/deriving/should_fail/T8165_fail2.stderr
@@ -1,5 +1,6 @@
T8165_fail2.hs:9:12: error:
- The type family application ‘T Loop’
- is no smaller than the instance head
- (Use UndecidableInstances to permit this)
+ • The type family application ‘T Loop’
+ is no smaller than the instance head
+ (Use UndecidableInstances to permit this)
+ • In the instance declaration for ‘C Loop’
diff --git a/testsuite/tests/deriving/should_run/T3087.hs b/testsuite/tests/deriving/should_run/T3087.hs
index 9d3be0744d..1e20b9ece9 100644
--- a/testsuite/tests/deriving/should_run/T3087.hs
+++ b/testsuite/tests/deriving/should_run/T3087.hs
@@ -14,7 +14,7 @@ test1' = undefined `ext1Q` (\ (MyJust _) -> ()) $ MyJust ()
newtype Q r a = Q { unQ :: a -> r }
-ext2Q :: (Data d, Typeable2 t)
+ext2Q :: (Data d, Typeable t)
=> (d -> q) -> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q)
-> d -> q
ext2Q def ext arg =
diff --git a/testsuite/tests/driver/T13710/A.hs b/testsuite/tests/driver/T13710/A.hs
new file mode 100644
index 0000000000..5181945eeb
--- /dev/null
+++ b/testsuite/tests/driver/T13710/A.hs
@@ -0,0 +1,5 @@
+{-# LANGUAGE RecordWildCards #-}
+module A where
+import B
+data E = MkE
+p (H{..}) = ()
diff --git a/testsuite/tests/driver/T13710/A.hs-boot b/testsuite/tests/driver/T13710/A.hs-boot
new file mode 100644
index 0000000000..94a2f5e306
--- /dev/null
+++ b/testsuite/tests/driver/T13710/A.hs-boot
@@ -0,0 +1,2 @@
+module A ( E ) where
+data E
diff --git a/testsuite/tests/driver/T13710/B.hs b/testsuite/tests/driver/T13710/B.hs
new file mode 100644
index 0000000000..87c93a9f39
--- /dev/null
+++ b/testsuite/tests/driver/T13710/B.hs
@@ -0,0 +1,3 @@
+module B where
+import {-# SOURCE #-} A
+data H = H { h :: E }
diff --git a/testsuite/tests/driver/T13710/Makefile b/testsuite/tests/driver/T13710/Makefile
new file mode 100644
index 0000000000..d582f94af5
--- /dev/null
+++ b/testsuite/tests/driver/T13710/Makefile
@@ -0,0 +1,6 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T13710:
+ '$(TEST_HC)' $(TEST_HC_OPTS) --make B.hs
diff --git a/testsuite/tests/driver/T13710/T13710.stdout b/testsuite/tests/driver/T13710/T13710.stdout
new file mode 100644
index 0000000000..2d729289db
--- /dev/null
+++ b/testsuite/tests/driver/T13710/T13710.stdout
@@ -0,0 +1,3 @@
+[1 of 3] Compiling A[boot] ( A.hs-boot, A.o-boot )
+[2 of 3] Compiling B ( B.hs, B.o )
+[3 of 3] Compiling A ( A.hs, A.o )
diff --git a/testsuite/tests/driver/T13710/all.T b/testsuite/tests/driver/T13710/all.T
new file mode 100644
index 0000000000..64daacc96b
--- /dev/null
+++ b/testsuite/tests/driver/T13710/all.T
@@ -0,0 +1,4 @@
+test('T13710',
+ [extra_files(['A.hs', 'A.hs-boot', 'B.hs'])],
+ run_command,
+ ['$MAKE -s --no-print-directory T13710'])
diff --git a/testsuite/tests/gadt/gadt7.stderr b/testsuite/tests/gadt/gadt7.stderr
index ea9033ac6c..bb179975fb 100644
--- a/testsuite/tests/gadt/gadt7.stderr
+++ b/testsuite/tests/gadt/gadt7.stderr
@@ -1,15 +1,15 @@
gadt7.hs:16:38: error:
• Couldn't match expected type ‘p1’ with actual type ‘p’
- ‘p1’ is untouchable
+ ‘p’ is untouchable
inside the constraints: a ~ Int
bound by a pattern with constructor: K :: T Int,
in a case alternative
at gadt7.hs:16:33
- ‘p1’ is a rigid type variable bound by
- the inferred type of i1b :: T a -> p -> p1 at gadt7.hs:16:1-44
‘p’ is a rigid type variable bound by
the inferred type of i1b :: T a -> p -> p1 at gadt7.hs:16:1-44
+ ‘p1’ is a rigid type variable bound by
+ the inferred type of i1b :: T a -> p -> p1 at gadt7.hs:16:1-44
Possible fix: add a type signature for ‘i1b’
• In the expression: y1
In a case alternative: K -> y1
diff --git a/testsuite/tests/ghc-api/T6145.hs b/testsuite/tests/ghc-api/T6145.hs
index fc0a71ade3..f1a619be1a 100644
--- a/testsuite/tests/ghc-api/T6145.hs
+++ b/testsuite/tests/ghc-api/T6145.hs
@@ -34,8 +34,6 @@ main = do
where
isDataCon (L _ (AbsBinds { abs_binds = bs }))
= not (isEmptyBag (filterBag isDataCon bs))
- isDataCon (L _ (AbsBindsSig { abs_sig_bind = b }))
- = isDataCon b
isDataCon (L l (f@FunBind {}))
| (MG (L _ (m:_)) _ _ _) <- fun_matches f,
(L _ (c@ConPatOut{}):_)<-hsLMatchPats m,
diff --git a/testsuite/tests/ghci.debugger/scripts/all.T b/testsuite/tests/ghci.debugger/scripts/all.T
index 96de3a334b..9e533aa192 100644
--- a/testsuite/tests/ghci.debugger/scripts/all.T
+++ b/testsuite/tests/ghci.debugger/scripts/all.T
@@ -50,8 +50,7 @@ test('break009', [extra_files(['../Test6.hs']),
test('break010', extra_files(['../Test6.hs']), ghci_script, ['break010.script'])
test('break011',
[extra_files(['../Test7.hs']),
- combined_output,
- when(msys(), expect_broken(12712))],
+ combined_output],
ghci_script, ['break011.script'])
test('break012', normal, ghci_script, ['break012.script'])
test('break013', normal, ghci_script, ['break013.script'])
diff --git a/testsuite/tests/ghci.debugger/scripts/break012.stdout b/testsuite/tests/ghci.debugger/scripts/break012.stdout
index 2e86b42713..5d478ae04e 100644
--- a/testsuite/tests/ghci.debugger/scripts/break012.stdout
+++ b/testsuite/tests/ghci.debugger/scripts/break012.stdout
@@ -1,14 +1,14 @@
Stopped in Main.g, break012.hs:5:10-18
-_result :: (p, a1 -> a1, (), a -> a -> a) = _
-a :: p = _
-b :: a2 -> a2 = _
+_result :: (a1, a2 -> a2, (), a -> a -> a) = _
+a :: a1 = _
+b :: a3 -> a3 = _
c :: () = _
d :: a -> a -> a = _
-a :: p
-b :: a2 -> a2
+a :: a1
+b :: a3 -> a3
c :: ()
d :: a -> a -> a
-a = (_t1::p)
-b = (_t2::a2 -> a2)
+a = (_t1::a1)
+b = (_t2::a3 -> a3)
c = (_t3::())
d = (_t4::a -> a -> a)
diff --git a/testsuite/tests/indexed-types/should_compile/T12369.hs b/testsuite/tests/indexed-types/should_compile/T12369.hs
new file mode 100644
index 0000000000..51cee7df03
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_compile/T12369.hs
@@ -0,0 +1,35 @@
+{-# language PolyKinds, KindSignatures, GADTs, TypeFamilies, RankNTypes, TypeInType,
+ TypeOperators, ConstraintKinds #-}
+
+module T12369 where
+
+import Data.Kind
+
+data family Fix :: (k -> *) -> k
+newtype instance Fix f = In { out :: f (Fix f) }
+
+type FREE k = (k -> Constraint) -> (k -> k)
+type f ~> g = forall a. f a -> g a
+type f ~~> g = forall a b. f a b -> g a b
+
+data family Free k :: FREE k
+
+newtype instance Free Type k p where
+ Free0 :: (forall q. k q => (p -> q) -> q) -> Free Type k p
+
+newtype instance Free (j -> Type) k p a where
+ Free1 :: (forall q. k q => (p ~> q) -> q a) -> Free (j -> Type) k p a
+
+newtype instance Free (j1 -> j2 -> Type) k p a b where
+ Free2 :: (forall q. k q => (p ~~> q) -> q a b) -> Free (j1 -> j2 -> Type) k p a b
+
+data family Free2 :: FREE k
+
+newtype instance Free2 :: FREE Type where
+ Free20 :: (forall q. k q => (p -> q) -> q) -> Free2 k p
+
+newtype instance Free2 :: forall k. FREE (k -> Type) where
+ Free21 :: (forall q. k q => (p ~> q) -> q a) -> Free2 k p a
+
+newtype instance Free2 :: forall k1 k2. FREE (k1 -> k2 -> Type) where
+ Free22 :: (forall q. k q => (p ~~> q) -> q a b) -> Free2 k p a b
diff --git a/testsuite/tests/indexed-types/should_compile/T14045.hs b/testsuite/tests/indexed-types/should_compile/T14045.hs
new file mode 100644
index 0000000000..951388bfce
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_compile/T14045.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE TypeFamilies, PolyKinds, DataKinds, GADTs #-}
+
+module T14045 where
+
+import Data.Kind
+
+data family Sing (a :: k)
+data instance Sing :: Bool -> Type where
+ SFalse :: Sing False
+ STrue :: Sing True
diff --git a/testsuite/tests/indexed-types/should_compile/all.T b/testsuite/tests/indexed-types/should_compile/all.T
index ec55113e6b..359e7d5794 100644
--- a/testsuite/tests/indexed-types/should_compile/all.T
+++ b/testsuite/tests/indexed-types/should_compile/all.T
@@ -265,3 +265,5 @@ test('T13398a', normal, compile, [''])
test('T13398b', normal, compile, [''])
test('T13662', normal, compile, [''])
test('T13705', normal, compile, [''])
+test('T12369', normal, compile, [''])
+test('T14045', normal, compile, [''])
diff --git a/testsuite/tests/indexed-types/should_fail/Overlap4.stderr b/testsuite/tests/indexed-types/should_fail/Overlap4.stderr
index 937a18d861..53dc8b4ac0 100644
--- a/testsuite/tests/indexed-types/should_fail/Overlap4.stderr
+++ b/testsuite/tests/indexed-types/should_fail/Overlap4.stderr
@@ -1,6 +1,4 @@
-Overlap4.hs:7:12: error:
- • Expecting one more argument to ‘Maybe’
- Expected a type, but ‘Maybe’ has kind ‘* -> *’
- • In the type ‘Maybe’
- In the type family declaration for ‘F’
+Overlap4.hs:7:3: error:
+ • Number of parameters must match family declaration; expected 2
+ • In the type family declaration for ‘F’
diff --git a/testsuite/tests/indexed-types/should_fail/SimpleFail1a.stderr b/testsuite/tests/indexed-types/should_fail/SimpleFail1a.stderr
index b0c91af91a..8637eaa892 100644
--- a/testsuite/tests/indexed-types/should_fail/SimpleFail1a.stderr
+++ b/testsuite/tests/indexed-types/should_fail/SimpleFail1a.stderr
@@ -1,4 +1,5 @@
SimpleFail1a.hs:4:1: error:
- • Number of parameters must match family declaration; expected 2
+ • Expecting one more argument to ‘T1 Int’
+ Expected a type, but ‘T1 Int’ has kind ‘* -> *’
• In the data instance declaration for ‘T1’
diff --git a/testsuite/tests/indexed-types/should_fail/SimpleFail1b.stderr b/testsuite/tests/indexed-types/should_fail/SimpleFail1b.stderr
index e872f115a2..32303ecccb 100644
--- a/testsuite/tests/indexed-types/should_fail/SimpleFail1b.stderr
+++ b/testsuite/tests/indexed-types/should_fail/SimpleFail1b.stderr
@@ -1,6 +1,4 @@
-SimpleFail1b.hs:4:1:
- Too many parameters to T1:
- Char is unexpected;
- expected only two parameters
- In the data instance declaration for ‘T1’
+SimpleFail1b.hs:4:1: error:
+ • Expected kind ‘* -> *’, but ‘T1 Int Bool’ has kind ‘*’
+ • In the data instance declaration for ‘T1’
diff --git a/testsuite/tests/indexed-types/should_fail/SimpleFail2a.stderr b/testsuite/tests/indexed-types/should_fail/SimpleFail2a.stderr
index a9262eb9ec..9bd571e2b9 100644
--- a/testsuite/tests/indexed-types/should_fail/SimpleFail2a.stderr
+++ b/testsuite/tests/indexed-types/should_fail/SimpleFail2a.stderr
@@ -2,6 +2,6 @@
SimpleFail2a.hs:11:3: error:
• Type indexes must match class instance head
Expected: Sd Int
- Actual: Sd a
+ Actual: Sd a :: *
• In the data instance declaration for ‘Sd’
In the instance declaration for ‘C Int’
diff --git a/testsuite/tests/indexed-types/should_fail/T12867.stderr b/testsuite/tests/indexed-types/should_fail/T12867.stderr
index 40e566b3ec..2115e43541 100644
--- a/testsuite/tests/indexed-types/should_fail/T12867.stderr
+++ b/testsuite/tests/indexed-types/should_fail/T12867.stderr
@@ -1,7 +1,6 @@
T12867.hs:7:21: error:
- • Expecting one fewer arguments to ‘TestM’
- Expected kind ‘k0 -> *’, but ‘TestM’ has kind ‘*’
+ • Expected kind ‘k0 -> *’, but ‘TestM’ has kind ‘*’
• In the first argument of ‘Eq’, namely ‘(TestM a)’
In the type ‘(Eq (TestM a))’
In the type declaration for ‘Test2’
diff --git a/testsuite/tests/indexed-types/should_fail/T13877.hs b/testsuite/tests/indexed-types/should_fail/T13877.hs
new file mode 100644
index 0000000000..ee5f16b1f3
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_fail/T13877.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeInType #-}
+{-# LANGUAGE TypeOperators #-}
+module T13877 where
+
+import Data.Kind
+
+data family Sing (a :: k)
+data instance Sing (z :: [a]) where
+ SNil :: Sing '[]
+ SCons :: Sing x -> Sing xs -> Sing (x:xs)
+
+data TyFun :: * -> * -> *
+type a ~> b = TyFun a b -> *
+infixr 0 ~>
+
+type family Apply (f :: k1 ~> k2) (x :: k1) :: k2
+type a @@ b = Apply a b
+infixl 9 @@
+
+data FunArrow = (:->) | (:~>)
+
+class FunType (arr :: FunArrow) where
+ type Fun (k1 :: Type) arr (k2 :: Type) :: Type
+
+class FunType arr => AppType (arr :: FunArrow) where
+ type App k1 arr k2 (f :: Fun k1 arr k2) (x :: k1) :: k2
+
+type FunApp arr = (FunType arr, AppType arr)
+
+instance FunType (:->) where
+ type Fun k1 (:->) k2 = k1 -> k2
+
+instance AppType (:->) where
+ type App k1 (:->) k2 (f :: k1 -> k2) x = f x
+
+instance FunType (:~>) where
+ type Fun k1 (:~>) k2 = k1 ~> k2
+
+instance AppType (:~>) where
+ type App k1 (:~>) k2 (f :: k1 ~> k2) x = f @@ x
+
+infixr 0 -?>
+type (-?>) (k1 :: Type) (k2 :: Type) (arr :: FunArrow) = Fun k1 arr k2
+
+listElim :: forall (a :: Type) (p :: [a] -> Type) (l :: [a]).
+ Sing l
+ -> p '[]
+ -> (forall (x :: a) (xs :: [a]). Sing x -> Sing xs -> p xs -> p (x:xs))
+ -> p l
+listElim = listElimPoly @(:->) @a @p @l
+
+listElimTyFun :: forall (a :: Type) (p :: [a] ~> Type) (l :: [a]).
+ Sing l
+ -> p @@ '[]
+ -> (forall (x :: a) (xs :: [a]). Sing x -> Sing xs -> p @@ xs -> p @@ (x:xs))
+ -> p @@ l
+listElimTyFun = listElimPoly @(:->) @a @p @l
+
+listElimPoly :: forall (arr :: FunArrow) (a :: Type) (p :: ([a] -?> Type) arr) (l :: [a]).
+ FunApp arr
+ => Sing l
+ -> App [a] arr Type p '[]
+ -> (forall (x :: a) (xs :: [a]). Sing x -> Sing xs -> App [a] arr Type p xs -> App [a] arr Type p (x:xs))
+ -> App [a] arr Type p l
+listElimPoly SNil pNil _ = pNil
+listElimPoly (SCons x (xs :: Sing xs)) pNil pCons = pCons x xs (listElimPoly @arr @a @p @xs xs pNil pCons)
diff --git a/testsuite/tests/indexed-types/should_fail/T13877.stderr b/testsuite/tests/indexed-types/should_fail/T13877.stderr
new file mode 100644
index 0000000000..4498d97a41
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_fail/T13877.stderr
@@ -0,0 +1,31 @@
+
+T13877.hs:65:17: error:
+ • Couldn't match type ‘p xs’ with ‘Apply p xs’
+ Expected type: Sing x
+ -> Sing xs -> App [a] (':->) * p xs -> App [a] (':->) * p (x : xs)
+ Actual type: Sing x -> Sing xs -> (p @@ xs) -> p @@ (x : xs)
+ • In the expression: listElimPoly @(:->) @a @p @l
+ In an equation for ‘listElimTyFun’:
+ listElimTyFun = listElimPoly @(:->) @a @p @l
+ • Relevant bindings include
+ listElimTyFun :: Sing l
+ -> (p @@ '[])
+ -> (forall (x :: a) (xs :: [a]).
+ Sing x -> Sing xs -> (p @@ xs) -> p @@ (x : xs))
+ -> p @@ l
+ (bound at T13877.hs:65:1)
+
+T13877.hs:65:41: error:
+ • Expecting one more argument to ‘p’
+ Expected kind ‘(-?>) [a] * (':->)’, but ‘p’ has kind ‘[a] ~> *’
+ • In the type ‘p’
+ In the expression: listElimPoly @(:->) @a @p @l
+ In an equation for ‘listElimTyFun’:
+ listElimTyFun = listElimPoly @(:->) @a @p @l
+ • Relevant bindings include
+ listElimTyFun :: Sing l
+ -> (p @@ '[])
+ -> (forall (x :: a) (xs :: [a]).
+ Sing x -> Sing xs -> (p @@ xs) -> p @@ (x : xs))
+ -> p @@ l
+ (bound at T13877.hs:65:1)
diff --git a/testsuite/tests/indexed-types/should_fail/T14033.hs b/testsuite/tests/indexed-types/should_fail/T14033.hs
new file mode 100644
index 0000000000..2c8ab68a05
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_fail/T14033.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module T14033 where
+
+newtype Zero = Zero
+newtype Succ a = Succ a
+
+type family Add n m :: * where
+ Add Zero m = m
+ Add (Succ n) m = Succ (Add n m)
diff --git a/testsuite/tests/indexed-types/should_fail/T14033.stderr b/testsuite/tests/indexed-types/should_fail/T14033.stderr
new file mode 100644
index 0000000000..fbc6b54486
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_fail/T14033.stderr
@@ -0,0 +1,6 @@
+
+T14033.hs:5:16: error:
+ • The constructor of a newtype must have exactly one field
+ but ‘Zero’ has none
+ • In the definition of data constructor ‘Zero’
+ In the newtype declaration for ‘Zero’
diff --git a/testsuite/tests/indexed-types/should_fail/T14045a.hs b/testsuite/tests/indexed-types/should_fail/T14045a.hs
new file mode 100644
index 0000000000..fc545a8d41
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_fail/T14045a.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE TypeFamilies, PolyKinds, DataKinds, GADTs, FlexibleInstances #-}
+
+module T14045a where
+
+import Data.Kind
+
+class C (a :: k) where
+ data S (a :: k)
+
+instance C (z :: Bool) where
+ data S :: Bool -> Type where
+ SF :: S False
+ ST :: S True
diff --git a/testsuite/tests/indexed-types/should_fail/T14045a.stderr b/testsuite/tests/indexed-types/should_fail/T14045a.stderr
new file mode 100644
index 0000000000..0306bd2a07
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_fail/T14045a.stderr
@@ -0,0 +1,7 @@
+
+T14045a.hs:11:3: error:
+ • Type indexes must match class instance head
+ Expected: S z
+ Actual: S :: Bool -> Type
+ • In the data instance declaration for ‘S’
+ In the instance declaration for ‘C (z :: Bool)’
diff --git a/testsuite/tests/indexed-types/should_fail/T5934.stderr b/testsuite/tests/indexed-types/should_fail/T5934.stderr
index e303e54f74..21af0d868a 100644
--- a/testsuite/tests/indexed-types/should_fail/T5934.stderr
+++ b/testsuite/tests/indexed-types/should_fail/T5934.stderr
@@ -5,16 +5,3 @@ T5934.hs:12:7: error:
GHC doesn't yet support impredicative polymorphism
• In the expression: 0
In an equation for ‘run’: run = 0
-
-T5934.hs:12:7: error:
- • Ambiguous type variable ‘a0’ arising from the literal ‘0’
- prevents the constraint ‘(Num a0)’ from being solved.
- Probable fix: use a type annotation to specify what ‘a0’ should be.
- These potential instances exist:
- instance Num Integer -- Defined in ‘GHC.Num’
- instance Num Double -- Defined in ‘GHC.Float’
- instance Num Float -- Defined in ‘GHC.Float’
- ...plus two others
- (use -fprint-potential-instances to see them all)
- • In the expression: 0
- In an equation for ‘run’: run = 0
diff --git a/testsuite/tests/indexed-types/should_fail/TyFamArity1.stderr b/testsuite/tests/indexed-types/should_fail/TyFamArity1.stderr
index 8b3d5f5910..46521deeba 100644
--- a/testsuite/tests/indexed-types/should_fail/TyFamArity1.stderr
+++ b/testsuite/tests/indexed-types/should_fail/TyFamArity1.stderr
@@ -1,6 +1,4 @@
-TyFamArity1.hs:4:23: error:
- • Expecting one more argument to ‘IO’
- Expected a type, but ‘IO’ has kind ‘* -> *’
- • In the type ‘IO’
- In the type instance declaration for ‘T’
+TyFamArity1.hs:4:15: error:
+ • Number of parameters must match family declaration; expected 2
+ • In the type instance declaration for ‘T’
diff --git a/testsuite/tests/indexed-types/should_fail/TyFamArity2.stderr b/testsuite/tests/indexed-types/should_fail/TyFamArity2.stderr
index 778d8ab9f4..8d48921946 100644
--- a/testsuite/tests/indexed-types/should_fail/TyFamArity2.stderr
+++ b/testsuite/tests/indexed-types/should_fail/TyFamArity2.stderr
@@ -1,11 +1,4 @@
TyFamArity2.hs:4:15: error:
- • Too many parameters to T:
- Float is unexpected;
- expected only one parameter
+ • Number of parameters must match family declaration; expected 1
• In the type instance declaration for ‘T’
-
-TyFamArity2.hs:4:29: error:
- • Expected kind ‘* -> *’, but ‘Char’ has kind ‘*’
- • In the type ‘Char’
- In the type instance declaration for ‘T’
diff --git a/testsuite/tests/indexed-types/should_fail/all.T b/testsuite/tests/indexed-types/should_fail/all.T
index 50257e6bb8..c3a2f16d6d 100644
--- a/testsuite/tests/indexed-types/should_fail/all.T
+++ b/testsuite/tests/indexed-types/should_fail/all.T
@@ -135,3 +135,6 @@ test('T7102a', normal, ghci_script, ['T7102a.script'])
test('T13271', normal, compile_fail, [''])
test('T13674', normal, compile_fail, [''])
test('T13784', normal, compile_fail, [''])
+test('T13877', normal, compile_fail, [''])
+test('T14033', normal, compile_fail, [''])
+test('T14045a', normal, compile_fail, [''])
diff --git a/testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr b/testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
index 663a7d7f2e..d96c448cf9 100644
--- a/testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
+++ b/testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
@@ -275,5 +275,6 @@
(FromSource))
(WpHole) {NameSet:
[]}
- []))]}))]}
+ []))]}
+ (False)))]}
diff --git a/testsuite/tests/parser/should_fail/T7848.hs b/testsuite/tests/parser/should_fail/T7848.hs
index 25f0af7ee0..920f28e8c9 100644
--- a/testsuite/tests/parser/should_fail/T7848.hs
+++ b/testsuite/tests/parser/should_fail/T7848.hs
@@ -8,4 +8,4 @@ x (+) ((&)@z) ((:&&) a b) (c :&& d) (e `A` f) (A g h) = y
y _ = (&)
{-# INLINE (&) #-}
{-# SPECIALIZE (&) :: a #-}
- (&) = x
+ (&) = 'c'
diff --git a/testsuite/tests/parser/should_fail/T7848.stderr b/testsuite/tests/parser/should_fail/T7848.stderr
index 95ac7374ef..413920dbe6 100644
--- a/testsuite/tests/parser/should_fail/T7848.stderr
+++ b/testsuite/tests/parser/should_fail/T7848.stderr
@@ -1,13 +1,7 @@
-T7848.hs:6:1: error:
- • Occurs check: cannot construct the infinite type:
- t ~ p0 -> p1 -> A -> A -> A -> A -> p2 -> t
- • Relevant bindings include x :: t (bound at T7848.hs:6:1)
-
T7848.hs:10:9: error:
- • Couldn't match expected type ‘t’ with actual type ‘a’
- because type variable ‘a’ would escape its scope
- This (rigid, skolem) type variable is bound by
+ • Couldn't match expected type ‘Char’ with actual type ‘a’
+ ‘a’ is a rigid type variable bound by
the type signature for:
(&) :: forall a. a
at T7848.hs:10:9-35
@@ -20,5 +14,4 @@ T7848.hs:10:9: error:
y _ = (&)
{-# INLINE (&) #-}
{-# SPECIALIZE (&) :: a #-}
- (&) = x
- • Relevant bindings include x :: t (bound at T7848.hs:6:1)
+ (&) = 'c'
diff --git a/testsuite/tests/patsyn/should_compile/T13768.hs b/testsuite/tests/patsyn/should_compile/T13768.hs
new file mode 100644
index 0000000000..c4510bd20a
--- /dev/null
+++ b/testsuite/tests/patsyn/should_compile/T13768.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE ViewPatterns #-}
+module T13768 where
+
+data NS (f :: k -> *) (xs :: [k]) = NS Int
+
+data IsNS (f :: k -> *) (xs :: [k]) where
+ IsZ :: f x -> IsNS f (x ': xs)
+ IsS :: NS f xs -> IsNS f (x ': xs)
+
+isNS :: NS f xs -> IsNS f xs
+isNS = undefined
+
+pattern Z :: () => (xs' ~ (x ': xs)) => f x -> NS f xs'
+pattern Z x <- (isNS -> IsZ x)
+
+pattern S :: () => (xs' ~ (x ': xs)) => NS f xs -> NS f xs'
+pattern S p <- (isNS -> IsS p)
+
+{-# COMPLETE Z, S #-}
+
+data SList :: [k] -> * where
+ SNil :: SList '[]
+ SCons :: SList (x ': xs)
+
+go :: SList ys -> NS f ys -> Int
+go SCons (Z _) = 0
+go SCons (S _) = 1
+go SNil _ = error "inaccessible"
diff --git a/testsuite/tests/patsyn/should_compile/T14058.hs b/testsuite/tests/patsyn/should_compile/T14058.hs
new file mode 100644
index 0000000000..7c263b8f44
--- /dev/null
+++ b/testsuite/tests/patsyn/should_compile/T14058.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE TypeInType #-}
+module T14058 where
+
+import T14058a (Sing(..))
+
+foo :: Sing ('[ '[] ] :: [[a]])
+foo = SCons SNil SNil
diff --git a/testsuite/tests/patsyn/should_compile/T14058a.hs b/testsuite/tests/patsyn/should_compile/T14058a.hs
new file mode 100644
index 0000000000..a7e5d97b79
--- /dev/null
+++ b/testsuite/tests/patsyn/should_compile/T14058a.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeInType #-}
+{-# LANGUAGE TypeOperators #-}
+module T14058a (Sing(.., SCons)) where
+
+data family Sing (a :: k)
+
+data instance Sing (z :: [a]) where
+ SNil :: Sing '[]
+ (:%) :: Sing x -> Sing xs -> Sing (x:xs)
+
+pattern SCons :: forall a (z :: [a]). ()
+ => forall (x :: a) (xs :: [a]). z ~ (x:xs)
+ => Sing x -> Sing xs -> Sing z
+pattern SCons x xs = (:%) x xs
+{-# COMPLETE SNil, SCons #-}
diff --git a/testsuite/tests/patsyn/should_compile/all.T b/testsuite/tests/patsyn/should_compile/all.T
index 30319c7050..b8c9806694 100644
--- a/testsuite/tests/patsyn/should_compile/all.T
+++ b/testsuite/tests/patsyn/should_compile/all.T
@@ -70,3 +70,6 @@ test('T13441b', normal, compile_fail, [''])
test('T13454', normal, compile, [''])
test('T13752', normal, compile, [''])
test('T13752a', normal, compile, [''])
+test('T13768', normal, compile, [''])
+test('T14058', [extra_files(['T14058.hs', 'T14058a.hs'])],
+ multimod_compile, ['T14058', '-v0'])
diff --git a/testsuite/tests/perf/compiler/all.T b/testsuite/tests/perf/compiler/all.T
index 03892714c7..baca57cf5e 100644
--- a/testsuite/tests/perf/compiler/all.T
+++ b/testsuite/tests/perf/compiler/all.T
@@ -444,7 +444,7 @@ test('T5631',
# 2014-04-04: 346389856 (x86 Windows, 64 bit machine)
# 2014-12-01: 390199244 (Windows laptop)
# 2016-04-06: 570137436 (amd64/Linux) many reasons
- (wordsize(64), 1037482512, 5)]),
+ (wordsize(64), 1106015512, 5)]),
# expected value: 774595008 (amd64/Linux):
# expected value: 735486328 (amd64/Linux) 2012/12/12:
# expected value: 690742040 (amd64/Linux) Call Arity improvements
@@ -459,6 +459,8 @@ test('T5631',
# 2017-02-17: 1517484488 (amd64/Linux) Type-indexed Typeable
# 2017-03-03: 1065147968 (amd64/Linux) Share Typeable KindReps
# 2017-03-31: 1037482512 (amd64/Linux) Fix memory leak in simplifier
+ # 2017-07-27: 1106015512 (Mac) Regresssion from tracking visibility in TypeEqOrigin
+ # should be fixed by #14037
only_ways(['normal'])
],
compile,
diff --git a/testsuite/tests/pmcheck/should_compile/T14086.hs b/testsuite/tests/pmcheck/should_compile/T14086.hs
new file mode 100644
index 0000000000..de91229c24
--- /dev/null
+++ b/testsuite/tests/pmcheck/should_compile/T14086.hs
@@ -0,0 +1,6 @@
+{-# language TypeInType, EmptyCase #-}
+module T14086 where
+import Data.Kind
+
+f :: Type -> Int
+f x = case x of
diff --git a/testsuite/tests/pmcheck/should_compile/all.T b/testsuite/tests/pmcheck/should_compile/all.T
index f44034b0d2..cabe23950b 100644
--- a/testsuite/tests/pmcheck/should_compile/all.T
+++ b/testsuite/tests/pmcheck/should_compile/all.T
@@ -41,6 +41,8 @@ test('T11276', compile_timeout_multiplier(0.01), compile, ['-fwarn-incomplete-pa
test('T11303b', compile_timeout_multiplier(0.01), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns +RTS -M1G -RTS'])
test('T11374', compile_timeout_multiplier(0.01), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns +RTS -M1G -RTS'])
test('T11195', compile_timeout_multiplier(0.60), compile, ['-package ghc -fwarn-incomplete-patterns -fwarn-overlapping-patterns +RTS -M2G -RTS'])
+test('T14086', normal, compile,
+ ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns'])
# Other tests
test('pmc001', [], compile,
diff --git a/testsuite/tests/polykinds/KindVType.stderr b/testsuite/tests/polykinds/KindVType.stderr
index 7ce3404579..27e2e588a5 100644
--- a/testsuite/tests/polykinds/KindVType.stderr
+++ b/testsuite/tests/polykinds/KindVType.stderr
@@ -1,6 +1,6 @@
KindVType.hs:8:8: error:
- • Couldn't match type ‘*’ with ‘* -> *’
+ • Couldn't match type ‘Int’ with ‘Maybe’
Expected type: Proxy Maybe
Actual type: Proxy Int
• In the expression: (Proxy :: Proxy Int)
diff --git a/testsuite/tests/polykinds/T12593.stderr b/testsuite/tests/polykinds/T12593.stderr
index 4b551558a1..4dda0cddd5 100644
--- a/testsuite/tests/polykinds/T12593.stderr
+++ b/testsuite/tests/polykinds/T12593.stderr
@@ -1,7 +1,6 @@
T12593.hs:11:16: error:
- • Expecting two fewer arguments to ‘Free k k4 k5 p’
- Expected kind ‘k0 -> k1 -> *’, but ‘Free k k4 k5 p’ has kind ‘*’
+ • Expected kind ‘k0 -> k1 -> *’, but ‘Free k k1 k2 p’ has kind ‘*’
• In the type signature:
run :: k2 q =>
Free k k1 k2 p a b
@@ -20,12 +19,68 @@ T12593.hs:12:31: error:
-> (forall (c :: k) (d :: k1). p c d -> q c d) -> q a b
T12593.hs:12:40: error:
- • Expecting two more arguments to ‘k4’
+ • Expecting two more arguments to ‘k1’
Expected a type, but
- ‘k4’ has kind
+ ‘k1’ has kind
‘((k0 -> k1 -> *) -> Constraint) -> (k2 -> k3 -> *) -> *’
• In the kind ‘k1’
In the type signature:
run :: k2 q =>
Free k k1 k2 p a b
-> (forall (c :: k) (d :: k1). p c d -> q c d) -> q a b
+
+T12593.hs:12:47: error:
+ • Couldn't match kind ‘(((k0 -> k1 -> *) -> Constraint)
+ -> (k2 -> k3 -> *) -> *)
+ -> Constraint’
+ with ‘*’
+ When matching kinds
+ k :: (((k0 -> k1 -> *) -> Constraint) -> (k2 -> k3 -> *) -> *)
+ -> Constraint
+ k2 :: *
+ • In the first argument of ‘p’, namely ‘c’
+ In the type signature:
+ run :: k2 q =>
+ Free k k1 k2 p a b
+ -> (forall (c :: k) (d :: k1). p c d -> q c d) -> q a b
+
+T12593.hs:12:49: error:
+ • Couldn't match kind ‘((k0 -> k1 -> *) -> Constraint)
+ -> (k2 -> k3 -> *) -> *’
+ with ‘*’
+ When matching kinds
+ k4 :: ((k0 -> k1 -> *) -> Constraint) -> (k2 -> k3 -> *) -> *
+ k3 :: *
+ • In the second argument of ‘p’, namely ‘d’
+ In the type signature:
+ run :: k2 q =>
+ Free k k1 k2 p a b
+ -> (forall (c :: k) (d :: k1). p c d -> q c d) -> q a b
+
+T12593.hs:12:56: error:
+ • Couldn't match kind ‘(((k0 -> k1 -> *) -> Constraint)
+ -> (k2 -> k3 -> *) -> *)
+ -> Constraint’
+ with ‘*’
+ When matching kinds
+ k :: (((k0 -> k1 -> *) -> Constraint) -> (k2 -> k3 -> *) -> *)
+ -> Constraint
+ k0 :: *
+ • In the first argument of ‘q’, namely ‘c’
+ In the type signature:
+ run :: k2 q =>
+ Free k k1 k2 p a b
+ -> (forall (c :: k) (d :: k1). p c d -> q c d) -> q a b
+
+T12593.hs:12:58: error:
+ • Couldn't match kind ‘((k0 -> k1 -> *) -> Constraint)
+ -> (k2 -> k3 -> *) -> *’
+ with ‘*’
+ When matching kinds
+ k4 :: ((k0 -> k1 -> *) -> Constraint) -> (k2 -> k3 -> *) -> *
+ k1 :: *
+ • In the second argument of ‘q’, namely ‘d’
+ In the type signature:
+ run :: k2 q =>
+ Free k k1 k2 p a b
+ -> (forall (c :: k) (d :: k1). p c d -> q c d) -> q a b
diff --git a/testsuite/tests/polykinds/T13555.stderr b/testsuite/tests/polykinds/T13555.stderr
index eaea0335cf..e822f6e596 100644
--- a/testsuite/tests/polykinds/T13555.stderr
+++ b/testsuite/tests/polykinds/T13555.stderr
@@ -9,26 +9,7 @@ T13555.hs:25:14: error:
TaggedT m Maybe (CRTInfo (GF fp d))
at T13555.hs:25:14-79
Expected type: TaggedT m Maybe (CRTInfo (GF fp d))
- Actual type: TaggedT m Maybe (CRTInfo (GF fp d))
- • When checking that instance signature for ‘crtInfo’
- is more general than its signature in the class
- Instance sig: forall (m :: k0).
- Reflects m Int =>
- TaggedT m Maybe (CRTInfo (GF fp d))
- Class sig: forall k2 (m :: k2).
- Reflects m Int =>
- TaggedT m Maybe (CRTInfo (GF fp d))
- In the instance declaration for ‘CRTrans Maybe (GF fp d)’
-
-T13555.hs:25:14: error:
- • Could not deduce (Reflects m Int)
- from the context: Reflects m Int
- bound by the type signature for:
- crtInfo :: forall k2 (m :: k2).
- Reflects m Int =>
- TaggedT m Maybe (CRTInfo (GF fp d))
- at T13555.hs:25:14-79
- The type variable ‘k0’ is ambiguous
+ Actual type: TaggedT m0 Maybe (CRTInfo (GF fp d))
• When checking that instance signature for ‘crtInfo’
is more general than its signature in the class
Instance sig: forall (m :: k0).
diff --git a/testsuite/tests/polykinds/T6039.stderr b/testsuite/tests/polykinds/T6039.stderr
index 4c31bb4aa4..048efd538f 100644
--- a/testsuite/tests/polykinds/T6039.stderr
+++ b/testsuite/tests/polykinds/T6039.stderr
@@ -1,5 +1,4 @@
T6039.hs:5:14: error:
- • Expecting one fewer arguments to ‘j’
- Expected kind ‘* -> *’, but ‘j’ has kind ‘*’
+ • Expected kind ‘* -> *’, but ‘j’ has kind ‘*’
• In the kind ‘j k’
diff --git a/testsuite/tests/polykinds/T7278.stderr b/testsuite/tests/polykinds/T7278.stderr
index 676be2cb0f..265e27892b 100644
--- a/testsuite/tests/polykinds/T7278.stderr
+++ b/testsuite/tests/polykinds/T7278.stderr
@@ -1,6 +1,5 @@
T7278.hs:9:43: error:
- • Expecting two fewer arguments to ‘t’
- Expected kind ‘* -> * -> *’, but ‘t’ has kind ‘k’
+ • Expected kind ‘* -> * -> *’, but ‘t’ has kind ‘k’
• In the type signature:
f :: (C (t :: k) (TF t)) => TF t p1 p0 -> t p1 p0
diff --git a/testsuite/tests/polykinds/T7438.stderr b/testsuite/tests/polykinds/T7438.stderr
index a198657754..6c4eec47f2 100644
--- a/testsuite/tests/polykinds/T7438.stderr
+++ b/testsuite/tests/polykinds/T7438.stderr
@@ -1,16 +1,16 @@
T7438.hs:6:14: error:
• Couldn't match expected type ‘p1’ with actual type ‘p’
- ‘p1’ is untouchable
+ ‘p’ is untouchable
inside the constraints: b ~ a
bound by a pattern with constructor:
Nil :: forall k (a :: k). Thrist a a,
in an equation for ‘go’
at T7438.hs:6:4-6
- ‘p1’ is a rigid type variable bound by
- the inferred type of go :: Thrist a b -> p -> p1 at T7438.hs:6:1-16
‘p’ is a rigid type variable bound by
the inferred type of go :: Thrist a b -> p -> p1 at T7438.hs:6:1-16
+ ‘p1’ is a rigid type variable bound by
+ the inferred type of go :: Thrist a b -> p -> p1 at T7438.hs:6:1-16
Possible fix: add a type signature for ‘go’
• In the expression: acc
In an equation for ‘go’: go Nil acc = acc
diff --git a/testsuite/tests/polykinds/T8566.stderr b/testsuite/tests/polykinds/T8566.stderr
index 1e7818c5ef..0794442edc 100644
--- a/testsuite/tests/polykinds/T8566.stderr
+++ b/testsuite/tests/polykinds/T8566.stderr
@@ -1,6 +1,6 @@
T8566.hs:32:9: error:
- • Could not deduce (C ('AA (t (I a ps)) as) ps fs0)
+ • Could not deduce (C ('AA (t1 (I a ps)) as) ps fs0)
arising from a use of ‘c’
from the context: C ('AA (t (I a ps)) as) ps fs
bound by the instance declaration at T8566.hs:30:10-67
diff --git a/testsuite/tests/polykinds/T8616.stderr b/testsuite/tests/polykinds/T8616.stderr
index 00c9c6328e..6249bf7b62 100644
--- a/testsuite/tests/polykinds/T8616.stderr
+++ b/testsuite/tests/polykinds/T8616.stderr
@@ -1,6 +1,6 @@
T8616.hs:8:29: error:
- • Expected a type, but ‘Any’ has kind ‘k’
+ • Expected a type, but ‘(Any :: k)’ has kind ‘k’
• In an expression type signature: (Any :: k)
In the expression: undefined :: (Any :: k)
In an equation for ‘withSomeSing’:
diff --git a/testsuite/tests/polykinds/T9017.stderr b/testsuite/tests/polykinds/T9017.stderr
index 79a9a4617f..d9483c8490 100644
--- a/testsuite/tests/polykinds/T9017.stderr
+++ b/testsuite/tests/polykinds/T9017.stderr
@@ -1,12 +1,16 @@
T9017.hs:8:7: error:
- • Couldn't match kind ‘k’ with ‘*’
- ‘k’ is a rigid type variable bound by
+ • Couldn't match kind ‘k1’ with ‘*’
+ ‘k1’ is a rigid type variable bound by
the type signature for:
foo :: forall k k1 (a :: k -> k1 -> *) (b :: k) (m :: k -> k1).
a b (m b)
at T9017.hs:7:1-16
- When matching the kind of ‘a’
+ When matching types
+ a1 :: * -> * -> *
+ a :: k -> k1 -> *
+ Expected type: a b (m b)
+ Actual type: a1 a0 (m0 a0)
• In the expression: arr return
In an equation for ‘foo’: foo = arr return
• Relevant bindings include
diff --git a/testsuite/tests/polykinds/T9200b.stderr b/testsuite/tests/polykinds/T9200b.stderr
index 22f9df73f1..7c3cb65bd0 100644
--- a/testsuite/tests/polykinds/T9200b.stderr
+++ b/testsuite/tests/polykinds/T9200b.stderr
@@ -1,5 +1,5 @@
T9200b.hs:8:5: error:
- Expected kind ‘k’, but ‘'True’ has kind ‘Bool’
- In the first argument of ‘F’, namely ‘True’
- In the type family declaration for ‘F’
+ • Expected kind ‘k’, but ‘True’ has kind ‘Bool’
+ • In the first argument of ‘F’, namely ‘True’
+ In the type family declaration for ‘F’
diff --git a/testsuite/tests/programs/galois_raytrace/Eval.hs b/testsuite/tests/programs/galois_raytrace/Eval.hs
index bf43d10605..001842edad 100644
--- a/testsuite/tests/programs/galois_raytrace/Eval.hs
+++ b/testsuite/tests/programs/galois_raytrace/Eval.hs
@@ -243,7 +243,7 @@ doPrimOp primOp op args
show op ++ " takes " ++ show (length types) ++ " argument" ++ s
++ " with" ++ the ++ " type" ++ s ++ "\n|\n|" ++
" " ++ unwords [ show ty | ty <- types ] ++ "\n|\n|" ++
- " currently, the relevent argument" ++ s ++ " on the stack " ++
+ " currently, the relevant argument" ++ s ++ " on the stack " ++
are ++ "\n|\n| " ++
unwords [ "(" ++ show arg ++ ")"
| arg <- reverse (take (length types) args) ] ++ "\n|\n| "
diff --git a/testsuite/tests/quasiquotation/Makefile b/testsuite/tests/quasiquotation/Makefile
index 8e2e7e7c78..ebc91d23e5 100644
--- a/testsuite/tests/quasiquotation/Makefile
+++ b/testsuite/tests/quasiquotation/Makefile
@@ -9,3 +9,7 @@ T4150:
'$(TEST_HC)' $(TEST_HC_OPTS) -v0 -c T4150A.hs
-'$(TEST_HC)' $(TEST_HC_OPTS) -v0 -c T4150.hs
+T14028:
+ '$(TEST_HC)' $(TEST_HC_OPTS) T14028Quote.hs
+ '$(TEST_HC)' $(TEST_HC_OPTS) -c T14028C.c
+ '$(TEST_HC)' $(TEST_HC_OPTS) -fexternal-interpreter T14028 T14028C.o
diff --git a/testsuite/tests/quasiquotation/T14028.hs b/testsuite/tests/quasiquotation/T14028.hs
new file mode 100644
index 0000000000..5313df6e77
--- /dev/null
+++ b/testsuite/tests/quasiquotation/T14028.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+import T14028Quote
+
+s :: String
+s = [here|goes nothing|]
+
+main = putStrLn s
diff --git a/testsuite/tests/quasiquotation/T14028C.c b/testsuite/tests/quasiquotation/T14028C.c
new file mode 100644
index 0000000000..0115013d70
--- /dev/null
+++ b/testsuite/tests/quasiquotation/T14028C.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+void hi() {
+ puts("Hello, World!");
+}
diff --git a/testsuite/tests/quasiquotation/T14028Quote.hs b/testsuite/tests/quasiquotation/T14028Quote.hs
new file mode 100644
index 0000000000..01413ec100
--- /dev/null
+++ b/testsuite/tests/quasiquotation/T14028Quote.hs
@@ -0,0 +1,6 @@
+module T14028Quote where
+import Language.Haskell.TH
+import Language.Haskell.TH.Quote
+
+here :: QuasiQuoter
+here = QuasiQuoter { quoteExp = litE . stringL }
diff --git a/testsuite/tests/quasiquotation/all.T b/testsuite/tests/quasiquotation/all.T
index 84d25f8bdd..a10b8e4446 100644
--- a/testsuite/tests/quasiquotation/all.T
+++ b/testsuite/tests/quasiquotation/all.T
@@ -6,3 +6,7 @@ test('T7918',
[req_interp, extra_run_opts('"' + config.libdir + '"'),
only_ways(config.ghc_th_way), unless(have_dynamic(), skip)],
compile_and_run, ['-package ghc ' + config.ghc_th_way_flags])
+test('T14028',
+ [req_interp, only_ways(config.ghc_th_way)],
+ run_command,
+ ['$MAKE -s --no-print-directory T14028'])
diff --git a/testsuite/tests/quotes/TH_localname.stderr b/testsuite/tests/quotes/TH_localname.stderr
index a5af954e82..41eb9882e8 100644
--- a/testsuite/tests/quotes/TH_localname.stderr
+++ b/testsuite/tests/quotes/TH_localname.stderr
@@ -5,7 +5,7 @@ TH_localname.hs:3:11: error:
t0)’ from being solved.
Relevant bindings include
y :: t0 (bound at TH_localname.hs:3:6)
- x :: t0 -> Language.Haskell.TH.Lib.ExpQ
+ x :: t0 -> Language.Haskell.TH.Lib.Internal.ExpQ
(bound at TH_localname.hs:3:1)
Probable fix: use a type annotation to specify what ‘t0’ should be.
These potential instances exist:
diff --git a/testsuite/tests/rename/should_fail/rnfail026.stderr b/testsuite/tests/rename/should_fail/rnfail026.stderr
index dc6ee9691a..8bd80b1b58 100644
--- a/testsuite/tests/rename/should_fail/rnfail026.stderr
+++ b/testsuite/tests/rename/should_fail/rnfail026.stderr
@@ -1,7 +1,6 @@
rnfail026.hs:16:27: error:
- • Expecting one fewer arguments to ‘Set a’
- Expected kind ‘* -> *’, but ‘Set a’ has kind ‘*’
+ • Expected kind ‘* -> *’, but ‘Set a’ has kind ‘*’
• In the first argument of ‘Monad’, namely
‘(forall a. Eq a => Set a)’
In the instance declaration for ‘Monad (forall a. Eq a => Set a)’
diff --git a/testsuite/tests/roles/should_compile/Roles13.stderr b/testsuite/tests/roles/should_compile/Roles13.stderr
index f4b44a28c4..414ef801d5 100644
--- a/testsuite/tests/roles/should_compile/Roles13.stderr
+++ b/testsuite/tests/roles/should_compile/Roles13.stderr
@@ -13,7 +13,7 @@ convert :: Wrap Age -> Int
[GblId, Arity=1, Caf=NoCafRefs]
convert
= convert1
- `cast` (<Wrap Age>_R -> Roles13.N:Wrap[0] Roles13.N:Age[0]
+ `cast` (<Wrap Age>_R ->_R Roles13.N:Wrap[0] (Roles13.N:Age[0])
:: (Wrap Age -> Wrap Age :: *) ~R# (Wrap Age -> Int :: *))
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
diff --git a/testsuite/tests/roles/should_compile/T14101.hs b/testsuite/tests/roles/should_compile/T14101.hs
new file mode 100644
index 0000000000..3a23b5af70
--- /dev/null
+++ b/testsuite/tests/roles/should_compile/T14101.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE RoleAnnotations #-}
+module T14101 where
+
+type role Array representational
+data Array a
+
+type Arr = Array
+
+data Foo a = Foo (Arr a)
+type role Foo representational
diff --git a/testsuite/tests/roles/should_compile/all.T b/testsuite/tests/roles/should_compile/all.T
index c0b0d827c9..8d7c31f4da 100644
--- a/testsuite/tests/roles/should_compile/all.T
+++ b/testsuite/tests/roles/should_compile/all.T
@@ -7,3 +7,4 @@ test('Roles14', only_ways('normal'), compile, ['-ddump-tc -dsuppress-uniques'])
test('T8958', [normalise_fun(normalise_errmsg), only_ways('normal')], compile, ['-ddump-tc -dsuppress-uniques -fprint-typechecker-elaboration'])
test('T10263', normal, compile, [''])
test('T9204b', [], multimod_compile, ['T9204b', '-v0'])
+test('T14101', normal, compile, [''])
diff --git a/testsuite/tests/rts/T6006.stdout-mingw32 b/testsuite/tests/rts/T6006.stdout-mingw32
index 42e57fde57..962ec4b280 100644
--- a/testsuite/tests/rts/T6006.stdout-mingw32
+++ b/testsuite/tests/rts/T6006.stdout-mingw32
@@ -1,2 +1,2 @@
-"T6006.exe"
+"T6006"
[]
diff --git a/testsuite/tests/rts/flags/Makefile b/testsuite/tests/rts/flags/Makefile
new file mode 100644
index 0000000000..61900477f9
--- /dev/null
+++ b/testsuite/tests/rts/flags/Makefile
@@ -0,0 +1,6 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T1791:
+ '$(TEST_HC)' T1791.hs -o T1791 -O -rtsopts
diff --git a/testsuite/tests/rts/flags/T12870.hs b/testsuite/tests/rts/flags/T12870.hs
new file mode 100644
index 0000000000..8d536d58d6
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870.hs
@@ -0,0 +1,6 @@
+module T12870 where
+
+import System.Environment
+
+main :: IO ()
+main = getArgs >>= putStr . show
diff --git a/testsuite/tests/rts/flags/T12870_.stdout b/testsuite/tests/rts/flags/T12870_.stdout
new file mode 100644
index 0000000000..1b04d8a31c
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870_.stdout
@@ -0,0 +1 @@
+Heap overflow caught!
diff --git a/testsuite/tests/rts/flags/T12870a.stdout b/testsuite/tests/rts/flags/T12870a.stdout
new file mode 100644
index 0000000000..495a52faf3
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870a.stdout
@@ -0,0 +1 @@
+["arg1","+RTS","arg2"] \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T12870c.stderr b/testsuite/tests/rts/flags/T12870c.stderr
new file mode 100644
index 0000000000..0545774941
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870c.stderr
@@ -0,0 +1 @@
+T12870c.exe: Most RTS options are disabled. Link with -rtsopts to enable them.
diff --git a/testsuite/tests/rts/flags/T12870d.stdout b/testsuite/tests/rts/flags/T12870d.stdout
new file mode 100644
index 0000000000..495a52faf3
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870d.stdout
@@ -0,0 +1 @@
+["arg1","+RTS","arg2"] \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T12870e.stdout b/testsuite/tests/rts/flags/T12870e.stdout
new file mode 100644
index 0000000000..4859ab454c
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870e.stdout
@@ -0,0 +1 @@
+["+RTS","-G2","-RTS","arg1","--RTS","+RTS","arg2"] \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T12870f.stdout b/testsuite/tests/rts/flags/T12870f.stdout
new file mode 100644
index 0000000000..4859ab454c
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870f.stdout
@@ -0,0 +1 @@
+["+RTS","-G2","-RTS","arg1","--RTS","+RTS","arg2"] \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T12870g.hs b/testsuite/tests/rts/flags/T12870g.hs
new file mode 100644
index 0000000000..e409349827
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870g.hs
@@ -0,0 +1,8 @@
+module T12870g where
+
+import GHC.RTS.Flags (getGCFlags, generations)
+
+main :: IO ()
+main = do
+ gcFlags <- getGCFlags
+ putStr . show $ generations gcFlags
diff --git a/testsuite/tests/rts/flags/T12870g.stdout b/testsuite/tests/rts/flags/T12870g.stdout
new file mode 100644
index 0000000000..c7930257df
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870g.stdout
@@ -0,0 +1 @@
+7 \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T12870h.stdout b/testsuite/tests/rts/flags/T12870h.stdout
new file mode 100644
index 0000000000..e440e5c842
--- /dev/null
+++ b/testsuite/tests/rts/flags/T12870h.stdout
@@ -0,0 +1 @@
+3 \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/all.T b/testsuite/tests/rts/flags/all.T
new file mode 100644
index 0000000000..33a28e500a
--- /dev/null
+++ b/testsuite/tests/rts/flags/all.T
@@ -0,0 +1,44 @@
+#Standard handling of RTS arguments
+test('T12870a',
+ [extra_run_opts('+RTS -G2 -RTS arg1 --RTS +RTS arg2'), extra_files(['T12870.hs'])],
+ multimod_compile_and_run,
+ ['T12870', '-rtsopts -main-is T12870'])
+
+test('T12870b',
+ [extra_run_opts('+RTS -G2 -RTS arg1 --RTS +RTS arg2'), extra_files(['T12870.hs']),
+ exit_code(1), ignore_stderr],
+ multimod_compile_and_run,
+ ['T12870', '-rtsopts=none -main-is T12870'])
+
+test('T12870c',
+ [extra_run_opts('+RTS -G2 -RTS arg1 --RTS +RTS arg2'), extra_files(['T12870.hs']),
+ exit_code(1)],
+ multimod_compile_and_run,
+ ['T12870', '-rtsopts=some -main-is T12870'])
+
+test('T12870d',
+ [extra_run_opts('+RTS -G2 -RTS arg1 --RTS +RTS arg2'), extra_files(['T12870.hs'])],
+ multimod_compile_and_run,
+ ['T12870', '-main-is T12870'])
+
+#RTS options should be passed along to the program
+test('T12870e',
+ [extra_run_opts('+RTS -G2 -RTS arg1 --RTS +RTS arg2'), extra_files(['T12870.hs'])],
+ multimod_compile_and_run,
+ ['T12870', '-rtsopts=ignore -main-is T12870'])
+test('T12870f',
+ [extra_run_opts('+RTS -G2 -RTS arg1 --RTS +RTS arg2'), extra_files(['T12870.hs'])],
+ multimod_compile_and_run,
+ ['T12870', '-rtsopts=ignoreAll -main-is T12870'])
+
+#Check handling of env variables
+test('T12870g',
+ [extra_files(['T12870g.hs']), cmd_prefix('GHCRTS=-G7 '), extra_files(['T12870g.hs'])],
+ multimod_compile_and_run,
+ ['T12870g', '-rtsopts -main-is T12870g -with-rtsopts="-G3"'])
+
+test('T12870h',
+ [extra_files(['T12870g.hs']), cmd_prefix('GHCRTS=-G7 '), extra_files(['T12870g.hs'])],
+ multimod_compile_and_run,
+ ['T12870g', '-rtsopts=ignoreAll -main-is T12870g -with-rtsopts="-G3"'])
+
diff --git a/testsuite/tests/stranal/should_compile/T9208.hs b/testsuite/tests/stranal/should_compile/T9208.hs
index b8ec6df6d1..5243445c96 100644
--- a/testsuite/tests/stranal/should_compile/T9208.hs
+++ b/testsuite/tests/stranal/should_compile/T9208.hs
@@ -25,6 +25,7 @@ import Control.Monad
#if __GLASGOW_HASKELL__ >= 800
import Control.Monad.Fail (MonadFail(fail))
#endif
+import Control.Monad.IO.Class (MonadIO (..))
import Data.Binary
import Data.Binary.Get
@@ -81,7 +82,8 @@ instance MonadFail GHCJSQ where
fail = undefined
#endif
-instance TH.Quasi GHCJSQ where qRunIO m = GHCJSQ $ \s -> fmap (,s) m
+instance MonadIO GHCJSQ where liftIO m = GHCJSQ $ \s -> fmap (,s) m
+instance TH.Quasi GHCJSQ
-- | the Template Haskell server
runTHServer :: IO ()
diff --git a/testsuite/tests/th/T13642.hs b/testsuite/tests/th/T13642.hs
index 35aee30ddb..090b891433 100644
--- a/testsuite/tests/th/T13642.hs
+++ b/testsuite/tests/th/T13642.hs
@@ -5,5 +5,5 @@ import Data.Kind (Type)
import Language.Haskell.TH (stringE, pprint)
foo :: IO ()
-foo = $([d| data Foo :: forall a. a -> Type where MkFoo :: Foo Int |]
- >>= \d -> stringE (pprint d))
+foo = putStrLn $([d| data Foo :: forall a. a -> Type where MkFoo :: Foo Int |]
+ >>= \d -> stringE (pprint d))
diff --git a/testsuite/tests/th/T13642.stderr b/testsuite/tests/th/T13642.stderr
deleted file mode 100644
index a6ff054a26..0000000000
--- a/testsuite/tests/th/T13642.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-
-T13642.hs:8:9: error:
- Exotic form of kind not (yet) handled by Template Haskell
- forall a. a -> Type
diff --git a/testsuite/tests/th/T13837.hs b/testsuite/tests/th/T13837.hs
new file mode 100644
index 0000000000..3d33341e4d
--- /dev/null
+++ b/testsuite/tests/th/T13837.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE TemplateHaskell #-}
+module T13837 where
+
+import Language.Haskell.TH.Lib
+import Language.Haskell.TH.Syntax
+
+test_local_tyfam_expansion :: String
+test_local_tyfam_expansion =
+ $(do fam_name <- newName "Fam"
+ stringE . show =<< qReifyInstances fam_name [])
diff --git a/testsuite/tests/th/T13837.stderr b/testsuite/tests/th/T13837.stderr
new file mode 100644
index 0000000000..53700b5a7a
--- /dev/null
+++ b/testsuite/tests/th/T13837.stderr
@@ -0,0 +1,10 @@
+
+T13837.hs:9:5: error:
+ • The exact Name ‘Fam’ is not in scope
+ Probable cause: you used a unique Template Haskell name (NameU),
+ perhaps via newName, but did not bind it
+ If that's it, then -ddump-splices might be useful
+ • In the argument of reifyInstances: Fam_0
+ In the untyped splice:
+ $(do fam_name <- newName "Fam"
+ stringE . show =<< qReifyInstances fam_name [])
diff --git a/testsuite/tests/th/T13887.hs b/testsuite/tests/th/T13887.hs
new file mode 100644
index 0000000000..8687447d16
--- /dev/null
+++ b/testsuite/tests/th/T13887.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TemplateHaskell #-}
+module Main where
+
+import Data.Proxy
+import GHC.Generics
+import Language.Haskell.TH
+
+main :: IO ()
+main = do
+ putStrLn $([t| Proxy (:*:) |] >>= stringE . pprint)
+ putStrLn $([t| Proxy '(:*:) |] >>= stringE . pprint)
+ putStrLn $([t| Proxy '(:) |] >>= stringE . pprint)
diff --git a/testsuite/tests/th/T13887.stdout b/testsuite/tests/th/T13887.stdout
new file mode 100644
index 0000000000..48845be60a
--- /dev/null
+++ b/testsuite/tests/th/T13887.stdout
@@ -0,0 +1,3 @@
+Data.Proxy.Proxy (GHC.Generics.:*:)
+Data.Proxy.Proxy '(GHC.Generics.:*:)
+Data.Proxy.Proxy '(GHC.Types.:)
diff --git a/testsuite/tests/th/T13968.hs b/testsuite/tests/th/T13968.hs
new file mode 100644
index 0000000000..1e54ef12f3
--- /dev/null
+++ b/testsuite/tests/th/T13968.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE TemplateHaskell #-}
+module T13968 where
+
+import Language.Haskell.TH
+
+$(pure [ValD (VarP 'succ) (NormalB (ConE 'True)) []])
diff --git a/testsuite/tests/th/T13968.stderr b/testsuite/tests/th/T13968.stderr
new file mode 100644
index 0000000000..2850dae0c5
--- /dev/null
+++ b/testsuite/tests/th/T13968.stderr
@@ -0,0 +1,3 @@
+
+T13968.hs:6:3: error:
+ Cannot redefine a Name retrieved by a Template Haskell quote: succ
diff --git a/testsuite/tests/th/T3177a.stderr b/testsuite/tests/th/T3177a.stderr
index e2e8cadbdc..d68be6d1fc 100644
--- a/testsuite/tests/th/T3177a.stderr
+++ b/testsuite/tests/th/T3177a.stderr
@@ -1,10 +1,8 @@
T3177a.hs:8:8: error:
- • Expecting one fewer arguments to ‘Int’
- Expected kind ‘* -> *’, but ‘Int’ has kind ‘*’
+ • Expected kind ‘* -> *’, but ‘Int’ has kind ‘*’
• In the type signature: f :: (Int Int)
T3177a.hs:11:6: error:
- • Expecting one fewer arguments to ‘Int’
- Expected kind ‘* -> *’, but ‘Int’ has kind ‘*’
+ • Expected kind ‘* -> *’, but ‘Int’ has kind ‘*’
• In the type signature: g :: Int Int
diff --git a/testsuite/tests/th/T5358.stderr b/testsuite/tests/th/T5358.stderr
index 4bfc53a78e..b698bc1004 100644
--- a/testsuite/tests/th/T5358.stderr
+++ b/testsuite/tests/th/T5358.stderr
@@ -1,4 +1,24 @@
+T5358.hs:10:13: error:
+ • Couldn't match expected type ‘t -> a0’ with actual type ‘Int’
+ • The function ‘T5358.t1’ is applied to one argument,
+ but its type ‘Int’ has none
+ In the first argument of ‘(==)’, namely ‘T5358.t1 x’
+ In the expression: T5358.t1 x == T5358.t2 x
+ • Relevant bindings include
+ x :: t (bound at T5358.hs:10:9)
+ T5358.prop_x1 :: t -> Bool (bound at T5358.hs:10:1)
+
+T5358.hs:10:21: error:
+ • Couldn't match expected type ‘t -> a0’ with actual type ‘Int’
+ • The function ‘T5358.t2’ is applied to one argument,
+ but its type ‘Int’ has none
+ In the second argument of ‘(==)’, namely ‘T5358.t2 x’
+ In the expression: T5358.t1 x == T5358.t2 x
+ • Relevant bindings include
+ x :: t (bound at T5358.hs:10:9)
+ T5358.prop_x1 :: t -> Bool (bound at T5358.hs:10:1)
+
T5358.hs:14:12: error:
• Exception when trying to run compile-time code:
runTest called error: forall (t_0 :: *) . t_0 -> GHC.Types.Bool
diff --git a/testsuite/tests/th/T7276.stderr b/testsuite/tests/th/T7276.stderr
index 93c9a0c835..4fa2a3c4c9 100644
--- a/testsuite/tests/th/T7276.stderr
+++ b/testsuite/tests/th/T7276.stderr
@@ -2,7 +2,7 @@
T7276.hs:6:8: error:
• Couldn't match type ‘[Language.Haskell.TH.Syntax.Dec]’
with ‘Language.Haskell.TH.Syntax.Exp’
- Expected type: Language.Haskell.TH.Lib.ExpQ
- Actual type: Language.Haskell.TH.Lib.DecsQ
+ Expected type: Language.Haskell.TH.Lib.Internal.ExpQ
+ Actual type: Language.Haskell.TH.Lib.Internal.DecsQ
• In the expression: [d| y = 3 |]
In the untyped splice: $([d| y = 3 |])
diff --git a/testsuite/tests/th/TH_PromotedList.stderr b/testsuite/tests/th/TH_PromotedList.stderr
index 8a6422f6ec..fde888ff88 100644
--- a/testsuite/tests/th/TH_PromotedList.stderr
+++ b/testsuite/tests/th/TH_PromotedList.stderr
@@ -1,3 +1,3 @@
-TH_PromotedList.hs:11:3: Warning:
- (':) GHC.Types.Int ((':) GHC.Types.Bool '[])
+TH_PromotedList.hs:11:3: warning:
+ '(:) GHC.Types.Int ('(:) GHC.Types.Bool '[])
diff --git a/testsuite/tests/th/TH_RichKinds2.stderr b/testsuite/tests/th/TH_RichKinds2.stderr
index 11829296e0..6b0662218a 100644
--- a/testsuite/tests/th/TH_RichKinds2.stderr
+++ b/testsuite/tests/th/TH_RichKinds2.stderr
@@ -5,5 +5,6 @@ TH_RichKinds2.hs:24:4: warning:
SJust_4 :: (s_5 a_6) -> SMaybe_0 s_5 ('GHC.Base.Just a_6)
type instance TH_RichKinds2.Map f_7 '[] = '[]
type instance TH_RichKinds2.Map f_8
- ('GHC.Types.: h_9 t_10) = 'GHC.Types.: (f_8 h_9)
- (TH_RichKinds2.Map f_8 t_10)
+ ('(GHC.Types.:) h_9 t_10) = '(GHC.Types.:) (f_8 h_9)
+ (TH_RichKinds2.Map f_8
+ t_10)
diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T
index f89be6e0bb..29a6334f6b 100644
--- a/testsuite/tests/th/all.T
+++ b/testsuite/tests/th/all.T
@@ -386,7 +386,10 @@ test('T13473', normal, multimod_compile_and_run,
['T13473.hs', '-v0 ' + config.ghc_th_way_flags])
test('T13587', expect_broken(13587), compile_and_run, ['-v0'])
test('T13618', normal, compile_and_run, ['-v0'])
-test('T13642', normal, compile_fail, ['-v0'])
+test('T13642', normal, compile, ['-v0'])
test('T13781', normal, compile, ['-v0'])
test('T13782', normal, compile, [''])
+test('T13837', normal, compile_fail, ['-v0 -dsuppress-uniques'])
test('T13856', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques'])
+test('T13887', normal, compile_and_run, ['-v0'])
+test('T13968', normal, compile_fail, ['-v0'])
diff --git a/testsuite/tests/typecheck/should_compile/T13594.stderr b/testsuite/tests/typecheck/should_compile/T13594.stderr
new file mode 100644
index 0000000000..57810cc1e6
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T13594.stderr
@@ -0,0 +1,3 @@
+
+T13594.hs:8:1: error:
+ Top-level strict bindings aren't allowed: !x = (1, 2)
diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T
index 2ce4e91fa8..c18c73b9bc 100644
--- a/testsuite/tests/typecheck/should_compile/all.T
+++ b/testsuite/tests/typecheck/should_compile/all.T
@@ -556,7 +556,7 @@ test('T13474', normal, compile, [''])
test('T13524', normal, compile, [''])
test('T13509', normal, compile, [''])
test('T13526', normal, compile, [''])
-test('T13594', normal, compile, [''])
+test('T13594', normal, compile_fail, [''])
test('T13603', normal, compile, [''])
test('T13333', normal, compile, [''])
test('T13585', [extra_files(['T13585.hs', 'T13585a.hs', 'T13585b.hs'])], run_command, ['$MAKE -s --no-print-directory T13585'])
diff --git a/testsuite/tests/typecheck/should_fail/T11356.stderr b/testsuite/tests/typecheck/should_fail/T11356.stderr
index aa1db97c62..e0224022a2 100644
--- a/testsuite/tests/typecheck/should_fail/T11356.stderr
+++ b/testsuite/tests/typecheck/should_fail/T11356.stderr
@@ -1,5 +1,4 @@
T11356.hs:3:7: error:
- • Expecting one fewer arguments to ‘T p’
- Expected kind ‘k0 -> Constraint’, but ‘T p’ has kind ‘Constraint’
+ • Expected kind ‘k0 -> Constraint’, but ‘T p’ has kind ‘Constraint’
• In the class declaration for ‘C’
diff --git a/testsuite/tests/typecheck/should_fail/T11672.hs b/testsuite/tests/typecheck/should_fail/T11672.hs
new file mode 100644
index 0000000000..8c5e2fba6e
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T11672.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
+module BadError where
+
+import GHC.TypeLits
+import Data.Proxy
+
+f :: Proxy (a :: Symbol) -> Int
+f _ = f (Proxy :: Proxy (Int -> Bool))
diff --git a/testsuite/tests/typecheck/should_fail/T11672.stderr b/testsuite/tests/typecheck/should_fail/T11672.stderr
new file mode 100644
index 0000000000..16eb31042f
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T11672.stderr
@@ -0,0 +1,12 @@
+
+T11672.hs:9:10: error:
+ • Couldn't match kind ‘*’ with ‘Symbol’
+ When matching types
+ a0 :: Symbol
+ Int -> Bool :: *
+ Expected type: Proxy a0
+ Actual type: Proxy (Int -> Bool)
+ • In the first argument of ‘f’, namely
+ ‘(Proxy :: Proxy (Int -> Bool))’
+ In the expression: f (Proxy :: Proxy (Int -> Bool))
+ In an equation for ‘f’: f _ = f (Proxy :: Proxy (Int -> Bool))
diff --git a/testsuite/tests/typecheck/should_fail/T11963.hs b/testsuite/tests/typecheck/should_fail/T11963.hs
new file mode 100644
index 0000000000..c4f78aee29
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T11963.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE GADTs, PolyKinds, RankNTypes #-}
+
+module T11963 where
+
+-- this module should be rejected without TypeInType
+
+import Data.Proxy
+
+-- see code in RnTypes.extract_hs_tv_bndrs which checks for these bad cases
+
+ -- bndr_kvs vs body_tvs
+data Typ k t where
+ Typ :: (forall (a :: k -> *). a t -> a t) -> Typ k t
+
+ -- bndr_kvs vs acc_tvs
+foo :: (forall (t :: k). Proxy t) -> Proxy k
+foo _ = undefined
+
+ -- locals vs body_kvs
+bar :: forall k. forall (t :: k). Proxy t
+bar = undefined
+
+ -- body_kvs vs acc_tvs
+quux :: (forall t. Proxy (t :: k)) -> Proxy k
+quux _ = undefined
+
+ -- body_tvs vs acc_kvs
+blargh :: (forall a. a -> Proxy k) -> Proxy (t :: k)
+blargh _ = undefined
diff --git a/testsuite/tests/typecheck/should_fail/T11963.stderr b/testsuite/tests/typecheck/should_fail/T11963.stderr
new file mode 100644
index 0000000000..74c3ab0ee1
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T11963.stderr
@@ -0,0 +1,20 @@
+
+T11963.hs:13:26: error:
+ Variable ‘k’ used as both a kind and a type
+ Did you intend to use TypeInType?
+
+T11963.hs:16:22: error:
+ Variable ‘k’ used as both a kind and a type
+ Did you intend to use TypeInType?
+
+T11963.hs:20:15: error:
+ Variable ‘k’ used as both a kind and a type
+ Did you intend to use TypeInType?
+
+T11963.hs:24:32: error:
+ Variable ‘k’ used as both a kind and a type
+ Did you intend to use TypeInType?
+
+T11963.hs:28:33: error:
+ Variable ‘k’ used as both a kind and a type
+ Did you intend to use TypeInType?
diff --git a/testsuite/tests/typecheck/should_fail/T12373.hs b/testsuite/tests/typecheck/should_fail/T12373.hs
new file mode 100644
index 0000000000..3f23779b82
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T12373.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE MagicHash, ScopedTypeVariables, UnboxedTuples #-}
+
+module T12373 where
+
+import GHC.MVar
+import GHC.Prim
+import GHC.Types
+
+main :: IO ()
+main = IO (\rw -> newMVar# rw) >> return ()
diff --git a/testsuite/tests/typecheck/should_fail/T12373.stderr b/testsuite/tests/typecheck/should_fail/T12373.stderr
new file mode 100644
index 0000000000..d3a4bb5e65
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T12373.stderr
@@ -0,0 +1,11 @@
+
+T12373.hs:10:19: error:
+ • Couldn't match a lifted type with an unlifted type
+ When matching types
+ a1 :: *
+ MVar# RealWorld a0 :: TYPE 'UnliftedRep
+ Expected type: (# State# RealWorld, a1 #)
+ Actual type: (# State# RealWorld, MVar# RealWorld a0 #)
+ • In the expression: newMVar# rw
+ In the first argument of ‘IO’, namely ‘(\ rw -> newMVar# rw)’
+ In the first argument of ‘(>>)’, namely ‘IO (\ rw -> newMVar# rw)’
diff --git a/testsuite/tests/typecheck/should_fail/T12785b.stderr b/testsuite/tests/typecheck/should_fail/T12785b.stderr
index 1b1d1bc569..b8e572d6e2 100644
--- a/testsuite/tests/typecheck/should_fail/T12785b.stderr
+++ b/testsuite/tests/typecheck/should_fail/T12785b.stderr
@@ -8,6 +8,12 @@ T12785b.hs:29:63: error:
a -> HTree n (HTree ('S n) a) -> HTree ('S n) a,
in an equation for ‘nest’
at T12785b.hs:29:7-51
+ ‘s’ is a rigid type variable bound by
+ a pattern with constructor:
+ Hide :: forall a (n :: Peano) (f :: a -> *) (s :: HTree n a).
+ STree n a f s -> Hidden n f,
+ in an equation for ‘nest’
+ at T12785b.hs:29:7-12
• In the second argument of ‘($)’, namely ‘a `SBranchX` tr’
In the expression: Hide $ a `SBranchX` tr
In an equation for ‘nest’:
diff --git a/testsuite/tests/typecheck/should_fail/T13530.hs b/testsuite/tests/typecheck/should_fail/T13530.hs
new file mode 100644
index 0000000000..9f95e497f2
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T13530.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+
+module T13530 where
+
+import GHC.Exts
+
+g :: Int -> (# Int#, a #)
+g (I# y) = (# y, undefined #)
+
+f :: Int -> (# Int#, Int# #)
+f x = g x
diff --git a/testsuite/tests/typecheck/should_fail/T13530.stderr b/testsuite/tests/typecheck/should_fail/T13530.stderr
new file mode 100644
index 0000000000..139c1b0f34
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T13530.stderr
@@ -0,0 +1,10 @@
+
+T13530.hs:11:7: error:
+ • Couldn't match a lifted type with an unlifted type
+ When matching types
+ a0 :: *
+ Int# :: TYPE 'IntRep
+ Expected type: (# Int#, Int# #)
+ Actual type: (# Int#, a0 #)
+ • In the expression: g x
+ In an equation for ‘f’: f x = g x
diff --git a/testsuite/tests/typecheck/should_fail/T13610.hs b/testsuite/tests/typecheck/should_fail/T13610.hs
new file mode 100644
index 0000000000..371c3388e9
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T13610.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE MagicHash #-}
+
+module T13610 where
+
+import GHC.Prim
+import GHC.Types
+
+main = do
+ let primDouble = 0.42## :: Double#
+ let double = 0.42 :: Double
+ IO (\s -> mkWeakNoFinalizer# double () s)
diff --git a/testsuite/tests/typecheck/should_fail/T13610.stderr b/testsuite/tests/typecheck/should_fail/T13610.stderr
new file mode 100644
index 0000000000..0755ce9371
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T13610.stderr
@@ -0,0 +1,14 @@
+
+T13610.hs:11:15: error:
+ • Couldn't match a lifted type with an unlifted type
+ When matching types
+ a :: *
+ Weak# () :: TYPE 'UnliftedRep
+ Expected type: (# State# RealWorld, a #)
+ Actual type: (# State# RealWorld, Weak# () #)
+ • In the expression: mkWeakNoFinalizer# double () s
+ In the first argument of ‘IO’, namely
+ ‘(\ s -> mkWeakNoFinalizer# double () s)’
+ In a stmt of a 'do' block:
+ IO (\ s -> mkWeakNoFinalizer# double () s)
+ • Relevant bindings include main :: IO a (bound at T13610.hs:8:1)
diff --git a/testsuite/tests/typecheck/should_fail/T13819.hs b/testsuite/tests/typecheck/should_fail/T13819.hs
new file mode 100644
index 0000000000..5244ddc840
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T13819.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE DeriveFunctor, TypeApplications #-}
+
+module T13819 where
+
+import Data.Coerce
+import Control.Applicative
+
+newtype A a = A (IO a)
+ deriving Functor
+
+instance Applicative A where
+ pure = pure @(_ -> WrappedMonad A _) @(_ -> A _) pure
+
+instance Monad A where
diff --git a/testsuite/tests/typecheck/should_fail/T13819.stderr b/testsuite/tests/typecheck/should_fail/T13819.stderr
new file mode 100644
index 0000000000..ab818f399b
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T13819.stderr
@@ -0,0 +1,18 @@
+
+T13819.hs:12:10: error:
+ • Couldn't match type ‘w0 -> A w0’ with ‘A a’
+ Expected type: a -> A a
+ Actual type: (w1 -> WrappedMonad A w2) (w0 -> A w0)
+ • In the expression: pure @(_ -> WrappedMonad A _) @(_ -> A _) pure
+ In an equation for ‘pure’:
+ pure = pure @(_ -> WrappedMonad A _) @(_ -> A _) pure
+ In the instance declaration for ‘Applicative A’
+ • Relevant bindings include
+ pure :: a -> A a (bound at T13819.hs:12:3)
+
+T13819.hs:12:17: error:
+ • Expected kind ‘* -> *’, but ‘_ -> WrappedMonad A _’ has kind ‘*’
+ • In the type ‘(_ -> WrappedMonad A _)’
+ In the expression: pure @(_ -> WrappedMonad A _) @(_ -> A _) pure
+ In an equation for ‘pure’:
+ pure = pure @(_ -> WrappedMonad A _) @(_ -> A _) pure
diff --git a/testsuite/tests/typecheck/should_fail/T14000.hs b/testsuite/tests/typecheck/should_fail/T14000.hs
new file mode 100644
index 0000000000..854a78b6ad
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T14000.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE TypeFamilies #-}
+module T14000 where
+
+class C a where
+ type T a
+ c :: a -> T a
+
+foo = c noSuchThing -- noSuchThing is not in scope
diff --git a/testsuite/tests/typecheck/should_fail/T14000.stderr b/testsuite/tests/typecheck/should_fail/T14000.stderr
new file mode 100644
index 0000000000..8b51e37641
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T14000.stderr
@@ -0,0 +1,2 @@
+
+T14000.hs:8:9: error: Variable not in scope: noSuchThing
diff --git a/testsuite/tests/typecheck/should_fail/T14055.hs b/testsuite/tests/typecheck/should_fail/T14055.hs
new file mode 100644
index 0000000000..996c33be1c
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T14055.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE DataKinds, TypeFamilies #-}
+
+newtype X = RollX (() -> X)
+
+type family F t :: X where
+ F t = RollX (t -> ())
diff --git a/testsuite/tests/typecheck/should_fail/T14055.stderr b/testsuite/tests/typecheck/should_fail/T14055.stderr
new file mode 100644
index 0000000000..19e4d59112
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T14055.stderr
@@ -0,0 +1,6 @@
+
+T14055.hs:6:18: error:
+ • Expected kind ‘() -> X’, but ‘t -> ()’ has kind ‘*’
+ • In the first argument of ‘RollX’, namely ‘(t -> ())’
+ In the type ‘RollX (t -> ())’
+ In the type family declaration for ‘F’
diff --git a/testsuite/tests/typecheck/should_fail/T2994.stderr b/testsuite/tests/typecheck/should_fail/T2994.stderr
index 4777e486e6..7f20acf5aa 100644
--- a/testsuite/tests/typecheck/should_fail/T2994.stderr
+++ b/testsuite/tests/typecheck/should_fail/T2994.stderr
@@ -18,7 +18,6 @@ T2994.hs:13:23: error:
In the instance declaration for ‘MonadReader (Reader' r)’
T2994.hs:15:10: error:
- • Expecting one fewer arguments to ‘MonadReader r r’
- Expected kind ‘(* -> *) -> Constraint’,
+ • Expected kind ‘(* -> *) -> Constraint’,
but ‘MonadReader r r’ has kind ‘Constraint’
• In the instance declaration for ‘MonadReader r r (Reader' r)’
diff --git a/testsuite/tests/typecheck/should_fail/T3540.stderr b/testsuite/tests/typecheck/should_fail/T3540.stderr
index 1723e86bbe..0fdb88b313 100644
--- a/testsuite/tests/typecheck/should_fail/T3540.stderr
+++ b/testsuite/tests/typecheck/should_fail/T3540.stderr
@@ -12,7 +12,7 @@ T3540.hs:10:13: error:
• In the type signature: thing2 :: (a ~ Int) -> Int
T3540.hs:13:12: error:
- • Expected a type, but ‘?dude::Int’ has kind ‘Constraint’
+ • Expected a type, but ‘?dude :: Int’ has kind ‘Constraint’
• In the type signature: thing3 :: (?dude :: Int) -> Int
T3540.hs:16:11: error:
diff --git a/testsuite/tests/typecheck/should_fail/T4875.stderr b/testsuite/tests/typecheck/should_fail/T4875.stderr
index 782b0969d5..48808e319c 100644
--- a/testsuite/tests/typecheck/should_fail/T4875.stderr
+++ b/testsuite/tests/typecheck/should_fail/T4875.stderr
@@ -1,7 +1,5 @@
T4875.hs:27:24: error:
- • Expecting one fewer arguments to ‘r’
- Expected kind ‘* -> *’, but ‘r’ has kind ‘*’
- • In the type signature:
- multiplicities :: r c -> [c]
+ • Expected kind ‘* -> *’, but ‘r’ has kind ‘*’
+ • In the type signature: multiplicities :: r c -> [c]
In the class declaration for ‘Morphic’
diff --git a/testsuite/tests/typecheck/should_fail/T5691.stderr b/testsuite/tests/typecheck/should_fail/T5691.stderr
index ad5c7e452f..9d4e587166 100644
--- a/testsuite/tests/typecheck/should_fail/T5691.stderr
+++ b/testsuite/tests/typecheck/should_fail/T5691.stderr
@@ -1,12 +1,12 @@
-T5691.hs:14:9: error:
+T5691.hs:15:24: error:
• Couldn't match type ‘p’ with ‘PrintRuleInterp’
Expected type: PrintRuleInterp a
Actual type: p a
- • When checking that the pattern signature: p a
- fits the type of its context: PrintRuleInterp a
- In the pattern: f :: p a
- In an equation for ‘test’: test (f :: p a) = MkPRI $ printRule_ f
+ • In the first argument of ‘printRule_’, namely ‘f’
+ In the second argument of ‘($)’, namely ‘printRule_ f’
+ In the expression: MkPRI $ printRule_ f
+ • Relevant bindings include f :: p a (bound at T5691.hs:14:9)
T5691.hs:24:10: error:
• No instance for (Alternative RecDecParser)
diff --git a/testsuite/tests/typecheck/should_fail/T7368.stderr b/testsuite/tests/typecheck/should_fail/T7368.stderr
index f187aee61c..660ef98f26 100644
--- a/testsuite/tests/typecheck/should_fail/T7368.stderr
+++ b/testsuite/tests/typecheck/should_fail/T7368.stderr
@@ -1,7 +1,11 @@
T7368.hs:3:10: error:
• Couldn't match kind ‘*’ with ‘* -> *’
- When matching the kind of ‘Maybe’
+ When matching types
+ b0 :: *
+ Maybe :: * -> *
+ Expected type: a0 -> b0
+ Actual type: c0 Maybe
• In the first argument of ‘b’, namely ‘(l Nothing)’
In the expression: b (l Nothing)
In an equation for ‘f’: f = b (l Nothing)
diff --git a/testsuite/tests/typecheck/should_fail/T7368a.stderr b/testsuite/tests/typecheck/should_fail/T7368a.stderr
index e55aab0e62..16c8326afe 100644
--- a/testsuite/tests/typecheck/should_fail/T7368a.stderr
+++ b/testsuite/tests/typecheck/should_fail/T7368a.stderr
@@ -5,7 +5,7 @@ T7368a.hs:8:6: error:
f :: * -> *
Bad :: (* -> *) -> *
Expected type: f (Bad f)
- Actual type: Bad (Bad f)
+ Actual type: Bad w0
• In the pattern: Bad x
In an equation for ‘fun’: fun (Bad x) = True
• Relevant bindings include
diff --git a/testsuite/tests/typecheck/should_fail/T7453.stderr b/testsuite/tests/typecheck/should_fail/T7453.stderr
index 518d6fad05..77348c357a 100644
--- a/testsuite/tests/typecheck/should_fail/T7453.stderr
+++ b/testsuite/tests/typecheck/should_fail/T7453.stderr
@@ -1,56 +1,32 @@
-T7453.hs:9:15: error:
- • Couldn't match type ‘p’ with ‘t’
+T7453.hs:10:30: error:
+ • Couldn't match expected type ‘t’ with actual type ‘p’
because type variable ‘t’ would escape its scope
This (rigid, skolem) type variable is bound by
the type signature for:
z :: forall t. Id t
at T7453.hs:8:11-19
- Expected type: Id t
- Actual type: Id p
- • In the expression: aux
- In an equation for ‘z’:
- z = aux
- where
- aux = Id v
- In an equation for ‘cast1’:
- cast1 v
- = runId z
- where
- z :: Id t
- z = aux
- where
- aux = Id v
+ • In the first argument of ‘Id’, namely ‘v’
+ In the expression: Id v
+ In an equation for ‘aux’: aux = Id v
• Relevant bindings include
- aux :: Id p (bound at T7453.hs:10:21)
+ aux :: Id t (bound at T7453.hs:10:21)
z :: Id t (bound at T7453.hs:9:11)
v :: p (bound at T7453.hs:7:7)
cast1 :: p -> a (bound at T7453.hs:7:1)
-T7453.hs:15:15: error:
- • Couldn't match type ‘p’ with ‘t1’
+T7453.hs:16:33: error:
+ • Couldn't match expected type ‘t1’ with actual type ‘p’
because type variable ‘t1’ would escape its scope
This (rigid, skolem) type variable is bound by
the type signature for:
z :: forall t1. () -> t1
at T7453.hs:14:11-22
- Expected type: () -> t1
- Actual type: () -> p
- • In the expression: aux
- In an equation for ‘z’:
- z = aux
- where
- aux = const v
- In an equation for ‘cast2’:
- cast2 v
- = z ()
- where
- z :: () -> t
- z = aux
- where
- aux = const v
+ • In the first argument of ‘const’, namely ‘v’
+ In the expression: const v
+ In an equation for ‘aux’: aux = const v
• Relevant bindings include
- aux :: forall b. b -> p (bound at T7453.hs:16:21)
+ aux :: b -> t1 (bound at T7453.hs:16:21)
z :: () -> t1 (bound at T7453.hs:15:11)
v :: p (bound at T7453.hs:13:7)
cast2 :: p -> t (bound at T7453.hs:13:1)
diff --git a/testsuite/tests/typecheck/should_fail/T7609.stderr b/testsuite/tests/typecheck/should_fail/T7609.stderr
index 24339311b8..32bc980fe9 100644
--- a/testsuite/tests/typecheck/should_fail/T7609.stderr
+++ b/testsuite/tests/typecheck/should_fail/T7609.stderr
@@ -2,16 +2,13 @@
T7609.hs:7:16: error:
• Expecting one more argument to ‘Maybe’
Expected a type, but ‘Maybe’ has kind ‘* -> *’
- • In the type signature:
- f :: (a `X` a, Maybe)
+ • In the type signature: f :: (a `X` a, Maybe)
T7609.hs:10:7: error:
- • Expected a constraint, but ‘X a a’ has kind ‘*’
- • In the type signature:
- g :: (a `X` a) => Maybe
+ • Expected a constraint, but ‘a `X` a’ has kind ‘*’
+ • In the type signature: g :: (a `X` a) => Maybe
T7609.hs:10:19: error:
• Expecting one more argument to ‘Maybe’
Expected a type, but ‘Maybe’ has kind ‘* -> *’
- • In the type signature:
- g :: (a `X` a) => Maybe
+ • In the type signature: g :: (a `X` a) => Maybe
diff --git a/testsuite/tests/typecheck/should_fail/T7696.stderr b/testsuite/tests/typecheck/should_fail/T7696.stderr
index eef19a5cfc..41f2296797 100644
--- a/testsuite/tests/typecheck/should_fail/T7696.stderr
+++ b/testsuite/tests/typecheck/should_fail/T7696.stderr
@@ -1,7 +1,7 @@
T7696.hs:7:6: error:
- • Couldn't match type ‘() a0’ with ‘()’
+ • Couldn't match type ‘m0 a0’ with ‘()’
Expected type: ((), w ())
- Actual type: (() a0, w ())
+ Actual type: (m0 a0, t0 m0)
• In the expression: f1
In an equation for ‘f2’: f2 = f1
diff --git a/testsuite/tests/typecheck/should_fail/T7778.stderr b/testsuite/tests/typecheck/should_fail/T7778.stderr
index 2db22e95ff..a0f10fcd92 100644
--- a/testsuite/tests/typecheck/should_fail/T7778.stderr
+++ b/testsuite/tests/typecheck/should_fail/T7778.stderr
@@ -1,12 +1,10 @@
T7778.hs:3:7: error:
- • Expecting one fewer arguments to ‘Num Int => Num’
- Expected kind ‘* -> Constraint’, but ‘Num Int => Num’ has kind ‘*’
- • In the type signature:
- v :: ((Num Int => Num) ()) => ()
+ • Expected kind ‘* -> Constraint’,
+ but ‘Num Int => Num’ has kind ‘*’
+ • In the type signature: v :: ((Num Int => Num) ()) => ()
T7778.hs:3:19: error:
• Expecting one more argument to ‘Num’
Expected a type, but ‘Num’ has kind ‘* -> Constraint’
- • In the type signature:
- v :: ((Num Int => Num) ()) => ()
+ • In the type signature: v :: ((Num Int => Num) ()) => ()
diff --git a/testsuite/tests/typecheck/should_fail/T8142.stderr b/testsuite/tests/typecheck/should_fail/T8142.stderr
index aec8b3b55c..25d60d1aff 100644
--- a/testsuite/tests/typecheck/should_fail/T8142.stderr
+++ b/testsuite/tests/typecheck/should_fail/T8142.stderr
@@ -1,16 +1,24 @@
-T8142.hs:6:18: error:
- • Couldn't match type ‘Nu g0’ with ‘Nu g’
- Expected type: Nu ((,) a) -> Nu g
+T8142.hs:6:10: error:
+ • Couldn't match type ‘Nu ((,) a0)’ with ‘c -> f c’
+ Expected type: (c -> f c) -> c -> f c
Actual type: Nu ((,) a0) -> Nu g0
- NB: ‘Nu’ is a type function, and may not be injective
- The type variable ‘g0’ is ambiguous
- • In the ambiguity check for the inferred type for ‘h’
- To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
- When checking the inferred type
- h :: forall a (g :: * -> *). Nu ((,) a) -> Nu g
+ The type variable ‘a0’ is ambiguous
+ • In the expression: h
In an equation for ‘tracer’:
tracer
= h
where
h = (\ (_, b) -> ((outI . fmap h) b)) . out
+ • Relevant bindings include
+ tracer :: (c -> f c) -> c -> f c (bound at T8142.hs:6:1)
+
+T8142.hs:6:57: error:
+ • Couldn't match type ‘Nu ((,) a)’ with ‘g (Nu ((,) a))’
+ Expected type: Nu ((,) a) -> (a, g (Nu ((,) a)))
+ Actual type: Nu ((,) a) -> (a, Nu ((,) a))
+ • In the second argument of ‘(.)’, namely ‘out’
+ In the expression: (\ (_, b) -> ((outI . fmap h) b)) . out
+ In an equation for ‘h’: h = (\ (_, b) -> ((outI . fmap h) b)) . out
+ • Relevant bindings include
+ h :: Nu ((,) a) -> Nu g (bound at T8142.hs:6:18)
diff --git a/testsuite/tests/typecheck/should_fail/T8262.stderr b/testsuite/tests/typecheck/should_fail/T8262.stderr
index d52ee31a31..fb0d17aef5 100644
--- a/testsuite/tests/typecheck/should_fail/T8262.stderr
+++ b/testsuite/tests/typecheck/should_fail/T8262.stderr
@@ -1,7 +1,11 @@
T8262.hs:5:15: error:
• Couldn't match a lifted type with an unlifted type
- When matching the kind of ‘GHC.Prim.Int#’
+ When matching types
+ a :: *
+ GHC.Prim.Int# :: TYPE 'GHC.Types.IntRep
• In the first argument of ‘Just’, namely ‘(1#)’
In the expression: Just (1#)
In an equation for ‘foo’: foo x = Just (1#)
+ • Relevant bindings include
+ foo :: p -> Maybe a (bound at T8262.hs:5:1)
diff --git a/testsuite/tests/typecheck/should_fail/T8603.hs b/testsuite/tests/typecheck/should_fail/T8603.hs
index 90c1db3ad6..d17f246209 100644
--- a/testsuite/tests/typecheck/should_fail/T8603.hs
+++ b/testsuite/tests/typecheck/should_fail/T8603.hs
@@ -10,6 +10,10 @@ newtype RV a = RV { getPDF :: [(Rational,a)] } deriving (Show, Eq)
instance Functor RV where
fmap f = RV . map (\(x,y) -> (x, f y)) . getPDF
+instance Applicative RV where
+ pure = return
+ (<*>) = ap
+
instance Monad RV where
return x = RV [(1,x)]
rv >>= f = RV $
@@ -29,4 +33,4 @@ testRVState1
= do prize <- lift uniform [1,2,3]
return False
--- lift :: (MonadTrans t, Monad m) => m a -> t m a \ No newline at end of file
+-- lift :: (MonadTrans t, Monad m) => m a -> t m a
diff --git a/testsuite/tests/typecheck/should_fail/T8603.stderr b/testsuite/tests/typecheck/should_fail/T8603.stderr
index d87bd635c4..2ee5ad4634 100644
--- a/testsuite/tests/typecheck/should_fail/T8603.stderr
+++ b/testsuite/tests/typecheck/should_fail/T8603.stderr
@@ -1,19 +1,15 @@
-T8603.hs:13:10: error:
- • No instance for (Applicative RV)
- arising from the superclasses of an instance declaration
- • In the instance declaration for ‘Monad RV’
-
-T8603.hs:29:17: error:
- • Couldn't match type ‘RV a1’ with ‘StateT s RV a0’
+T8603.hs:33:17: error:
+ • Couldn't match kind ‘* -> *’ with ‘*’
+ When matching types
+ t0 :: (* -> *) -> * -> *
+ (->) :: * -> * -> *
Expected type: [Integer] -> StateT s RV a0
- Actual type: (->) ((->) [a1]) (RV a1)
+ Actual type: t0 ((->) [a1]) (RV a1)
• The function ‘lift’ is applied to two arguments,
- but its type ‘([a1] -> RV a1) -> (->) ((->) [a1]) (RV a1)’
+ but its type ‘([a1] -> RV a1) -> t0 ((->) [a1]) (RV a1)’
has only one
In a stmt of a 'do' block: prize <- lift uniform [1, 2, 3]
In the expression:
do prize <- lift uniform [1, 2, ....]
return False
- • Relevant bindings include
- testRVState1 :: RVState s Bool (bound at T8603.hs:28:1)
diff --git a/testsuite/tests/typecheck/should_fail/all.T b/testsuite/tests/typecheck/should_fail/all.T
index 254e04b55d..d865c76718 100644
--- a/testsuite/tests/typecheck/should_fail/all.T
+++ b/testsuite/tests/typecheck/should_fail/all.T
@@ -446,3 +446,11 @@ test('T13677', normal, compile_fail, [''])
test('T13821A', expect_broken(13821), run_command, ['$MAKE -s --no-print-directory T13821A'])
test('T13821B', expect_broken(13821), backpack_typecheck_fail, [''])
test('T13983', normal, compile_fail, [''])
+test('T13530', normal, compile_fail, [''])
+test('T12373', normal, compile_fail, [''])
+test('T13610', normal, compile_fail, [''])
+test('T11672', normal, compile_fail, [''])
+test('T13819', normal, compile_fail, [''])
+test('T11963', normal, compile_fail, [''])
+test('T14000', normal, compile_fail, [''])
+test('T14055', normal, compile_fail, [''])
diff --git a/testsuite/tests/typecheck/should_fail/tcfail070.stderr b/testsuite/tests/typecheck/should_fail/tcfail070.stderr
index 0219626375..3f7bc90d8a 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail070.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail070.stderr
@@ -1,6 +1,5 @@
tcfail070.hs:15:15: error:
- • Expecting one fewer arguments to ‘[Int]’
- Expected kind ‘* -> k0’, but ‘[Int]’ has kind ‘*’
+ • Expected kind ‘* -> k0’, but ‘[Int]’ has kind ‘*’
• In the type ‘([Int] Bool)’
In the type declaration for ‘State’
diff --git a/testsuite/tests/typecheck/should_fail/tcfail078.stderr b/testsuite/tests/typecheck/should_fail/tcfail078.stderr
index 8a94f7c4e4..014d589bf6 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail078.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail078.stderr
@@ -1,6 +1,4 @@
tcfail078.hs:5:6: error:
- • Expecting one fewer arguments to ‘Integer’
- Expected kind ‘* -> Constraint’, but ‘Integer’ has kind ‘*’
- • In the type signature:
- f :: Integer i => i
+ • Expected kind ‘* -> Constraint’, but ‘Integer’ has kind ‘*’
+ • In the type signature: f :: Integer i => i
diff --git a/testsuite/tests/typecheck/should_fail/tcfail090.stderr b/testsuite/tests/typecheck/should_fail/tcfail090.stderr
index 662d7da804..efb81e8ee6 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail090.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail090.stderr
@@ -1,6 +1,8 @@
tcfail090.hs:11:9: error:
• Couldn't match a lifted type with an unlifted type
- When matching the kind of ‘ByteArray#’
+ When matching types
+ a0 :: *
+ ByteArray# :: TYPE 'UnliftedRep
• In the expression: my_undefined
In an equation for ‘die’: die _ = my_undefined
diff --git a/testsuite/tests/typecheck/should_fail/tcfail113.stderr b/testsuite/tests/typecheck/should_fail/tcfail113.stderr
index 410ce3daac..fbdffa5ab9 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail113.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail113.stderr
@@ -2,17 +2,13 @@
tcfail113.hs:12:7: error:
• Expecting one more argument to ‘Maybe’
Expected a type, but ‘Maybe’ has kind ‘* -> *’
- • In the type signature:
- f :: [Maybe]
+ • In the type signature: f :: [Maybe]
tcfail113.hs:15:8: error:
• Expected kind ‘* -> *’, but ‘Int’ has kind ‘*’
• In the first argument of ‘T’, namely ‘Int’
- In the type signature:
- g :: T Int
+ In the type signature: g :: T Int
tcfail113.hs:18:6: error:
- • Expecting one fewer arguments to ‘Int’
- Expected kind ‘* -> *’, but ‘Int’ has kind ‘*’
- • In the type signature:
- h :: Int Int
+ • Expected kind ‘* -> *’, but ‘Int’ has kind ‘*’
+ • In the type signature: h :: Int Int
diff --git a/testsuite/tests/typecheck/should_fail/tcfail122.stderr b/testsuite/tests/typecheck/should_fail/tcfail122.stderr
index a6fbc86c49..29a1576ddb 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail122.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail122.stderr
@@ -1,7 +1,11 @@
tcfail122.hs:8:9: error:
- • Couldn't match kind ‘*’ with ‘* -> *’
- When matching the kind of ‘a’
+ • Couldn't match kind ‘* -> *’ with ‘*’
+ When matching types
+ c0 :: (* -> *) -> *
+ a :: * -> *
+ Expected type: a b
+ Actual type: c0 d0
• In the expression:
undefined :: forall (c :: (* -> *) -> *) (d :: * -> *). c d
In the expression:
diff --git a/testsuite/tests/typecheck/should_fail/tcfail123.stderr b/testsuite/tests/typecheck/should_fail/tcfail123.stderr
index 8f5f0a0afe..7089810e7c 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail123.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail123.stderr
@@ -1,7 +1,9 @@
tcfail123.hs:11:9: error:
• Couldn't match a lifted type with an unlifted type
- When matching the kind of ‘GHC.Prim.Int#’
+ When matching types
+ p0 :: *
+ GHC.Prim.Int# :: TYPE 'GHC.Types.IntRep
• In the first argument of ‘f’, namely ‘3#’
In the expression: f 3#
In an equation for ‘h’: h v = f 3#
diff --git a/testsuite/tests/typecheck/should_fail/tcfail132.stderr b/testsuite/tests/typecheck/should_fail/tcfail132.stderr
index 3f8f226468..2e0a13c844 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail132.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail132.stderr
@@ -1,7 +1,6 @@
tcfail132.hs:17:37: error:
- • Expecting one fewer arguments to ‘Object f' f t’
- Expected kind ‘* -> * -> * -> *’,
+ • Expected kind ‘* -> * -> * -> *’,
but ‘Object f' f t’ has kind ‘* -> * -> *’
• In the first argument of ‘T’, namely ‘(Object f' f t)’
In the type ‘T (Object f' f t) (DUnit t)’
diff --git a/testsuite/tests/typecheck/should_fail/tcfail200.stderr b/testsuite/tests/typecheck/should_fail/tcfail200.stderr
index 407265ee9d..fdd0e3c073 100644
--- a/testsuite/tests/typecheck/should_fail/tcfail200.stderr
+++ b/testsuite/tests/typecheck/should_fail/tcfail200.stderr
@@ -1,7 +1,11 @@
tcfail200.hs:5:15: error:
• Couldn't match a lifted type with an unlifted type
- When matching the kind of ‘GHC.Prim.Int#’
+ When matching types
+ a1 :: *
+ GHC.Prim.Int# :: TYPE 'GHC.Types.IntRep
• In the expression: 1#
In the expression: (1#, 'c')
In an equation for ‘x’: x = (1#, 'c')
+ • Relevant bindings include
+ x :: (a1, Char) (bound at tcfail200.hs:5:9)
diff --git a/testsuite/tests/typecheck/should_run/IPLocation.hs b/testsuite/tests/typecheck/should_run/IPLocation.hs
index 75575e0d16..964728934e 100644
--- a/testsuite/tests/typecheck/should_run/IPLocation.hs
+++ b/testsuite/tests/typecheck/should_run/IPLocation.hs
@@ -29,9 +29,15 @@ f6 0 = putStrLn $ prettyCallStack ?loc
f6 n = f6 (n-1)
-- recursive functions add a SrcLoc for each recursive call
+f7 :: IO ()
+f7 = putStrLn (prettyCallStack $ id (\_ -> callStack) ())
+ -- shouldn't crash. See #14043.
+
+main :: IO ()
main = do f0
f1
f3 (\ () -> putStrLn $ prettyCallStack ?loc)
f4 (\ () -> putStrLn $ prettyCallStack ?loc)
f5 (\ () -> putStrLn $ prettyCallStack ?loc3)
f6 5
+ f7
diff --git a/testsuite/tests/unboxedsums/T14051.hs b/testsuite/tests/unboxedsums/T14051.hs
new file mode 100644
index 0000000000..96662a946e
--- /dev/null
+++ b/testsuite/tests/unboxedsums/T14051.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE UnboxedSums #-}
+
+module Main where
+
+import T14051a
+
+main :: IO ()
+main = print $ case func () of
+ (# True | #) -> 123
+ _ -> 321
diff --git a/testsuite/tests/unboxedsums/T14051a.hs b/testsuite/tests/unboxedsums/T14051a.hs
new file mode 100644
index 0000000000..b88f70ea05
--- /dev/null
+++ b/testsuite/tests/unboxedsums/T14051a.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE UnboxedSums #-}
+
+module T14051a where
+
+func :: s -> (# Bool | Bool #)
+func _ = (# True | #)
diff --git a/testsuite/tests/unboxedsums/all.T b/testsuite/tests/unboxedsums/all.T
index eea818b6f1..45723cb4f0 100644
--- a/testsuite/tests/unboxedsums/all.T
+++ b/testsuite/tests/unboxedsums/all.T
@@ -32,3 +32,4 @@ test('T12711', only_ways(['ghci']), ghci_script, ['T12711.script'])
# ['$MAKE -s --no-print-directory sum_api_annots'])
test('UbxSumLevPoly', normal, compile, [''])
+test('T14051', normal, multi_compile, ['T14051.hs', [('T14051a.hs', '')], '-O2 -v0'])
diff --git a/utils/ghc-cabal/ghc.mk b/utils/ghc-cabal/ghc.mk
index 6250484017..eeae8a715b 100644
--- a/utils/ghc-cabal/ghc.mk
+++ b/utils/ghc-cabal/ghc.mk
@@ -27,9 +27,9 @@ CABAL_CONSTRAINT := --constraint="Cabal == $(CABAL_DOTTED_VERSION)"
# `cabal_macros_boot.h` also for GHC >= 8 (in which case it becomes a
# dummy include that doesn't contribute any macro definitions).
ifeq "$(Windows_Host)" "YES"
-CABAL_BUILD_DEPS := base array time containers bytestring deepseq process pretty directory Win32
+CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory Win32
else
-CABAL_BUILD_DEPS := base array time containers bytestring deepseq process pretty directory unix
+CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory unix
endif
ghc-cabal_DIST_BINARY_NAME = ghc-cabal$(exeext0)
@@ -40,11 +40,23 @@ ifneq "$(BINDIST)" "YES"
$(ghc-cabal_INPLACE) : $(ghc-cabal_DIST_BINARY) | $$(dir $$@)/.
"$(CP)" $< $@
+# Minor hack, since we can't reuse the `hs-suffix-rules-srcdir` macro
+ifneq ($(wildcard libraries/Cabal/Cabal/Distribution/Parsec/Lexer.x),)
+# Lexer.x exists so we have to call Alex ourselves
+CABAL_LEXER_DEP := bootstrapping/Cabal/Distribution/Parsec/Lexer.hs
+
+bootstrapping/Cabal/Distribution/Parsec/Lexer.hs: libraries/Cabal/Cabal/Distribution/Parsec/Lexer.x
+ mkdir -p bootstrapping/Cabal/Distribution/Parsec
+ $(call cmd,ALEX) $< -o $@
+else
+CABAL_LEXER_DEP := libraries/Cabal/Cabal/Distribution/Parsec/Lexer.hs
+endif
+
$(ghc-cabal_DIST_BINARY): $(wildcard libraries/Cabal/Cabal/Distribution/*/*/*.hs)
$(ghc-cabal_DIST_BINARY): $(wildcard libraries/Cabal/Cabal/Distribution/*/*.hs)
$(ghc-cabal_DIST_BINARY): $(wildcard libraries/Cabal/Cabal/Distribution/*.hs)
-$(ghc-cabal_DIST_BINARY): utils/ghc-cabal/Main.hs $(TOUCH_DEP) | $$(dir $$@)/. bootstrapping/.
+$(ghc-cabal_DIST_BINARY): $(CABAL_LEXER_DEP) utils/ghc-cabal/Main.hs $(TOUCH_DEP) | $$(dir $$@)/. bootstrapping/.
"$(GHC)" $(SRC_HC_OPTS) \
$(addprefix -optc, $(SRC_CC_OPTS) $(CONF_CC_OPTS_STAGE0)) \
$(addprefix -optl, $(SRC_LD_OPTS) $(CONF_GCC_LINKER_OPTS_STAGE0)) \
@@ -54,14 +66,21 @@ $(ghc-cabal_DIST_BINARY): utils/ghc-cabal/Main.hs $(TOUCH_DEP) | $$(dir $$@)/. b
-no-user-$(GHC_PACKAGE_DB_FLAG) \
-Wall -fno-warn-unused-imports -fno-warn-warnings-deprecations \
-DCABAL_VERSION=$(CABAL_VERSION) \
+ -DCABAL_PARSEC \
-DBOOTSTRAPPING \
-optP-include -optPutils/ghc-cabal/cabal_macros_boot.h \
-odir bootstrapping \
-hidir bootstrapping \
+ $(CABAL_LEXER_DEP) \
-ilibraries/Cabal/Cabal \
-ilibraries/binary/src \
-ilibraries/filepath \
-ilibraries/hpc \
+ -ilibraries/mtl \
+ -ilibraries/text \
+ libraries/text/cbits/cbits.c \
+ -Ilibraries/text/include \
+ -ilibraries/parsec \
$(utils/ghc-cabal_dist_EXTRA_HC_OPTS) \
$(EXTRA_HC_OPTS)
"$(TOUCH_CMD)" $@
diff --git a/utils/ghctags/Main.hs b/utils/ghctags/Main.hs
index c4db3ca212..f74c7514db 100644
--- a/utils/ghctags/Main.hs
+++ b/utils/ghctags/Main.hs
@@ -284,7 +284,6 @@ boundThings modname lbinding =
PatBind { pat_lhs = lhs } -> patThings lhs []
VarBind { var_id = id } -> [FoundThing modname (getOccString id) (startOfLocated lbinding)]
AbsBinds { } -> [] -- nothing interesting in a type abstraction
- AbsBindsSig { } -> []
PatSynBind PSB{ psb_id = id } -> [thing id]
where thing = foundOfLName modname
patThings lpat tl =
diff --git a/validate b/validate
index 09f4fd2f23..d885bd76ba 100755
--- a/validate
+++ b/validate
@@ -296,6 +296,7 @@ rm -f testsuite_summary.txt testsuite_summary_stage1.txt
$make -C testsuite/tests $BINDIST $PYTHON_ARG \
$MAKE_TEST_TARGET stage=2 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \
NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../testsuite_summary.txt \
+ JUNIT_FILE=../../testsuite.xml \
2>&1 | tee testlog
# Run a few tests using the stage1 compiler.
@@ -304,6 +305,7 @@ $make -C testsuite/tests $BINDIST $PYTHON_ARG \
$make -C testsuite/tests/stage1 $PYTHON_ARG \
$MAKE_TEST_TARGET stage=1 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \
NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../../testsuite_summary_stage1.txt \
+ JUNIT_FILE=../../../testsuite_stage1.xml \
2>&1 | tee testlog-stage1
echo