Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ghc/ghc
  • bgamari/ghc
  • syd/ghc
  • ggreif/ghc
  • watashi/ghc
  • RolandSenn/ghc
  • mpickering/ghc
  • DavidEichmann/ghc
  • carter/ghc
  • harpocrates/ghc
  • ethercrow/ghc
  • mijicd/ghc
  • adamse/ghc
  • alexbiehl/ghc
  • gridaphobe/ghc
  • trofi/ghc
  • supersven/ghc
  • ppk/ghc
  • ulysses4ever/ghc
  • AndreasK/ghc
  • ghuntley/ghc
  • shayne-fletcher-da/ghc
  • fgaz/ghc
  • yav/ghc
  • osa1/ghc
  • mbbx6spp/ghc
  • JulianLeviston/ghc
  • reactormonk/ghc
  • rae/ghc
  • takenobu-hs/ghc
  • michalt/ghc
  • andrewthad/ghc
  • hsyl20/ghc
  • scottgw/ghc
  • sjakobi/ghc
  • angerman/ghc
  • RyanGlScott/ghc
  • hvr/ghc
  • howtonotwin/ghc
  • chessai/ghc
  • m-renaud/ghc
  • brprice/ghc
  • stevehartdata/ghc
  • sighingnow/ghc
  • kgardas/ghc
  • ckoparkar/ghc
  • alp/ghc
  • smaeul/ghc
  • kakkun61/ghc
  • sykloid/ghc
  • newhoggy/ghc
  • toonn/ghc
  • nineonine/ghc
  • Phyx/ghc
  • ezyang/ghc
  • tweag/ghc
  • langston/ghc
  • ndmitchell/ghc
  • rockbmb/ghc
  • artempyanykh/ghc
  • mniip/ghc
  • mynguyenbmc/ghc
  • alexfmpe/ghc
  • crockeea/ghc
  • nh2/ghc
  • vaibhavsagar/ghc
  • phadej/ghc
  • Haskell-mouse/ghc
  • lolotp/ghc
  • spacekitteh/ghc
  • michaelpj/ghc
  • mgsloan/ghc
  • HPCohen/ghc
  • tmobile/ghc
  • radrow/ghc
  • simonmar/ghc
  • _deepfire/ghc
  • Ericson2314/ghc
  • leitao/ghc
  • fumieval/ghc
  • trac-isovector/ghc
  • cblp/ghc
  • xich/ghc
  • ciil/ghc
  • erthalion/ghc
  • xldenis/ghc
  • autotaker/ghc
  • haskell-wasm/ghc
  • kcsongor/ghc
  • agander/ghc
  • Baranowski/ghc
  • trac-dredozubov/ghc
  • 23Skidoo/ghc
  • iustin/ghc
  • ningning/ghc
  • josefs/ghc
  • kabuhr/ghc
  • gallais/ghc
  • dten/ghc
  • expipiplus1/ghc
  • Pluralia/ghc
  • rohanjr/ghc
  • intricate/ghc
  • kirelagin/ghc
  • Javran/ghc
  • DanielG/ghc
  • trac-mizunashi_mana/ghc
  • pparkkin/ghc
  • bollu/ghc
  • ntc2/ghc
  • jaspervdj/ghc
  • JoshMeredith/ghc
  • wz1000/ghc
  • zkourouma/ghc
  • code5hot/ghc
  • jdprice/ghc
  • tdammers/ghc
  • J-mie6/ghc
  • trac-lantti/ghc
  • ch1bo/ghc
  • cgohla/ghc
  • lucamolteni/ghc
  • acairncross/ghc
  • amerocu/ghc
  • chreekat/ghc
  • txsmith/ghc
  • trupill/ghc
  • typetetris/ghc
  • sergv/ghc
  • fryguybob/ghc
  • erikd/ghc
  • trac-roland/ghc
  • setupminimal/ghc
  • Friede80/ghc
  • SkyWriter/ghc
  • xplorld/ghc
  • abrar/ghc
  • obsidiansystems/ghc
  • Icelandjack/ghc
  • adinapoli/ghc
  • trac-matthewbauer/ghc
  • heatsink/ghc
  • dwijnand/ghc
  • Cmdv/ghc
  • alinab/ghc
  • pepeiborra/ghc
  • fommil/ghc
  • luochen1990/ghc
  • rlupton20/ghc
  • applePrincess/ghc
  • lehins/ghc
  • ronmrdechai/ghc
  • leeadam/ghc
  • harendra/ghc
  • mightymosquito1991/ghc
  • trac-gershomb/ghc
  • lucajulian/ghc
  • Rizary/ghc
  • VictorCMiraldo/ghc
  • jamesbrock/ghc
  • andrewdmeier/ghc
  • luke/ghc
  • pranaysashank/ghc
  • cocreature/ghc
  • hithroc/ghc
  • obreitwi/ghc
  • slrtbtfs/ghc
  • kaol/ghc
  • yairchu/ghc
  • Mathemagician98/ghc
  • trac-taylorfausak/ghc
  • leungbk/ghc
  • MichaWiedenmann/ghc
  • chris-martin/ghc
  • TDecki/ghc
  • adithyaov/ghc
  • trac-gelisam/ghc
  • Lysxia/ghc
  • complyue/ghc
  • bwignall/ghc
  • sternmull/ghc
  • sonika/ghc
  • leif/ghc
  • broadwaylamb/ghc
  • myszon/ghc
  • danbroooks/ghc
  • Mechachleopteryx/ghc
  • zardyh/ghc
  • trac-vdukhovni/ghc
  • OmarKhaledAbdo/ghc
  • arrowd/ghc
  • Bodigrim/ghc
  • matheus23/ghc
  • cardenaso11/ghc
  • trac-Athas/ghc
  • mb720/ghc
  • DylanZA/ghc
  • liff/ghc
  • typedrat/ghc
  • trac-claude/ghc
  • jbm/ghc
  • Gertjan423/ghc
  • PHO/ghc
  • JKTKops/ghc
  • kockahonza/ghc
  • msakai/ghc
  • Sir4ur0n/ghc
  • barambani/ghc
  • vishnu.c/ghc
  • dcoutts/ghc
  • trac-runeks/ghc
  • trac-MaxGabriel/ghc
  • lexi.lambda/ghc
  • strake/ghc
  • spavikevik/ghc
  • JakobBruenker/ghc
  • rmanne/ghc
  • gdziadkiewicz/ghc
  • ani/ghc
  • iliastsi/ghc
  • smunix/ghc
  • judah/ghc
  • blackgnezdo/ghc
  • emilypi/ghc
  • trac-bpfoley/ghc
  • muesli4/ghc
  • trac-gkaracha/ghc
  • Kleidukos/ghc
  • nek0/ghc
  • TristanCacqueray/ghc
  • dwulive/ghc
  • mbakke/ghc
  • arybczak/ghc
  • Yang123321/ghc
  • maksbotan/ghc
  • QuietMisdreavus/ghc
  • trac-olshanskydr/ghc
  • emekoi/ghc
  • samuela/ghc
  • josephcsible/ghc
  • dramforever/ghc
  • lpsmith/ghc
  • DenisFrezzato/ghc
  • michivi/ghc
  • jneira/ghc
  • jeffhappily/ghc
  • Ivan-Yudin/ghc
  • nakaji-dayo/ghc
  • gdevanla/ghc
  • galen/ghc
  • fendor/ghc
  • yaitskov/ghc
  • rcythr/ghc
  • awpr/ghc
  • jeremyschlatter/ghc
  • Aver1y/ghc
  • mitchellvitez/ghc
  • merijn/ghc
  • tomjaguarpaw1/ghc
  • trac-NoidedSuper/ghc
  • erewok/ghc
  • trac-junji.hashimoto/ghc
  • adamwespiser/ghc
  • bjaress/ghc
  • jhrcek/ghc
  • leonschoorl/ghc
  • lukasz-golebiewski/ghc
  • sheaf/ghc
  • last-g/ghc
  • carassius1014/ghc
  • eschwartz/ghc
  • dwincort/ghc
  • felixwiemuth/ghc
  • TimWSpence/ghc
  • marcusmonteirodesouza/ghc
  • WJWH/ghc
  • vtols/ghc
  • theobat/ghc
  • BinderDavid/ghc
  • ckoparkar0/ghc
  • alexander-kjeldaas/ghc
  • dme2/ghc
  • philderbeast/ghc
  • aaronallen8455/ghc
  • rayshih/ghc
  • benkard/ghc
  • mpardalos/ghc
  • saidelman/ghc
  • leiftw/ghc
  • ca333/ghc
  • bwroga/ghc
  • nmichael44/ghc
  • trac-crobbins/ghc
  • felixonmars/ghc
  • adityagupta1089/ghc
  • hgsipiere/ghc
  • treeowl/ghc
  • alexpeits/ghc
  • CraigFe/ghc
  • dnlkrgr/ghc
  • kerckhove_ts/ghc
  • cptwunderlich/ghc
  • eiais/ghc
  • hahohihu/ghc
  • sanchayan/ghc
  • lemmih/ghc
  • sehqlr/ghc
  • trac-dbeacham/ghc
  • luite/ghc
  • trac-f-a/ghc
  • vados/ghc
  • luntain/ghc
  • fatho/ghc
  • alexbiehl-gc/ghc
  • dcbdan/ghc
  • tvh/ghc
  • liam-ly/ghc
  • timbobbarnes/ghc
  • GovanifY/ghc
  • shanth2600/ghc
  • gliboc/ghc
  • duog/ghc
  • moxonsghost/ghc
  • zander/ghc
  • masaeedu/ghc
  • georgefst/ghc
  • guibou/ghc
  • nicuveo/ghc
  • mdebruijne/ghc
  • stjordanis/ghc
  • emiflake/ghc
  • wygulmage/ghc
  • frasertweedale/ghc
  • coot/ghc
  • aratamizuki/ghc
  • tsandstr/ghc
  • mrBliss/ghc
  • Anton-Latukha/ghc
  • tadfisher/ghc
  • vapourismo/ghc
  • Sorokin-Anton/ghc
  • basile-henry/ghc
  • trac-mightybyte/ghc
  • AbsoluteNikola/ghc
  • cobrien99/ghc
  • songzh/ghc
  • blamario/ghc
  • aj4ayushjain/ghc
  • trac-utdemir/ghc
  • tangcl/ghc
  • hdgarrood/ghc
  • maerwald/ghc
  • arjun/ghc
  • ratherforky/ghc
  • haskieLambda/ghc
  • EmilGedda/ghc
  • Bogicevic/ghc
  • eddiejessup/ghc
  • kozross/ghc
  • AlistairB/ghc
  • 3Rafal/ghc
  • christiaanb/ghc
  • trac-bit/ghc
  • matsumonkie/ghc
  • trac-parsonsmatt/ghc
  • chisui/ghc
  • jaro/ghc
  • trac-kmiyazato/ghc
  • davidsd/ghc
  • Tritlo/ghc
  • I-B-3/ghc
  • lykahb/ghc
  • AriFordsham/ghc
  • turion1/ghc
  • berberman/ghc
  • christiantakle/ghc
  • zyklotomic/ghc
  • trac-ocramz/ghc
  • CSEdd/ghc
  • doyougnu/ghc
  • mmhat/ghc
  • why-not-try-calmer/ghc
  • plutotulp/ghc
  • kjekac/ghc
  • Manvi07/ghc
  • teo/ghc
  • cactus/ghc
  • CarrieMY/ghc
  • abel/ghc
  • yihming/ghc
  • tsakki/ghc
  • jessicah/ghc
  • oliverbunting/ghc
  • meld/ghc
  • friedbrice/ghc
  • Joald/ghc
  • abarbu/ghc
  • DigitalBrains1/ghc
  • sterni/ghc
  • alexDarcy/ghc
  • hexchain/ghc
  • minimario/ghc
  • zliu41/ghc
  • tommd/ghc
  • jazcarate/ghc
  • peterbecich/ghc
  • alirezaghey/ghc
  • solomon/ghc
  • mikael.urankar/ghc
  • davjam/ghc
  • int-index/ghc
  • MorrowM/ghc
  • nrnrnr/ghc
  • Sonfamm/ghc-test-only
  • afzt1/ghc
  • nguyenhaibinh-tpc/ghc
  • trac-lierdakil/ghc
  • MichaWiedenmann1/ghc
  • jmorag/ghc
  • Ziharrk/ghc
  • trac-MitchellSalad/ghc
  • juampe/ghc
  • jwaldmann/ghc
  • snowleopard/ghc
  • juhp/ghc
  • normalcoder/ghc
  • ksqsf/ghc
  • trac-jberryman/ghc
  • roberth/ghc
  • 1ntEgr8/ghc
  • epworth/ghc
  • MrAdityaAlok/ghc
  • JunmingZhao42/ghc
  • jappeace/ghc
  • trac-Gabriel439/ghc
  • alt-romes/ghc
  • HugoPeters1024/ghc
  • 10ne1/ghc-fork
  • agentultra/ghc
  • Garfield1002/ghc
  • ChickenProp/ghc
  • clyring/ghc
  • MaxHearnden/ghc
  • jumper149/ghc
  • vem/ghc
  • ketzacoatl/ghc
  • Rosuavio/ghc
  • jackohughes/ghc
  • p4l1ly/ghc
  • konsumlamm/ghc
  • shlevy/ghc
  • torsten.schmits/ghc
  • andremarianiello/ghc
  • amesgen/ghc
  • googleson78/ghc
  • InfiniteVerma/ghc
  • uhbif19/ghc
  • yiyunliu/ghc
  • raehik/ghc
  • mrkun/ghc
  • telser/ghc
  • 1Jajen1/ghc
  • slotThe/ghc
  • WinstonHartnett/ghc
  • mpilgrem/ghc
  • dreamsmasher/ghc
  • schuelermine/ghc
  • trac-Viwor/ghc
  • undergroundquizscene/ghc
  • evertedsphere/ghc
  • coltenwebb/ghc
  • oberblastmeister/ghc
  • agrue/ghc
  • lf-/ghc
  • zacwood9/ghc
  • steshaw/ghc
  • high-cloud/ghc
  • SkamDart/ghc
  • PiDelport/ghc
  • maoif/ghc
  • RossPaterson/ghc
  • CharlesTaylor7/ghc
  • ribosomerocker/ghc
  • trac-ramirez7/ghc
  • daig/ghc
  • NicolasT/ghc
  • FinleyMcIlwaine/ghc
  • lawtonnichols/ghc
  • jmtd/ghc
  • ozkutuk/ghc
  • wildsebastian/ghc
  • lrzlin/ghc
  • tobias/ghc
  • fw/ghc
  • hawkinsw/ghc
  • type-dance/ghc
  • rui314/ghc
  • ocharles/ghc
  • wavewave/ghc
  • TheKK/ghc
  • nomeata/ghc
  • trac-csabahruska/ghc
  • jonathanjameswatson/ghc
  • L-as/ghc
  • Axman6/ghc
  • barracuda156/ghc
  • trac-jship/ghc
  • jake-87/ghc
  • meooow/ghc
  • rebeccat/ghc
  • hamana55/ghc
  • Enigmage/ghc
  • kokobd/ghc
  • agevelt/ghc
  • gshen42/ghc
  • chrismwendt/ghc
  • MangoIV/ghc
  • teto/ghc
  • Sookr1/ghc
  • trac-thomasjm/ghc
  • barci2/ghc-dev
  • trac-m4dc4p/ghc
  • dixonary/ghc
  • breakerzirconia/ghc
  • alexsio27444/ghc
  • glocq/ghc
  • sourabhxyz/ghc
  • ryantrinkle/ghc
  • Jade/ghc
  • scedfaliako/ghc
  • martijnbastiaan/ghc
  • trac-george.colpitts/ghc
  • ammarbinfaisal/ghc
  • mimi.vx/ghc
  • lortabac/ghc
  • trac-zyla/ghc
  • benbellick/ghc
  • aadaa-fgtaa/ghc
  • jvanbruegge/ghc
  • archbung/ghc
  • gilmi/ghc
  • mfonism/ghc
  • alex-mckenna/ghc
  • Ei30metry/ghc
  • DiegoDiverio/ghc
  • jorgecunhamendes/ghc
  • liesnikov/ghc
  • akrmn/ghc
  • trac-simplifierticks/ghc
  • jacco/ghc
  • rhendric/ghc
  • damhiya/ghc
  • ryndubei/ghc
  • DaveBarton/ghc
  • trac-Profpatsch/ghc
  • GZGavinZhao/ghc
  • ncfavier/ghc
  • jameshaydon/ghc
  • ajccosta/ghc
  • dschrempf/ghc
  • cydparser/ghc
  • LinuxUserGD/ghc
  • elodielander/ghc
  • facundominguez/ghc
  • psilospore/ghc
  • lachrimae/ghc
  • dylan-thinnes/ghc-type-errors-plugin
  • hamishmack/ghc
  • Leary/ghc
  • lzszt/ghc
  • lyokha/ghc
  • trac-glaubitz/ghc
  • Rewbert/ghc
  • andreabedini/ghc
  • Jasagredo/ghc
  • sol/ghc
  • OlegAlexander/ghc
  • trac-sthibaul/ghc
  • avdv/ghc
  • Wendaolee/ghc
  • ur4t/ghc
  • daylily/ghc
  • boltzmannrain/ghc
  • mmzk1526/ghc
  • trac-fizzixnerd/ghc
  • soulomoon/ghc
  • rwmjones/ghc
  • j14i/ghc
  • tracsis/ghc
  • gesh/ghc
  • flip101/ghc
  • eldritch-cookie/ghc
  • LemonjamesD/ghc
  • pgujjula/ghc
  • skeuchel/ghc
  • noteed/ghc
  • Torrekie/ghc
  • jlwoodwa/ghc
  • ayanamists/ghc
  • husong998/ghc
  • trac-edmundnoble/ghc
  • josephf/ghc
  • contrun/ghc
  • baulig/ghc
  • edsko/ghc
  • mzschr/ghc-issue-24732
  • ulidtko/ghc
  • Arsen/ghc
  • trac-sjoerd_visscher/ghc
  • crumbtoo/ghc
  • L0neGamer/ghc
  • DrewFenwick/ghc
  • benz0li/ghc
  • MaciejWas/ghc
  • jordanrule/ghc
  • trac-qqwy/ghc
  • LiamGoodacre/ghc
  • isomorpheme/ghc
  • trac-danidiaz/ghc
  • Kariim/ghc
  • taimoorzaeem/ghc
  • hololeap/ghc
  • ticat-fp/ghc
  • meritamen/ghc
  • criskell/ghc
  • trac-kraai/ghc
  • aergus/ghc
  • jdral/ghc
  • SamB/ghc
  • Tristian/ghc
  • ywgrit/ghc
  • KatsuPatrick/ghc
  • OsePedro/ghc
  • mpscholten/ghc
  • zaquest/ghc
  • fangyi-zhou/ghc
  • augyg/ghc
  • rkirkman/ghc
  • gulin.serge/ghc-windows-aarch64-bootstrap
  • iris/ghc
  • kwxm/ghc
  • maralorn/ghc
  • rafl/ghc
  • nikshalark/ghc
  • mrcjkb/ghc
  • blackheaven/ghc
  • laurenyim/ghc
  • bolt12/ghc
  • Xitian9/ghc
  • wenkokke/ghc
  • kephas/ghc
651 results
Show changes
Commits on Source (268)
Showing
with 433 additions and 247 deletions
[submodule "libraries/binary"] [submodule "libraries/binary"]
path = libraries/binary path = libraries/binary
url = http://git.haskell.org/packages/binary.git url = ../packages/binary.git
ignore = untracked ignore = untracked
[submodule "libraries/bytestring"] [submodule "libraries/bytestring"]
path = libraries/bytestring path = libraries/bytestring
url = http://git.haskell.org/packages/bytestring.git url = ../packages/bytestring.git
ignore = untracked ignore = untracked
[submodule "libraries/Cabal"] [submodule "libraries/Cabal"]
path = libraries/Cabal path = libraries/Cabal
url = http://git.haskell.org/packages/Cabal.git url = ../packages/Cabal.git
ignore = untracked ignore = untracked
[submodule "libraries/containers"] [submodule "libraries/containers"]
path = libraries/containers path = libraries/containers
url = http://git.haskell.org/packages/containers.git url = ../packages/containers.git
ignore = untracked ignore = untracked
[submodule "libraries/haskeline"] [submodule "libraries/haskeline"]
path = libraries/haskeline path = libraries/haskeline
url = http://git.haskell.org/packages/haskeline.git url = ../packages/haskeline.git
ignore = untracked ignore = untracked
[submodule "libraries/pretty"] [submodule "libraries/pretty"]
path = libraries/pretty path = libraries/pretty
url = http://git.haskell.org/packages/pretty.git url = ../packages/pretty.git
ignore = untracked ignore = untracked
[submodule "libraries/terminfo"] [submodule "libraries/terminfo"]
path = libraries/terminfo path = libraries/terminfo
url = http://git.haskell.org/packages/terminfo.git url = ../packages/terminfo.git
ignore = untracked ignore = untracked
[submodule "libraries/transformers"] [submodule "libraries/transformers"]
path = libraries/transformers path = libraries/transformers
url = http://git.haskell.org/packages/transformers.git url = ../packages/transformers.git
ignore = untracked ignore = untracked
[submodule "libraries/xhtml"] [submodule "libraries/xhtml"]
path = libraries/xhtml path = libraries/xhtml
url = http://git.haskell.org/packages/xhtml.git url = ../packages/xhtml.git
ignore = untracked ignore = untracked
[submodule "libraries/Win32"] [submodule "libraries/Win32"]
path = libraries/Win32 path = libraries/Win32
url = http://git.haskell.org/packages/Win32.git url = ../packages/Win32.git
ignore = untracked ignore = untracked
[submodule "libraries/primitive"] [submodule "libraries/primitive"]
path = libraries/primitive path = libraries/primitive
url = http://git.haskell.org/packages/primitive.git url = ../packages/primitive.git
ignore = untracked ignore = untracked
[submodule "libraries/vector"] [submodule "libraries/vector"]
path = libraries/vector path = libraries/vector
url = http://git.haskell.org/packages/vector.git url = ../packages/vector.git
ignore = untracked ignore = untracked
[submodule "libraries/time"] [submodule "libraries/time"]
path = libraries/time path = libraries/time
url = http://git.haskell.org/packages/time.git url = ../packages/time.git
ignore = untracked ignore = untracked
[submodule "libraries/random"] [submodule "libraries/random"]
path = libraries/random path = libraries/random
url = http://git.haskell.org/packages/random.git url = ../packages/random.git
ignore = untracked ignore = untracked
============================================================== ==============================================================
The (Interactive) Glasgow Haskell Compiler -- version 6.10.1 The (Interactive) Glasgow Haskell Compiler -- version 7.8.2
============================================================== ==============================================================
The GHC Team is pleased to announce a new major release of GHC. There The GHC Team is pleased to announce a new patchlevel release of GHC, 7.8.2.
have been a number of significant changes since the last major release,
including:
* Some new language features have been implemented: This is a bugfix release relative to 7.8.1, so we recommend upgrading.
* Record syntax: wild-card patterns, punning, and field disambiguation
* Generalised quasi-quotes
* Generalised list comprehensions
* View patterns
* Type families have been completely re-implemented
* Now comes with Haddock 2, which supports all GHC extensions
* Parallel garbage collection
* Base provides extensible exceptions
* The GHC API is easier to use
* External core (output only) now works again
* Data Parallel Haskell (DPH) comes as part of GHC
The full release notes are here: The full release notes are here:
http://haskell.org/ghc/docs/6.10.1/html/users_guide/release-6-10-1.html http://haskell.org/ghc/docs/7.8.1/html/users_guide/release-7-8-2.html
How to get it How to get it
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
...@@ -82,7 +62,8 @@ Supported Platforms ...@@ -82,7 +62,8 @@ Supported Platforms
The list of platforms we support, and the people responsible for them, The list of platforms we support, and the people responsible for them,
is here: is here:
http://ghc.haskell.org/trac/ghc/wiki/Contributors http://ghc.haskell.org/trac/ghc/wiki/Platforms
http://ghc.haskell.org/trac/ghc/wiki/CodeOwners
Ports to other platforms are possible with varying degrees of Ports to other platforms are possible with varying degrees of
difficulty. The Building Guide describes how to go about porting to a difficulty. The Building Guide describes how to go about porting to a
......
...@@ -72,7 +72,7 @@ endif ...@@ -72,7 +72,7 @@ endif
$(MAKE) -r --no-print-directory -f ghc.mk phase=final $@ $(MAKE) -r --no-print-directory -f ghc.mk phase=final $@
binary-dist: binary-dist-prep binary-dist: binary-dist-prep
mv bindistprep/*.tar.bz2 . mv bindistprep/*.tar.$(TAR_COMP_EXT) .
binary-dist-prep: binary-dist-prep:
ifeq "$(mingw32_TARGET_OS)" "1" ifeq "$(mingw32_TARGET_OS)" "1"
......
...@@ -206,7 +206,7 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS], ...@@ -206,7 +206,7 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS],
mipsel) mipsel)
test -z "[$]2" || eval "[$]2=ArchMipsel" test -z "[$]2" || eval "[$]2=ArchMipsel"
;; ;;
hppa|hppa1_1|ia64|m68k|rs6000|s390|s390x|sparc64|vax) hppa|hppa1_1|ia64|m68k|powerpc64le|rs6000|s390|s390x|sparc64|vax)
test -z "[$]2" || eval "[$]2=ArchUnknown" test -z "[$]2" || eval "[$]2=ArchUnknown"
;; ;;
*) *)
...@@ -451,6 +451,7 @@ AC_DEFUN([FP_SETTINGS], ...@@ -451,6 +451,7 @@ AC_DEFUN([FP_SETTINGS],
then then
mingw_bin_prefix=mingw/bin/ mingw_bin_prefix=mingw/bin/
SettingsCCompilerCommand="\$topdir/../${mingw_bin_prefix}gcc.exe" SettingsCCompilerCommand="\$topdir/../${mingw_bin_prefix}gcc.exe"
SettingsHaskellCPPCommand="\$topdir/../${mingw_bin_prefix}gcc.exe"
SettingsLdCommand="\$topdir/../${mingw_bin_prefix}ld.exe" SettingsLdCommand="\$topdir/../${mingw_bin_prefix}ld.exe"
SettingsArCommand="\$topdir/../${mingw_bin_prefix}ar.exe" SettingsArCommand="\$topdir/../${mingw_bin_prefix}ar.exe"
SettingsPerlCommand='$topdir/../perl/perl.exe' SettingsPerlCommand='$topdir/../perl/perl.exe'
...@@ -459,6 +460,8 @@ AC_DEFUN([FP_SETTINGS], ...@@ -459,6 +460,8 @@ AC_DEFUN([FP_SETTINGS],
SettingsTouchCommand='$topdir/touchy.exe' SettingsTouchCommand='$topdir/touchy.exe'
else else
SettingsCCompilerCommand="$WhatGccIsCalled" SettingsCCompilerCommand="$WhatGccIsCalled"
SettingsHaskellCPPCommand="$HaskellCPPCmd"
SettingsHaskellCPPFlags="$HaskellCPPArgs"
SettingsLdCommand="$LdCmd" SettingsLdCommand="$LdCmd"
SettingsArCommand="$ArCmd" SettingsArCommand="$ArCmd"
SettingsPerlCommand="$PerlCmd" SettingsPerlCommand="$PerlCmd"
...@@ -483,6 +486,8 @@ AC_DEFUN([FP_SETTINGS], ...@@ -483,6 +486,8 @@ AC_DEFUN([FP_SETTINGS],
SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2"
SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2" SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2"
AC_SUBST(SettingsCCompilerCommand) AC_SUBST(SettingsCCompilerCommand)
AC_SUBST(SettingsHaskellCPPCommand)
AC_SUBST(SettingsHaskellCPPFlags)
AC_SUBST(SettingsCCompilerFlags) AC_SUBST(SettingsCCompilerFlags)
AC_SUBST(SettingsCCompilerLinkFlags) AC_SUBST(SettingsCCompilerLinkFlags)
AC_SUBST(SettingsLdCommand) AC_SUBST(SettingsLdCommand)
...@@ -643,6 +648,10 @@ AC_ARG_WITH($2, ...@@ -643,6 +648,10 @@ AC_ARG_WITH($2,
else else
$1=$withval $1=$withval
fi fi
# Remember that we set this manually. Used to override CC_STAGE0
# and friends later, if we are not cross-compiling.
With_$2=$withval
], ],
[ [
if test "$HostOS" != "mingw32" if test "$HostOS" != "mingw32"
...@@ -685,6 +694,10 @@ AC_ARG_WITH($2, ...@@ -685,6 +694,10 @@ AC_ARG_WITH($2,
else else
$1=$withval $1=$withval
fi fi
# Remember that we set this manually. Used to override CC_STAGE0
# and friends later, if we are not cross-compiling.
With_$2=$withval
], ],
[ [
if test "$HostOS" != "mingw32" if test "$HostOS" != "mingw32"
...@@ -695,6 +708,8 @@ AC_ARG_WITH($2, ...@@ -695,6 +708,8 @@ AC_ARG_WITH($2,
) )
]) # FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL ]) # FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL
# FP_PROG_CONTEXT_DIFF # FP_PROG_CONTEXT_DIFF
# -------------------- # --------------------
# Figure out how to do context diffs. Sets the output variable ContextDiffCmd. # Figure out how to do context diffs. Sets the output variable ContextDiffCmd.
...@@ -1137,6 +1152,16 @@ AC_DEFUN([FP_PROG_AR_NEEDS_RANLIB],[ ...@@ -1137,6 +1152,16 @@ AC_DEFUN([FP_PROG_AR_NEEDS_RANLIB],[
esac esac
fi fi
# workaround for AC_PROG_RANLIB which sets RANLIB to `:' when
# ranlib is missing on the target OS. The problem is that
# ghc-cabal cannot execute `:' which is a shell built-in but can
# execute `true' which is usually simple program supported by the
# OS.
# Fixes #8795
if test "$RANLIB" = ":"
then
RANLIB="true"
fi
REAL_RANLIB_CMD="$RANLIB" REAL_RANLIB_CMD="$RANLIB"
if test $fp_cv_prog_ar_needs_ranlib = yes if test $fp_cv_prog_ar_needs_ranlib = yes
then then
...@@ -1788,7 +1813,12 @@ AC_MSG_NOTICE(Building in-tree ghc-pwd) ...@@ -1788,7 +1813,12 @@ AC_MSG_NOTICE(Building in-tree ghc-pwd)
dnl except we don't want to have to know what make is called. Sigh. dnl except we don't want to have to know what make is called. Sigh.
rm -rf utils/ghc-pwd/dist-boot rm -rf utils/ghc-pwd/dist-boot
mkdir utils/ghc-pwd/dist-boot mkdir utils/ghc-pwd/dist-boot
if ! "$WithGhc" -v0 -no-user-$GHC_PACKAGE_DB_FLAG -hidir utils/ghc-pwd/dist-boot -odir utils/ghc-pwd/dist-boot -stubdir utils/ghc-pwd/dist-boot --make utils/ghc-pwd/Main.hs -o utils/ghc-pwd/dist-boot/ghc-pwd dnl If special linker flags are needed to build things, then allow
dnl the user to pass them in via LDFLAGS.
changequote(, )dnl
GHC_LDFLAGS=`echo $LDFLAGS | sed 's/\(^\| \)\([^ ]\)/\1-optl\2/g'`
changequote([, ])dnl
if ! "$WithGhc" $GHC_LDFLAGS -v0 -no-user-$GHC_PACKAGE_DB_FLAG -hidir utils/ghc-pwd/dist-boot -odir utils/ghc-pwd/dist-boot -stubdir utils/ghc-pwd/dist-boot --make utils/ghc-pwd/Main.hs -o utils/ghc-pwd/dist-boot/ghc-pwd
then then
AC_MSG_ERROR([Building ghc-pwd failed]) AC_MSG_ERROR([Building ghc-pwd failed])
fi fi
...@@ -1861,6 +1891,9 @@ case "$1" in ...@@ -1861,6 +1891,9 @@ case "$1" in
mips*) mips*)
$2="mips" $2="mips"
;; ;;
powerpc64le*)
$2="powerpc64le"
;;
powerpc64*) powerpc64*)
$2="powerpc64" $2="powerpc64"
;; ;;
...@@ -2048,7 +2081,8 @@ AC_DEFUN([FIND_GCC],[ ...@@ -2048,7 +2081,8 @@ AC_DEFUN([FIND_GCC],[
$1="$CC" $1="$CC"
else else
FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL([$1], [$2], [$3]) FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL([$1], [$2], [$3])
# From Xcode 5 on, OS X command line tools do not include gcc anymore. Use clang. # From Xcode 5 on, OS X command line tools do not include gcc
# anymore. Use clang.
if test -z "$$1" if test -z "$$1"
then then
FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL([$1], [clang], [clang]) FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL([$1], [clang], [clang])
...@@ -2061,4 +2095,13 @@ AC_DEFUN([FIND_GCC],[ ...@@ -2061,4 +2095,13 @@ AC_DEFUN([FIND_GCC],[
AC_SUBST($1) AC_SUBST($1)
]) ])
AC_DEFUN([MAYBE_OVERRIDE_STAGE0],[
if test ! -z "$With_$1" -a "$CrossCompiling" != "YES"; then
AC_MSG_NOTICE([Not cross-compiling, so --with-$1 also sets $2])
$2=$With_$1
fi
])
# LocalWords: fi # LocalWords: fi
...@@ -21,9 +21,9 @@ include $(TOP)/mk/tree.mk ...@@ -21,9 +21,9 @@ include $(TOP)/mk/tree.mk
include $(TOP)/mk/config.mk include $(TOP)/mk/config.mk
ifeq "$(TEST_PREP)" "YES" ifeq "$(TEST_PREP)" "YES"
BIN_DIST_TEST_TAR_BZ2 = ../$(BIN_DIST_PREP_TAR_BZ2) BIN_DIST_TEST_TAR_COMP = ../$(BIN_DIST_PREP_TAR_COMP)
else else
BIN_DIST_TEST_TAR_BZ2 = ../$(BIN_DIST_TAR_BZ2) BIN_DIST_TEST_TAR_COMP = ../$(BIN_DIST_TAR_COMP)
endif endif
all: all:
...@@ -36,7 +36,7 @@ all: ...@@ -36,7 +36,7 @@ all:
# NB. tar has funny interpretation of filenames sometimes (thinking # NB. tar has funny interpretation of filenames sometimes (thinking
# c:/foo is a remote file), so it's safer to bzip and then pipe into # c:/foo is a remote file), so it's safer to bzip and then pipe into
# tar rather than using tar -xjf: # tar rather than using tar -xjf:
cd a/b/c/ && $(BZIP2_CMD) -cd ../../../$(BIN_DIST_TEST_TAR_BZ2) | $(TAR_CMD) -xf - cd a/b/c/ && $(TAR_COMP_CMD) -cd ../../../$(BIN_DIST_TEST_TAR_COMP) | $(TAR_CMD) -xf -
ifeq "$(Windows)" "YES" ifeq "$(Windows)" "YES"
mv a/b/c/$(BIN_DIST_NAME) $(BIN_DIST_INST_DIR) mv a/b/c/$(BIN_DIST_NAME) $(BIN_DIST_INST_DIR)
else else
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
ifeq "$(TEST_PREP)" "YES" ifeq "$(TEST_PREP)" "YES"
BIN_DIST_TEST_TAR_BZ2 = $(BIN_DIST_PREP_TAR_BZ2) BIN_DIST_TEST_TAR_COMP = $(BIN_DIST_PREP_TAR_COMP)
else else
BIN_DIST_TEST_TAR_BZ2 = $(BIN_DIST_TAR_BZ2) BIN_DIST_TEST_TAR_COMP = $(BIN_DIST_TAR_COMP)
endif endif
.PHONY: test_bindist .PHONY: test_bindist
...@@ -33,7 +33,7 @@ test_bindist: ...@@ -33,7 +33,7 @@ test_bindist:
mkdir bindisttest/a mkdir bindisttest/a
mkdir bindisttest/a/b mkdir bindisttest/a/b
mkdir bindisttest/a/b/c mkdir bindisttest/a/b/c
cd bindisttest/a/b/c/ && $(BZIP2_CMD) -cd ../../../../$(BIN_DIST_TEST_TAR_BZ2) | $(TAR_CMD) -xf - cd bindisttest/a/b/c/ && $(TAR_COMP_CMD) -cd ../../../../$(BIN_DIST_TEST_TAR_COMP) | $(TAR_CMD) -xf -
$(SHELL) bindisttest/checkBinaries.sh $(ProjectVersion) $(SHELL) bindisttest/checkBinaries.sh $(ProjectVersion)
ifeq "$(Windows_Host)" "YES" ifeq "$(Windows_Host)" "YES"
mv bindisttest/a/b/c/$(BIN_DIST_NAME) $(BIN_DIST_INST_DIR) mv bindisttest/a/b/c/$(BIN_DIST_NAME) $(BIN_DIST_INST_DIR)
......
...@@ -41,7 +41,7 @@ module Demand ( ...@@ -41,7 +41,7 @@ module Demand (
deferAfterIO, deferAfterIO,
postProcessUnsat, postProcessDmdTypeM, postProcessUnsat, postProcessDmdTypeM,
splitProdDmd, splitProdDmd_maybe, peelCallDmd, mkCallDmd, splitProdDmd_maybe, peelCallDmd, mkCallDmd,
dmdTransformSig, dmdTransformDataConSig, dmdTransformDictSelSig, dmdTransformSig, dmdTransformDataConSig, dmdTransformDictSelSig,
argOneShots, argsOneShots, argOneShots, argsOneShots,
...@@ -64,7 +64,7 @@ import BasicTypes ...@@ -64,7 +64,7 @@ import BasicTypes
import Binary import Binary
import Maybes ( orElse ) import Maybes ( orElse )
import Type ( Type ) import Type ( Type, isUnLiftedType )
import TyCon ( isNewTyCon, isClassTyCon ) import TyCon ( isNewTyCon, isClassTyCon )
import DataCon ( splitDataProductType_maybe ) import DataCon ( splitDataProductType_maybe )
\end{code} \end{code}
...@@ -198,11 +198,13 @@ seqMaybeStr Lazy = () ...@@ -198,11 +198,13 @@ seqMaybeStr Lazy = ()
seqMaybeStr (Str s) = seqStrDmd s seqMaybeStr (Str s) = seqStrDmd s
-- Splitting polymorphic demands -- Splitting polymorphic demands
splitStrProdDmd :: Int -> StrDmd -> [MaybeStr] splitStrProdDmd :: Int -> StrDmd -> Maybe [MaybeStr]
splitStrProdDmd n HyperStr = replicate n strBot splitStrProdDmd n HyperStr = Just (replicate n strBot)
splitStrProdDmd n HeadStr = replicate n strTop splitStrProdDmd n HeadStr = Just (replicate n strTop)
splitStrProdDmd n (SProd ds) = ASSERT( ds `lengthIs` n) ds splitStrProdDmd n (SProd ds) = ASSERT( ds `lengthIs` n) Just ds
splitStrProdDmd _ d@(SCall {}) = pprPanic "attempt to prod-split strictness call demand" (ppr d) splitStrProdDmd _ (SCall {}) = Nothing
-- This can happen when the programmer uses unsafeCoerce,
-- and we don't then want to crash the compiler (Trac #9208)
\end{code} \end{code}
%************************************************************************ %************************************************************************
...@@ -439,11 +441,12 @@ seqMaybeUsed (Use c u) = c `seq` seqUseDmd u ...@@ -439,11 +441,12 @@ seqMaybeUsed (Use c u) = c `seq` seqUseDmd u
seqMaybeUsed _ = () seqMaybeUsed _ = ()
-- Splitting polymorphic Maybe-Used demands -- Splitting polymorphic Maybe-Used demands
splitUseProdDmd :: Int -> UseDmd -> [MaybeUsed] splitUseProdDmd :: Int -> UseDmd -> Maybe [MaybeUsed]
splitUseProdDmd n Used = replicate n useTop splitUseProdDmd n Used = Just (replicate n useTop)
splitUseProdDmd n UHead = replicate n Abs splitUseProdDmd n UHead = Just (replicate n Abs)
splitUseProdDmd n (UProd ds) = ASSERT2( ds `lengthIs` n, ppr n $$ ppr ds ) ds splitUseProdDmd n (UProd ds) = ASSERT2( ds `lengthIs` n, text "splitUseProdDmd" $$ ppr n $$ ppr ds )
splitUseProdDmd _ d@(UCall _ _) = pprPanic "attempt to prod-split usage call demand" (ppr d) Just ds
splitUseProdDmd _ (UCall _ _) = Nothing
\end{code} \end{code}
%************************************************************************ %************************************************************************
...@@ -659,26 +662,18 @@ can be expanded to saturate a callee's arity. ...@@ -659,26 +662,18 @@ can be expanded to saturate a callee's arity.
\begin{code} \begin{code}
splitProdDmd :: Arity -> JointDmd -> [JointDmd]
splitProdDmd n (JD {strd = s, absd = u})
= mkJointDmds (split_str s) (split_abs u)
where
split_str Lazy = replicate n Lazy
split_str (Str s) = splitStrProdDmd n s
split_abs Abs = replicate n Abs
split_abs (Use _ u) = splitUseProdDmd n u
splitProdDmd_maybe :: JointDmd -> Maybe [JointDmd] splitProdDmd_maybe :: JointDmd -> Maybe [JointDmd]
-- Split a product into its components, iff there is any -- Split a product into its components, iff there is any
-- useful information to be extracted thereby -- useful information to be extracted thereby
-- The demand is not necessarily strict! -- The demand is not necessarily strict!
splitProdDmd_maybe (JD {strd = s, absd = u}) splitProdDmd_maybe (JD {strd = s, absd = u})
= case (s,u) of = case (s,u) of
(Str (SProd sx), Use _ u) -> Just (mkJointDmds sx (splitUseProdDmd (length sx) u)) (Str (SProd sx), Use _ u) | Just ux <- splitUseProdDmd (length sx) u
(Str s, Use _ (UProd ux)) -> Just (mkJointDmds (splitStrProdDmd (length ux) s) ux) -> Just (mkJointDmds sx ux)
(Lazy, Use _ (UProd ux)) -> Just (mkJointDmds (replicate (length ux) Lazy) ux) (Str s, Use _ (UProd ux)) | Just sx <- splitStrProdDmd (length ux) s
_ -> Nothing -> Just (mkJointDmds sx ux)
(Lazy, Use _ (UProd ux)) -> Just (mkJointDmds (replicate (length ux) Lazy) ux)
_ -> Nothing
\end{code} \end{code}
%************************************************************************ %************************************************************************
...@@ -1144,13 +1139,18 @@ type DeferAndUse -- Describes how to degrade a result type ...@@ -1144,13 +1139,18 @@ type DeferAndUse -- Describes how to degrade a result type
type DeferAndUseM = Maybe DeferAndUse type DeferAndUseM = Maybe DeferAndUse
-- Nothing <=> absent-ify the result type; it will never be used -- Nothing <=> absent-ify the result type; it will never be used
toCleanDmd :: Demand -> (CleanDemand, DeferAndUseM) toCleanDmd :: Demand -> Type -> (CleanDemand, DeferAndUseM)
-- See Note [Analyzing with lazy demand and lambdas] toCleanDmd (JD { strd = s, absd = u }) expr_ty
toCleanDmd (JD { strd = s, absd = u })
= case (s,u) of = case (s,u) of
(Str s', Use c u') -> (CD { sd = s', ud = u' }, Just (False, c)) (Str s', Use c u') -> -- The normal case
(Lazy, Use c u') -> (CD { sd = HeadStr, ud = u' }, Just (True, c)) (CD { sd = s', ud = u' }, Just (False, c))
(_, Abs) -> (CD { sd = HeadStr, ud = Used }, Nothing)
(Lazy, Use c u') -> -- See Note [Analyzing with lazy demand and lambdas]
(CD { sd = HeadStr, ud = u' }, Just (True, c))
(_, Abs) -- See Note [Analysing with absent demand]
| isUnLiftedType expr_ty -> (CD { sd = HeadStr, ud = Used }, Just (False, One))
| otherwise -> (CD { sd = HeadStr, ud = Used }, Nothing)
-- This is used in dmdAnalStar when post-processing -- This is used in dmdAnalStar when post-processing
-- a function's argument demand. So we only care about what -- a function's argument demand. So we only care about what
...@@ -1325,13 +1325,13 @@ cardinality analysis of the following example: ...@@ -1325,13 +1325,13 @@ cardinality analysis of the following example:
{-# NOINLINE build #-} {-# NOINLINE build #-}
build g = (g (:) [], g (:) []) build g = (g (:) [], g (:) [])
h c z = build (\x -> h c z = build (\x ->
let z1 = z ++ z let z1 = z ++ z
in if c in if c
then \y -> x (y ++ z1) then \y -> x (y ++ z1)
else \y -> x (z1 ++ y)) else \y -> x (z1 ++ y))
One can see that `build` assigns to `g` demand <L,C(C1(U))>. One can see that `build` assigns to `g` demand <L,C(C1(U))>.
Therefore, when analyzing the lambda `(\x -> ...)`, we Therefore, when analyzing the lambda `(\x -> ...)`, we
expect each lambda \y -> ... to be annotated as "one-shot" expect each lambda \y -> ... to be annotated as "one-shot"
one. Therefore (\x -> \y -> x (y ++ z)) should be analyzed with a one. Therefore (\x -> \y -> x (y ++ z)) should be analyzed with a
...@@ -1340,6 +1340,46 @@ demand <C(C(..), C(C1(U))>. ...@@ -1340,6 +1340,46 @@ demand <C(C(..), C(C1(U))>.
This is achieved by, first, converting the lazy demand L into the This is achieved by, first, converting the lazy demand L into the
strict S by the second clause of the analysis. strict S by the second clause of the analysis.
Note [Analysing with absent demand]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose we analyse an expression with demand <L,A>. The "A" means
"absent", so this expression will never be needed. What should happen?
There are several wrinkles:
* We *do* want to analyse the expression regardless.
Reason: Note [Always analyse in virgin pass]
But we can post-process the results to ignore all the usage
demands coming back. This is done by postProcessDmdTypeM.
* But in the case of an *unlifted type* we must be extra careful,
because unlifted values are evaluated even if they are not used.
Example (see Trac #9254):
f :: (() -> (# Int#, () #)) -> ()
-- Strictness signature is
-- <C(S(LS)), 1*C1(U(A,1*U()))>
-- I.e. calls k, but discards first component of result
f k = case k () of (# _, r #) -> r
g :: Int -> ()
g y = f (\n -> (# case y of I# y2 -> y2, n #))
Here f's strictness signature says (correctly) that it calls its
argument function and ignores the first component of its result.
This is correct in the sense that it'd be fine to (say) modify the
function so that always returned 0# in the first component.
But in function g, we *will* evaluate the 'case y of ...', because
it has type Int#. So 'y' will be evaluated. So we must record this
usage of 'y', else 'g' will say 'y' is absent, and will w/w so that
'y' is bound to an aBSENT_ERROR thunk.
An alternative would be to replace the 'case y of ...' with (say) 0#,
but I have not tried that. It's not a common situation, but it is
not theoretical: unsafePerformIO's implementation is very very like
'f' above.
%************************************************************************ %************************************************************************
%* * %* *
Demand signatures Demand signatures
...@@ -1461,12 +1501,12 @@ dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res)) ...@@ -1461,12 +1501,12 @@ dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res))
| otherwise -- Not saturated | otherwise -- Not saturated
= nopDmdType = nopDmdType
where where
go_str 0 dmd = Just (splitStrProdDmd arity dmd) go_str 0 dmd = splitStrProdDmd arity dmd
go_str n (SCall s') = go_str (n-1) s' go_str n (SCall s') = go_str (n-1) s'
go_str n HyperStr = go_str (n-1) HyperStr go_str n HyperStr = go_str (n-1) HyperStr
go_str _ _ = Nothing go_str _ _ = Nothing
go_abs 0 dmd = Just (splitUseProdDmd arity dmd) go_abs 0 dmd = splitUseProdDmd arity dmd
go_abs n (UCall One u') = go_abs (n-1) u' go_abs n (UCall One u') = go_abs (n-1) u'
go_abs _ _ = Nothing go_abs _ _ = Nothing
......
...@@ -125,7 +125,7 @@ is right here. ...@@ -125,7 +125,7 @@ is right here.
\begin{code} \begin{code}
wiredInIds :: [Id] wiredInIds :: [Id]
wiredInIds wiredInIds
= [lazyId] = [lazyId, dollarId]
++ errorIds -- Defined in MkCore ++ errorIds -- Defined in MkCore
++ ghcPrimIds ++ ghcPrimIds
...@@ -1040,20 +1040,32 @@ another gun with which to shoot yourself in the foot. ...@@ -1040,20 +1040,32 @@ another gun with which to shoot yourself in the foot.
\begin{code} \begin{code}
lazyIdName, unsafeCoerceName, nullAddrName, seqName, lazyIdName, unsafeCoerceName, nullAddrName, seqName,
realWorldName, voidPrimIdName, coercionTokenName, realWorldName, voidPrimIdName, coercionTokenName,
magicDictName, coerceName, proxyName :: Name magicDictName, coerceName, proxyName, dollarName :: Name
unsafeCoerceName = mkWiredInIdName gHC_PRIM (fsLit "unsafeCoerce#") unsafeCoerceIdKey unsafeCoerceId unsafeCoerceName = mkWiredInIdName gHC_PRIM (fsLit "unsafeCoerce#") unsafeCoerceIdKey unsafeCoerceId
nullAddrName = mkWiredInIdName gHC_PRIM (fsLit "nullAddr#") nullAddrIdKey nullAddrId nullAddrName = mkWiredInIdName gHC_PRIM (fsLit "nullAddr#") nullAddrIdKey nullAddrId
seqName = mkWiredInIdName gHC_PRIM (fsLit "seq") seqIdKey seqId seqName = mkWiredInIdName gHC_PRIM (fsLit "seq") seqIdKey seqId
realWorldName = mkWiredInIdName gHC_PRIM (fsLit "realWorld#") realWorldPrimIdKey realWorldPrimId realWorldName = mkWiredInIdName gHC_PRIM (fsLit "realWorld#") realWorldPrimIdKey realWorldPrimId
voidPrimIdName = mkWiredInIdName gHC_PRIM (fsLit "void#") voidPrimIdKey voidPrimId voidPrimIdName = mkWiredInIdName gHC_PRIM (fsLit "void#") voidPrimIdKey voidPrimId
lazyIdName = mkWiredInIdName gHC_MAGIC (fsLit "lazy") lazyIdKey lazyId lazyIdName = mkWiredInIdName gHC_MAGIC (fsLit "lazy") lazyIdKey lazyId
coercionTokenName = mkWiredInIdName gHC_PRIM (fsLit "coercionToken#") coercionTokenIdKey coercionTokenId coercionTokenName = mkWiredInIdName gHC_PRIM (fsLit "coercionToken#") coercionTokenIdKey coercionTokenId
magicDictName = mkWiredInIdName gHC_PRIM (fsLit "magicDict") magicDictKey magicDictId magicDictName = mkWiredInIdName gHC_PRIM (fsLit "magicDict") magicDictKey magicDictId
coerceName = mkWiredInIdName gHC_PRIM (fsLit "coerce") coerceKey coerceId coerceName = mkWiredInIdName gHC_PRIM (fsLit "coerce") coerceKey coerceId
proxyName = mkWiredInIdName gHC_PRIM (fsLit "proxy#") proxyHashKey proxyHashId proxyName = mkWiredInIdName gHC_PRIM (fsLit "proxy#") proxyHashKey proxyHashId
dollarName = mkWiredInIdName gHC_BASE (fsLit "$") dollarIdKey dollarId
\end{code} \end{code}
\begin{code} \begin{code}
dollarId :: Id -- Note [dollarId magic]
dollarId = pcMiscPrelId dollarName ty
(noCafIdInfo `setUnfoldingInfo` unf)
where
fun_ty = mkFunTy alphaTy openBetaTy
ty = mkForAllTys [alphaTyVar, openBetaTyVar] $
mkFunTy fun_ty fun_ty
unf = mkInlineUnfolding (Just 2) rhs
[f,x] = mkTemplateLocals [fun_ty, alphaTy]
rhs = mkLams [alphaTyVar, openBetaTyVar, f, x] $
App (Var f) (Var x)
------------------------------------------------ ------------------------------------------------
-- proxy# :: forall a. Proxy# a -- proxy# :: forall a. Proxy# a
...@@ -1160,6 +1172,20 @@ coerceId = pcMiscPrelId coerceName ty info ...@@ -1160,6 +1172,20 @@ coerceId = pcMiscPrelId coerceName ty info
[(DataAlt coercibleDataCon, [eq], Cast (Var x) (CoVarCo eq))] [(DataAlt coercibleDataCon, [eq], Cast (Var x) (CoVarCo eq))]
\end{code} \end{code}
Note [dollarId magic]
~~~~~~~~~~~~~~~~~~~~~
The only reason that ($) is wired in is so that its type can be
forall (a:*, b:Open). (a->b) -> a -> b
That is, the return type can be unboxed. E.g. this is OK
foo $ True where foo :: Bool -> Int#
because ($) doesn't inspect or move the result of the call to foo.
See Trac #8739.
There is a special typing rule for ($) in TcExpr, so the type of ($)
isn't looked at there, BUT Lint subsequently (and rightly) complains
if sees ($) applied to Int# (say), unless we give it a wired-in type
as we do here.
Note [Unsafe coerce magic] Note [Unsafe coerce magic]
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
We define a *primitive* We define a *primitive*
......
...@@ -51,7 +51,6 @@ module OccName ( ...@@ -51,7 +51,6 @@ module OccName (
mkTcOcc, mkTcOccFS, mkTcOcc, mkTcOccFS,
mkClsOcc, mkClsOccFS, mkClsOcc, mkClsOccFS,
mkDFunOcc, mkDFunOcc,
mkTupleOcc,
setOccNameSpace, setOccNameSpace,
demoteOccName, demoteOccName,
HasOccName(..), HasOccName(..),
...@@ -82,14 +81,12 @@ module OccName ( ...@@ -82,14 +81,12 @@ module OccName (
isTcClsNameSpace, isTvNameSpace, isDataConNameSpace, isVarNameSpace, isValNameSpace, isTcClsNameSpace, isTvNameSpace, isDataConNameSpace, isVarNameSpace, isValNameSpace,
isTupleOcc_maybe,
-- * The 'OccEnv' type -- * The 'OccEnv' type
OccEnv, emptyOccEnv, unitOccEnv, extendOccEnv, mapOccEnv, OccEnv, emptyOccEnv, unitOccEnv, extendOccEnv, mapOccEnv,
lookupOccEnv, mkOccEnv, mkOccEnv_C, extendOccEnvList, elemOccEnv, lookupOccEnv, mkOccEnv, mkOccEnv_C, extendOccEnvList, elemOccEnv,
occEnvElts, foldOccEnv, plusOccEnv, plusOccEnv_C, extendOccEnv_C, occEnvElts, foldOccEnv, plusOccEnv, plusOccEnv_C, extendOccEnv_C,
extendOccEnv_Acc, filterOccEnv, delListFromOccEnv, delFromOccEnv, extendOccEnv_Acc, filterOccEnv, delListFromOccEnv, delFromOccEnv,
alterOccEnv, alterOccEnv, pprOccEnv,
-- * The 'OccSet' type -- * The 'OccSet' type
OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet,
...@@ -108,7 +105,6 @@ module OccName ( ...@@ -108,7 +105,6 @@ module OccName (
import Util import Util
import Unique import Unique
import BasicTypes
import DynFlags import DynFlags
import UniqFM import UniqFM
import UniqSet import UniqSet
...@@ -261,6 +257,11 @@ instance Data OccName where ...@@ -261,6 +257,11 @@ instance Data OccName where
instance Outputable OccName where instance Outputable OccName where
ppr = pprOccName ppr = pprOccName
instance OutputableBndr OccName where
pprBndr _ = ppr
pprInfixOcc n = pprInfixVar (isSymOcc n) (ppr n)
pprPrefixOcc n = pprPrefixVar (isSymOcc n) (ppr n)
pprOccName :: OccName -> SDoc pprOccName :: OccName -> SDoc
pprOccName (OccName sp occ) pprOccName (OccName sp occ)
= getPprStyle $ \ sty -> = getPprStyle $ \ sty ->
...@@ -415,7 +416,10 @@ filterOccEnv x (A y) = A $ filterUFM x y ...@@ -415,7 +416,10 @@ filterOccEnv x (A y) = A $ filterUFM x y
alterOccEnv fn (A y) k = A $ alterUFM fn y k alterOccEnv fn (A y) k = A $ alterUFM fn y k
instance Outputable a => Outputable (OccEnv a) where instance Outputable a => Outputable (OccEnv a) where
ppr (A x) = ppr x ppr x = pprOccEnv ppr x
pprOccEnv :: (a -> SDoc) -> OccEnv a -> SDoc
pprOccEnv ppr_elt (A env) = pprUniqFM ppr_elt env
type OccSet = UniqSet OccName type OccSet = UniqSet OccName
...@@ -496,7 +500,7 @@ isDataSymOcc _ = False ...@@ -496,7 +500,7 @@ isDataSymOcc _ = False
-- it is a data constructor or variable or whatever) -- it is a data constructor or variable or whatever)
isSymOcc :: OccName -> Bool isSymOcc :: OccName -> Bool
isSymOcc (OccName DataName s) = isLexConSym s isSymOcc (OccName DataName s) = isLexConSym s
isSymOcc (OccName TcClsName s) = isLexConSym s || isLexVarSym s isSymOcc (OccName TcClsName s) = isLexSym s
isSymOcc (OccName VarName s) = isLexSym s isSymOcc (OccName VarName s) = isLexSym s
isSymOcc (OccName TvName s) = isLexSym s isSymOcc (OccName TvName s) = isLexSym s
-- Pretty inefficient! -- Pretty inefficient!
...@@ -805,55 +809,6 @@ tidyOccName env occ@(OccName occ_sp fs) ...@@ -805,55 +809,6 @@ tidyOccName env occ@(OccName occ_sp fs)
new_fs = mkFastString (base ++ show n) new_fs = mkFastString (base ++ show n)
\end{code} \end{code}
%************************************************************************
%* *
Stuff for dealing with tuples
%* *
%************************************************************************
\begin{code}
mkTupleOcc :: NameSpace -> TupleSort -> Arity -> OccName
mkTupleOcc ns sort ar = OccName ns (mkFastString str)
where
-- no need to cache these, the caching is done in the caller
-- (TysWiredIn.mk_tuple)
str = case sort of
UnboxedTuple -> '(' : '#' : commas ++ "#)"
BoxedTuple -> '(' : commas ++ ")"
ConstraintTuple -> '(' : commas ++ ")"
-- Cute hack: reuse the standard tuple OccNames (and hence code)
-- for fact tuples, but give them different Uniques so they are not equal.
--
-- You might think that this will go wrong because isTupleOcc_maybe won't
-- be able to tell the difference between boxed tuples and fact tuples. BUT:
-- 1. Fact tuples never occur directly in user code, so it doesn't matter
-- that we can't detect them in Orig OccNames originating from the user
-- programs (or those built by setRdrNameSpace used on an Exact tuple Name)
-- 2. Interface files have a special representation for tuple *occurrences*
-- in IfaceTyCons, their workers (in IfaceSyn) and their DataCons (in case
-- alternatives). Thus we don't rely on the OccName to figure out what kind
-- of tuple an occurrence was trying to use in these situations.
-- 3. We *don't* represent tuple data type declarations specially, so those
-- are still turned into wired-in names via isTupleOcc_maybe. But that's OK
-- because we don't actually need to declare fact tuples thanks to this hack.
--
-- So basically any OccName like (,,) flowing to isTupleOcc_maybe will always
-- refer to the standard boxed tuple. Cool :-)
commas = take (ar-1) (repeat ',')
isTupleOcc_maybe :: OccName -> Maybe (NameSpace, TupleSort, Arity)
-- Tuples are special, because there are so many of them!
isTupleOcc_maybe (OccName ns fs)
= case unpackFS fs of
'(':'#':',':rest -> Just (ns, UnboxedTuple, 2 + count_commas rest)
'(':',':rest -> Just (ns, BoxedTuple, 2 + count_commas rest)
_other -> Nothing
where
count_commas (',':rest) = 1 + count_commas rest
count_commas _ = 0
\end{code}
%************************************************************************ %************************************************************************
%* * %* *
\subsection{Lexical categories} \subsection{Lexical categories}
...@@ -863,6 +818,15 @@ isTupleOcc_maybe (OccName ns fs) ...@@ -863,6 +818,15 @@ isTupleOcc_maybe (OccName ns fs)
These functions test strings to see if they fit the lexical categories These functions test strings to see if they fit the lexical categories
defined in the Haskell report. defined in the Haskell report.
Note [Classification of generated names]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some names generated for internal use can show up in debugging output,
e.g. when using -ddump-simpl. These generated names start with a $
but should still be pretty-printed using prefix notation. We make sure
this is the case in isLexVarSym by only classifying a name as a symbol
if all its characters are symbols, not just its first one.
\begin{code} \begin{code}
isLexCon, isLexVar, isLexId, isLexSym :: FastString -> Bool isLexCon, isLexVar, isLexId, isLexSym :: FastString -> Bool
isLexConId, isLexConSym, isLexVarId, isLexVarSym :: FastString -> Bool isLexConId, isLexConSym, isLexVarId, isLexVarSym :: FastString -> Bool
...@@ -889,19 +853,23 @@ isLexConSym cs -- Infix type or data constructors ...@@ -889,19 +853,23 @@ isLexConSym cs -- Infix type or data constructors
| cs == (fsLit "->") = True | cs == (fsLit "->") = True
| otherwise = startsConSym (headFS cs) | otherwise = startsConSym (headFS cs)
isLexVarSym cs -- Infix identifiers isLexVarSym fs -- Infix identifiers e.g. "+"
| nullFS cs = False -- e.g. "+" = case (if nullFS fs then [] else unpackFS fs) of
| otherwise = startsVarSym (headFS cs) [] -> False
(c:cs) -> startsVarSym c && all isVarSymChar cs
------------- -------------
startsVarSym, startsVarId, startsConSym, startsConId :: Char -> Bool startsVarSym, startsVarId, startsConSym, startsConId :: Char -> Bool
startsVarSym c = isSymbolASCII c || (ord c > 0x7f && isSymbol c) -- Infix Ids startsVarSym c = isSymbolASCII c || (ord c > 0x7f && isSymbol c) -- Infix Ids
startsConSym c = c == ':' -- Infix data constructors startsConSym c = c == ':' -- Infix data constructors
startsVarId c = isLower c || c == '_' -- Ordinary Ids startsVarId c = isLower c || c == '_' -- Ordinary Ids
startsConId c = isUpper c || c == '(' -- Ordinary type constructors and data constructors startsConId c = isUpper c || c == '(' -- Ordinary type constructors and data constructors
isSymbolASCII :: Char -> Bool isSymbolASCII :: Char -> Bool
isSymbolASCII c = c `elem` "!#$%&*+./<=>?@\\^|~-" isSymbolASCII c = c `elem` "!#$%&*+./<=>?@\\^|~-"
isVarSymChar :: Char -> Bool
isVarSymChar c = c == ':' || startsVarSym c
\end{code} \end{code}
%************************************************************************ %************************************************************************
......
...@@ -12,7 +12,7 @@ module PatSyn ( ...@@ -12,7 +12,7 @@ module PatSyn (
-- ** Type deconstruction -- ** Type deconstruction
patSynId, patSynType, patSynArity, patSynIsInfix, patSynId, patSynType, patSynArity, patSynIsInfix,
patSynArgs, patSynArgTys, patSynTyDetails, patSynArgs, patSynTyDetails,
patSynWrapper, patSynMatcher, patSynWrapper, patSynMatcher,
patSynExTyVars, patSynSig, patSynInstArgTys patSynExTyVars, patSynSig, patSynInstArgTys
) where ) where
...@@ -37,8 +37,8 @@ import Data.Function ...@@ -37,8 +37,8 @@ import Data.Function
\end{code} \end{code}
Pattern synonym representation Note [Pattern synonym representation]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider the following pattern synonym declaration Consider the following pattern synonym declaration
pattern P x = MkT [x] (Just 42) pattern P x = MkT [x] (Just 42)
...@@ -58,15 +58,49 @@ with the following typeclass constraints: ...@@ -58,15 +58,49 @@ with the following typeclass constraints:
In this case, the fields of MkPatSyn will be set as follows: In this case, the fields of MkPatSyn will be set as follows:
psArgs = [x :: b] psArgs = [b]
psArity = 1 psArity = 1
psInfix = False psInfix = False
psUnivTyVars = [t] psUnivTyVars = [t]
psExTyVars = [b] psExTyVars = [b]
psTheta = ((Show (Maybe t), Ord b), (Eq t, Num t)) psProvTheta = (Show (Maybe t), Ord b)
psReqTheta = (Eq t, Num t)
psOrigResTy = T (Maybe t) psOrigResTy = T (Maybe t)
Note [Matchers and wrappers for pattern synonyms]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For each pattern synonym, we generate a single matcher function which
implements the actual matching. For the above example, the matcher
will have type:
$mP :: forall r t. (Eq t, Num t)
=> T (Maybe t)
-> (forall b. (Show (Maybe t), Ord b) => b -> r)
-> r
-> r
with the following implementation:
$mP @r @t $dEq $dNum scrut cont fail = case scrut of
MkT @b $dShow $dOrd [x] (Just 42) -> cont @b $dShow $dOrd x
_ -> fail
For *bidirectional* pattern synonyms, we also generate a single wrapper
function which implements the pattern synonym in an expression
context. For our running example, it will be:
$WP :: forall t b. (Show (Maybe t), Ord b, Eq t, Num t)
=> b -> T (Maybe t)
$WP x = MkT [x] (Just 42)
NB: the existential/universal and required/provided split does not
apply to the wrapper since you are only putting stuff in, not getting
stuff out.
Injectivity of bidirectional pattern synonyms is checked in
tcPatToExpr which walks the pattern and returns its corresponding
expression when available.
%************************************************************************ %************************************************************************
%* * %* *
...@@ -76,21 +110,36 @@ In this case, the fields of MkPatSyn will be set as follows: ...@@ -76,21 +110,36 @@ In this case, the fields of MkPatSyn will be set as follows:
\begin{code} \begin{code}
-- | A pattern synonym -- | A pattern synonym
-- See Note [Pattern synonym representation]
data PatSyn data PatSyn
= MkPatSyn { = MkPatSyn {
psId :: Id, psId :: Id,
psUnique :: Unique, -- Cached from Name psUnique :: Unique, -- Cached from Name
psMatcher :: Id,
psWrapper :: Maybe Id, psArgs :: [Type],
psArity :: Arity, -- == length psArgs
psInfix :: Bool, -- True <=> declared infix
psArgs :: [Var], psUnivTyVars :: [TyVar], -- Universially-quantified type variables
psArity :: Arity, -- == length psArgs psExTyVars :: [TyVar], -- Existentially-quantified type vars
psInfix :: Bool, -- True <=> declared infix psProvTheta :: ThetaType, -- Provided dictionaries
psReqTheta :: ThetaType, -- Required dictionaries
psOrigResTy :: Type,
psUnivTyVars :: [TyVar], -- Universially-quantified type variables -- See Note [Matchers and wrappers for pattern synonyms]
psExTyVars :: [TyVar], -- Existentially-quantified type vars psMatcher :: Id,
psTheta :: (ThetaType, ThetaType), -- Provided and required dictionaries -- Matcher function, of type
psOrigResTy :: Type -- forall r univ_tvs. req_theta
-- => res_ty
-- -> (forall ex_tvs. prov_theta -> arg_tys -> r)
-- -> r -> r
psWrapper :: Maybe Id
-- Nothing => uni-directional pattern synonym
-- Just wid => bi-direcitonal
-- Wrapper function, of type
-- forall univ_tvs, ex_tvs. (prov_theta, req_theta)
-- => arg_tys -> res_ty
} }
deriving Data.Typeable.Typeable deriving Data.Typeable.Typeable
\end{code} \end{code}
...@@ -144,7 +193,7 @@ instance Data.Data PatSyn where ...@@ -144,7 +193,7 @@ instance Data.Data PatSyn where
-- | Build a new pattern synonym -- | Build a new pattern synonym
mkPatSyn :: Name mkPatSyn :: Name
-> Bool -- ^ Is the pattern synonym declared infix? -> Bool -- ^ Is the pattern synonym declared infix?
-> [Var] -- ^ Original arguments -> [Type] -- ^ Original arguments
-> [TyVar] -- ^ Universially-quantified type variables -> [TyVar] -- ^ Universially-quantified type variables
-> [TyVar] -- ^ Existentially-quantified type variables -> [TyVar] -- ^ Existentially-quantified type variables
-> ThetaType -- ^ Wanted dicts -> ThetaType -- ^ Wanted dicts
...@@ -160,7 +209,7 @@ mkPatSyn name declared_infix orig_args ...@@ -160,7 +209,7 @@ mkPatSyn name declared_infix orig_args
matcher wrapper matcher wrapper
= MkPatSyn {psId = id, psUnique = getUnique name, = MkPatSyn {psId = id, psUnique = getUnique name,
psUnivTyVars = univ_tvs, psExTyVars = ex_tvs, psUnivTyVars = univ_tvs, psExTyVars = ex_tvs,
psTheta = (prov_theta, req_theta), psProvTheta = prov_theta, psReqTheta = req_theta,
psInfix = declared_infix, psInfix = declared_infix,
psArgs = orig_args, psArgs = orig_args,
psArity = length orig_args, psArity = length orig_args,
...@@ -170,7 +219,7 @@ mkPatSyn name declared_infix orig_args ...@@ -170,7 +219,7 @@ mkPatSyn name declared_infix orig_args
where where
pat_ty = mkSigmaTy univ_tvs req_theta $ pat_ty = mkSigmaTy univ_tvs req_theta $
mkSigmaTy ex_tvs prov_theta $ mkSigmaTy ex_tvs prov_theta $
mkFunTys (map varType orig_args) orig_res_ty mkFunTys orig_args orig_res_ty
id = mkLocalId name pat_ty id = mkLocalId name pat_ty
\end{code} \end{code}
...@@ -190,22 +239,21 @@ patSynIsInfix = psInfix ...@@ -190,22 +239,21 @@ patSynIsInfix = psInfix
patSynArity :: PatSyn -> Arity patSynArity :: PatSyn -> Arity
patSynArity = psArity patSynArity = psArity
patSynArgs :: PatSyn -> [Var] patSynArgs :: PatSyn -> [Type]
patSynArgs = psArgs patSynArgs = psArgs
patSynArgTys :: PatSyn -> [Type]
patSynArgTys = map varType . patSynArgs
patSynTyDetails :: PatSyn -> HsPatSynDetails Type patSynTyDetails :: PatSyn -> HsPatSynDetails Type
patSynTyDetails ps = case (patSynIsInfix ps, patSynArgTys ps) of patSynTyDetails ps = case (patSynIsInfix ps, patSynArgs ps) of
(True, [left, right]) -> InfixPatSyn left right (True, [left, right]) -> InfixPatSyn left right
(_, tys) -> PrefixPatSyn tys (_, tys) -> PrefixPatSyn tys
patSynExTyVars :: PatSyn -> [TyVar] patSynExTyVars :: PatSyn -> [TyVar]
patSynExTyVars = psExTyVars patSynExTyVars = psExTyVars
patSynSig :: PatSyn -> ([TyVar], [TyVar], (ThetaType, ThetaType)) patSynSig :: PatSyn -> ([TyVar], [TyVar], ThetaType, ThetaType)
patSynSig ps = (psUnivTyVars ps, psExTyVars ps, psTheta ps) patSynSig (MkPatSyn { psUnivTyVars = univ_tvs, psExTyVars = ex_tvs
, psProvTheta = prov, psReqTheta = req })
= (univ_tvs, ex_tvs, prov, req)
patSynWrapper :: PatSyn -> Maybe Id patSynWrapper :: PatSyn -> Maybe Id
patSynWrapper = psWrapper patSynWrapper = psWrapper
...@@ -217,9 +265,8 @@ patSynInstArgTys :: PatSyn -> [Type] -> [Type] ...@@ -217,9 +265,8 @@ patSynInstArgTys :: PatSyn -> [Type] -> [Type]
patSynInstArgTys ps inst_tys patSynInstArgTys ps inst_tys
= ASSERT2( length tyvars == length inst_tys = ASSERT2( length tyvars == length inst_tys
, ptext (sLit "patSynInstArgTys") <+> ppr ps $$ ppr tyvars $$ ppr inst_tys ) , ptext (sLit "patSynInstArgTys") <+> ppr ps $$ ppr tyvars $$ ppr inst_tys )
map (substTyWith tyvars inst_tys) arg_tys map (substTyWith tyvars inst_tys) (psArgs ps)
where where
(univ_tvs, ex_tvs, _) = patSynSig ps (univ_tvs, ex_tvs, _, _) = patSynSig ps
arg_tys = map varType (psArgs ps)
tyvars = univ_tvs ++ ex_tvs tyvars = univ_tvs ++ ex_tvs
\end{code} \end{code}
...@@ -331,49 +331,71 @@ instance Ord RdrName where ...@@ -331,49 +331,71 @@ instance Ord RdrName where
-- It is keyed by OccName, because we never use it for qualified names -- It is keyed by OccName, because we never use it for qualified names
-- We keep the current mapping, *and* the set of all Names in scope -- We keep the current mapping, *and* the set of all Names in scope
-- Reason: see Note [Splicing Exact Names] in RnEnv -- Reason: see Note [Splicing Exact Names] in RnEnv
type LocalRdrEnv = (OccEnv Name, NameSet) data LocalRdrEnv = LRE { lre_env :: OccEnv Name
, lre_in_scope :: NameSet }
instance Outputable LocalRdrEnv where
ppr (LRE {lre_env = env, lre_in_scope = ns})
= hang (ptext (sLit "LocalRdrEnv {"))
2 (vcat [ ptext (sLit "env =") <+> pprOccEnv ppr_elt env
, ptext (sLit "in_scope =") <+> braces (pprWithCommas ppr (nameSetToList ns))
] <+> char '}')
where
ppr_elt name = parens (ppr (getUnique (nameOccName name))) <+> ppr name
-- So we can see if the keys line up correctly
emptyLocalRdrEnv :: LocalRdrEnv emptyLocalRdrEnv :: LocalRdrEnv
emptyLocalRdrEnv = (emptyOccEnv, emptyNameSet) emptyLocalRdrEnv = LRE { lre_env = emptyOccEnv, lre_in_scope = emptyNameSet }
extendLocalRdrEnv :: LocalRdrEnv -> Name -> LocalRdrEnv extendLocalRdrEnv :: LocalRdrEnv -> Name -> LocalRdrEnv
-- The Name should be a non-top-level thing -- The Name should be a non-top-level thing
extendLocalRdrEnv (env, ns) name extendLocalRdrEnv (LRE { lre_env = env, lre_in_scope = ns }) name
= WARN( isExternalName name, ppr name ) = WARN( isExternalName name, ppr name )
( extendOccEnv env (nameOccName name) name LRE { lre_env = extendOccEnv env (nameOccName name) name
, addOneToNameSet ns name , lre_in_scope = addOneToNameSet ns name }
)
extendLocalRdrEnvList :: LocalRdrEnv -> [Name] -> LocalRdrEnv extendLocalRdrEnvList :: LocalRdrEnv -> [Name] -> LocalRdrEnv
extendLocalRdrEnvList (env, ns) names extendLocalRdrEnvList (LRE { lre_env = env, lre_in_scope = ns }) names
= WARN( any isExternalName names, ppr names ) = WARN( any isExternalName names, ppr names )
( extendOccEnvList env [(nameOccName n, n) | n <- names] LRE { lre_env = extendOccEnvList env [(nameOccName n, n) | n <- names]
, addListToNameSet ns names , lre_in_scope = addListToNameSet ns names }
)
lookupLocalRdrEnv :: LocalRdrEnv -> RdrName -> Maybe Name lookupLocalRdrEnv :: LocalRdrEnv -> RdrName -> Maybe Name
lookupLocalRdrEnv (env, _) (Unqual occ) = lookupOccEnv env occ lookupLocalRdrEnv (LRE { lre_env = env }) (Unqual occ) = lookupOccEnv env occ
lookupLocalRdrEnv _ _ = Nothing lookupLocalRdrEnv _ _ = Nothing
lookupLocalRdrOcc :: LocalRdrEnv -> OccName -> Maybe Name lookupLocalRdrOcc :: LocalRdrEnv -> OccName -> Maybe Name
lookupLocalRdrOcc (env, _) occ = lookupOccEnv env occ lookupLocalRdrOcc (LRE { lre_env = env }) occ = lookupOccEnv env occ
elemLocalRdrEnv :: RdrName -> LocalRdrEnv -> Bool elemLocalRdrEnv :: RdrName -> LocalRdrEnv -> Bool
elemLocalRdrEnv rdr_name (env, _) elemLocalRdrEnv rdr_name (LRE { lre_env = env, lre_in_scope = ns })
| isUnqual rdr_name = rdrNameOcc rdr_name `elemOccEnv` env = case rdr_name of
| otherwise = False Unqual occ -> occ `elemOccEnv` env
Exact name -> name `elemNameSet` ns -- See Note [Local bindings with Exact Names]
Qual {} -> False
Orig {} -> False
localRdrEnvElts :: LocalRdrEnv -> [Name] localRdrEnvElts :: LocalRdrEnv -> [Name]
localRdrEnvElts (env, _) = occEnvElts env localRdrEnvElts (LRE { lre_env = env }) = occEnvElts env
inLocalRdrEnvScope :: Name -> LocalRdrEnv -> Bool inLocalRdrEnvScope :: Name -> LocalRdrEnv -> Bool
-- This is the point of the NameSet -- This is the point of the NameSet
inLocalRdrEnvScope name (_, ns) = name `elemNameSet` ns inLocalRdrEnvScope name (LRE { lre_in_scope = ns }) = name `elemNameSet` ns
delLocalRdrEnvList :: LocalRdrEnv -> [OccName] -> LocalRdrEnv delLocalRdrEnvList :: LocalRdrEnv -> [OccName] -> LocalRdrEnv
delLocalRdrEnvList (env, ns) occs = (delListFromOccEnv env occs, ns) delLocalRdrEnvList (LRE { lre_env = env, lre_in_scope = ns }) occs
= LRE { lre_env = delListFromOccEnv env occs
, lre_in_scope = ns }
\end{code} \end{code}
Note [Local bindings with Exact Names]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With Template Haskell we can make local bindings that have Exact Names.
Computing shadowing etc may use elemLocalRdrEnv (at least it certainly
does so in RnTpes.bindHsTyVars), so for an Exact Name we must consult
the in-scope-name-set.
%************************************************************************ %************************************************************************
%* * %* *
GlobalRdrEnv GlobalRdrEnv
......
...@@ -876,6 +876,8 @@ labelDynamic dflags this_pkg this_mod lbl = ...@@ -876,6 +876,8 @@ labelDynamic dflags this_pkg this_mod lbl =
PlainModuleInitLabel m -> not (gopt Opt_Static dflags) && this_pkg /= (modulePackageId m) PlainModuleInitLabel m -> not (gopt Opt_Static dflags) && this_pkg /= (modulePackageId m)
HpcTicksLabel m -> not (gopt Opt_Static dflags) && this_pkg /= (modulePackageId m)
-- Note that DynamicLinkerLabels do NOT require dynamic linking themselves. -- Note that DynamicLinkerLabels do NOT require dynamic linking themselves.
_ -> False _ -> False
where os = platformOS (targetPlatform dflags) where os = platformOS (targetPlatform dflags)
......
...@@ -450,25 +450,27 @@ in TcGenDeriv.) -} ...@@ -450,25 +450,27 @@ in TcGenDeriv.) -}
whether or not it has free variables, and whether we're running whether or not it has free variables, and whether we're running
sequentially or in parallel. sequentially or in parallel.
Closure Node Argument Enter Closure Node Argument Enter
Characteristics Par Req'd Passing Via Characteristics Par Req'd Passing Via
------------------------------------------------------------------------------- ---------------------------------------------------------------------------
Unknown & no & yes & stack & node Unknown & no & yes & stack & node
Known fun (>1 arg), no fvs & no & no & registers & fast entry (enough args) Known fun (>1 arg), no fvs & no & no & registers & fast entry (enough args)
& slow entry (otherwise) & slow entry (otherwise)
Known fun (>1 arg), fvs & no & yes & registers & fast entry (enough args) Known fun (>1 arg), fvs & no & yes & registers & fast entry (enough args)
0 arg, no fvs \r,\s & no & no & n/a & direct entry 0 arg, no fvs \r,\s & no & no & n/a & direct entry
0 arg, no fvs \u & no & yes & n/a & node 0 arg, no fvs \u & no & yes & n/a & node
0 arg, fvs \r,\s & no & yes & n/a & direct entry 0 arg, fvs \r,\s,selector & no & yes & n/a & node
0 arg, fvs \u & no & yes & n/a & node 0 arg, fvs \r,\s & no & yes & n/a & direct entry
Unknown & yes & yes & stack & node 0 arg, fvs \u & no & yes & n/a & node
Known fun (>1 arg), no fvs & yes & no & registers & fast entry (enough args) Unknown & yes & yes & stack & node
& slow entry (otherwise) Known fun (>1 arg), no fvs & yes & no & registers & fast entry (enough args)
Known fun (>1 arg), fvs & yes & yes & registers & node & slow entry (otherwise)
0 arg, no fvs \r,\s & yes & no & n/a & direct entry Known fun (>1 arg), fvs & yes & yes & registers & node
0 arg, no fvs \u & yes & yes & n/a & node 0 arg, fvs \r,\s,selector & yes & yes & n/a & node
0 arg, fvs \r,\s & yes & yes & n/a & node 0 arg, no fvs \r,\s & yes & no & n/a & direct entry
0 arg, fvs \u & yes & yes & n/a & node 0 arg, no fvs \u & yes & yes & n/a & node
0 arg, fvs \r,\s & yes & yes & n/a & node
0 arg, fvs \u & yes & yes & n/a & node
When black-holing, single-entry closures could also be entered via node When black-holing, single-entry closures could also be entered via node
(rather than directly) to catch double-entry. -} (rather than directly) to catch double-entry. -}
...@@ -519,7 +521,8 @@ getCallMethod dflags _name _ lf_info _n_args _cg_loc _self_loop_info ...@@ -519,7 +521,8 @@ getCallMethod dflags _name _ lf_info _n_args _cg_loc _self_loop_info
-- fetched since we allocated it. -- fetched since we allocated it.
EnterIt EnterIt
getCallMethod dflags name id (LFReEntrant _ arity _ _) n_args _cg_loc _self_loop_info getCallMethod dflags name id (LFReEntrant _ arity _ _) n_args _cg_loc
_self_loop_info
| n_args == 0 = ASSERT( arity /= 0 ) | n_args == 0 = ASSERT( arity /= 0 )
ReturnIt -- No args at all ReturnIt -- No args at all
| n_args < arity = SlowCall -- Not enough args | n_args < arity = SlowCall -- Not enough args
...@@ -531,7 +534,8 @@ getCallMethod _ _name _ LFUnLifted n_args _cg_loc _self_loop_info ...@@ -531,7 +534,8 @@ getCallMethod _ _name _ LFUnLifted n_args _cg_loc _self_loop_info
getCallMethod _ _name _ (LFCon _) n_args _cg_loc _self_loop_info getCallMethod _ _name _ (LFCon _) n_args _cg_loc _self_loop_info
= ASSERT( n_args == 0 ) ReturnIt = ASSERT( n_args == 0 ) ReturnIt
getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun) n_args _cg_loc _self_loop_info getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun)
n_args _cg_loc _self_loop_info
| is_fun -- it *might* be a function, so we must "call" it (which is always safe) | is_fun -- it *might* be a function, so we must "call" it (which is always safe)
= SlowCall -- We cannot just enter it [in eval/apply, the entry code = SlowCall -- We cannot just enter it [in eval/apply, the entry code
-- is the fast-entry code] -- is the fast-entry code]
...@@ -544,6 +548,12 @@ getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun) n_args ...@@ -544,6 +548,12 @@ getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun) n_args
of jumping directly to the entry code is still valid. --SDM of jumping directly to the entry code is still valid. --SDM
-} -}
= EnterIt = EnterIt
-- even a non-updatable selector thunk can be updated by the garbage
-- collector, so we must enter it. (#8817)
| SelectorThunk{} <- std_form_info
= EnterIt
-- We used to have ASSERT( n_args == 0 ), but actually it is -- We used to have ASSERT( n_args == 0 ), but actually it is
-- possible for the optimiser to generate -- possible for the optimiser to generate
-- let bot :: Int = error Int "urk" -- let bot :: Int = error Int "urk"
...@@ -553,7 +563,8 @@ getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun) n_args ...@@ -553,7 +563,8 @@ getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun) n_args
| otherwise -- Jump direct to code for single-entry thunks | otherwise -- Jump direct to code for single-entry thunks
= ASSERT( n_args == 0 ) = ASSERT( n_args == 0 )
DirectEntry (thunkEntryLabel dflags name (idCafInfo id) std_form_info updatable) 0 DirectEntry (thunkEntryLabel dflags name (idCafInfo id) std_form_info
updatable) 0
getCallMethod _ _name _ (LFUnknown True) _n_arg _cg_locs _self_loop_info getCallMethod _ _name _ (LFUnknown True) _n_arg _cg_locs _self_loop_info
= SlowCall -- might be a function = SlowCall -- might be a function
...@@ -562,7 +573,8 @@ getCallMethod _ name _ (LFUnknown False) n_args _cg_loc _self_loop_info ...@@ -562,7 +573,8 @@ getCallMethod _ name _ (LFUnknown False) n_args _cg_loc _self_loop_info
= ASSERT2( n_args == 0, ppr name <+> ppr n_args ) = ASSERT2( n_args == 0, ppr name <+> ppr n_args )
EnterIt -- Not a function EnterIt -- Not a function
getCallMethod _ _name _ LFLetNoEscape _n_args (LneLoc blk_id lne_regs) _self_loop_info getCallMethod _ _name _ LFLetNoEscape _n_args (LneLoc blk_id lne_regs)
_self_loop_info
= JumpToIt blk_id lne_regs = JumpToIt blk_id lne_regs
getCallMethod _ _ _ _ _ _ _ = panic "Unknown call method" getCallMethod _ _ _ _ _ _ _ = panic "Unknown call method"
......
...@@ -19,7 +19,6 @@ module CoreLint ( lintCoreBindings, lintUnfolding, lintExpr ) where ...@@ -19,7 +19,6 @@ module CoreLint ( lintCoreBindings, lintUnfolding, lintExpr ) where
#include "HsVersions.h" #include "HsVersions.h"
import Demand
import CoreSyn import CoreSyn
import CoreFVs import CoreFVs
import CoreUtils import CoreUtils
...@@ -239,9 +238,13 @@ lintSingleBinding top_lvl_flag rec_flag (binder,rhs) ...@@ -239,9 +238,13 @@ lintSingleBinding top_lvl_flag rec_flag (binder,rhs)
-- Check whether arity and demand type are consistent (only if demand analysis -- Check whether arity and demand type are consistent (only if demand analysis
-- already happened) -- already happened)
; checkL (case dmdTy of --
StrictSig dmd_ty -> idArity binder >= dmdTypeDepth dmd_ty || exprIsTrivial rhs) -- Note (Apr 2014): this is actually ok. See Note [Demand analysis for trivial right-hand sides]
(mkArityMsg binder) -- in DmdAnal. After eta-expansion in CorePrep the rhs is no longer trivial.
-- ; let dmdTy = idStrictness binder
-- ; checkL (case dmdTy of
-- StrictSig dmd_ty -> idArity binder >= dmdTypeDepth dmd_ty || exprIsTrivial rhs)
-- (mkArityMsg binder)
; lintIdUnfolding binder binder_ty (idUnfolding binder) } ; lintIdUnfolding binder binder_ty (idUnfolding binder) }
...@@ -249,7 +252,6 @@ lintSingleBinding top_lvl_flag rec_flag (binder,rhs) ...@@ -249,7 +252,6 @@ lintSingleBinding top_lvl_flag rec_flag (binder,rhs)
-- the unfolding is a SimplifiableCoreExpr. Give up for now. -- the unfolding is a SimplifiableCoreExpr. Give up for now.
where where
binder_ty = idType binder binder_ty = idType binder
dmdTy = idStrictness binder
bndr_vars = varSetElems (idFreeVars binder) bndr_vars = varSetElems (idFreeVars binder)
-- If you edit this function, you may need to update the GHC formalism -- If you edit this function, you may need to update the GHC formalism
...@@ -854,6 +856,9 @@ lintCoercion co@(TyConAppCo r tc cos) ...@@ -854,6 +856,9 @@ lintCoercion co@(TyConAppCo r tc cos)
; checkRole co2 r r2 ; checkRole co2 r r2
; return (rk, mkFunTy s1 s2, mkFunTy t1 t2, r) } ; return (rk, mkFunTy s1 s2, mkFunTy t1 t2, r) }
| Just {} <- synTyConDefn_maybe tc
= failWithL (ptext (sLit "Synonym in TyConAppCo:") <+> ppr co)
| otherwise | otherwise
= do { (ks,ss,ts,rs) <- mapAndUnzip4M lintCoercion cos = do { (ks,ss,ts,rs) <- mapAndUnzip4M lintCoercion cos
; rk <- lint_co_app co (tyConKind tc) (ss `zip` ks) ; rk <- lint_co_app co (tyConKind tc) (ss `zip` ks)
...@@ -1421,6 +1426,7 @@ mkKindErrMsg tyvar arg_ty ...@@ -1421,6 +1426,7 @@ mkKindErrMsg tyvar arg_ty
hang (ptext (sLit "Arg type:")) hang (ptext (sLit "Arg type:"))
4 (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))] 4 (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty))]
{- Not needed now
mkArityMsg :: Id -> MsgDoc mkArityMsg :: Id -> MsgDoc
mkArityMsg binder mkArityMsg binder
= vcat [hsep [ptext (sLit "Demand type has"), = vcat [hsep [ptext (sLit "Demand type has"),
...@@ -1433,7 +1439,7 @@ mkArityMsg binder ...@@ -1433,7 +1439,7 @@ mkArityMsg binder
] ]
where (StrictSig dmd_ty) = idStrictness binder where (StrictSig dmd_ty) = idStrictness binder
-}
mkCastErr :: CoreExpr -> Coercion -> Type -> Type -> MsgDoc mkCastErr :: CoreExpr -> Coercion -> Type -> Type -> MsgDoc
mkCastErr expr co from_ty expr_ty mkCastErr expr co from_ty expr_ty
= vcat [ptext (sLit "From-type of Cast differs from type of enclosed expression"), = vcat [ptext (sLit "From-type of Cast differs from type of enclosed expression"),
......
...@@ -196,6 +196,7 @@ corePrepTopBinds initialCorePrepEnv binds ...@@ -196,6 +196,7 @@ corePrepTopBinds initialCorePrepEnv binds
mkDataConWorkers :: [TyCon] -> [CoreBind] mkDataConWorkers :: [TyCon] -> [CoreBind]
-- See Note [Data constructor workers] -- See Note [Data constructor workers]
-- c.f. Note [Injecting implicit bindings] in TidyPgm
mkDataConWorkers data_tycons mkDataConWorkers data_tycons
= [ NonRec id (Var id) -- The ice is thin here, but it works = [ NonRec id (Var id) -- The ice is thin here, but it works
| tycon <- data_tycons, -- CorePrep will eta-expand it | tycon <- data_tycons, -- CorePrep will eta-expand it
......
...@@ -23,7 +23,7 @@ module CoreSubst ( ...@@ -23,7 +23,7 @@ module CoreSubst (
substTy, substCo, substExpr, substExprSC, substBind, substBindSC, substTy, substCo, substExpr, substExprSC, substBind, substBindSC,
substUnfolding, substUnfoldingSC, substUnfolding, substUnfoldingSC,
lookupIdSubst, lookupTvSubst, lookupCvSubst, substIdOcc, lookupIdSubst, lookupTvSubst, lookupCvSubst, substIdOcc,
substTickish, substTickish, substVarSet,
-- ** Operations on substitutions -- ** Operations on substitutions
emptySubst, mkEmptySubst, mkSubst, mkOpenSubst, substInScope, isEmptySubst, emptySubst, mkEmptySubst, mkSubst, mkOpenSubst, substInScope, isEmptySubst,
......
...@@ -18,7 +18,7 @@ module CoreSyn ( ...@@ -18,7 +18,7 @@ module CoreSyn (
-- * Main data types -- * Main data types
Expr(..), Alt, Bind(..), AltCon(..), Arg, Tickish(..), Expr(..), Alt, Bind(..), AltCon(..), Arg, Tickish(..),
CoreProgram, CoreExpr, CoreAlt, CoreBind, CoreArg, CoreBndr, CoreProgram, CoreExpr, CoreAlt, CoreBind, CoreArg, CoreBndr,
TaggedExpr, TaggedAlt, TaggedBind, TaggedArg, TaggedBndr(..), TaggedExpr, TaggedAlt, TaggedBind, TaggedArg, TaggedBndr(..), deTagExpr,
-- ** 'Expr' construction -- ** 'Expr' construction
mkLets, mkLams, mkLets, mkLams,
...@@ -1106,6 +1106,25 @@ instance Outputable b => OutputableBndr (TaggedBndr b) where ...@@ -1106,6 +1106,25 @@ instance Outputable b => OutputableBndr (TaggedBndr b) where
pprBndr _ b = ppr b -- Simple pprBndr _ b = ppr b -- Simple
pprInfixOcc b = ppr b pprInfixOcc b = ppr b
pprPrefixOcc b = ppr b pprPrefixOcc b = ppr b
deTagExpr :: TaggedExpr t -> CoreExpr
deTagExpr (Var v) = Var v
deTagExpr (Lit l) = Lit l
deTagExpr (Type ty) = Type ty
deTagExpr (Coercion co) = Coercion co
deTagExpr (App e1 e2) = App (deTagExpr e1) (deTagExpr e2)
deTagExpr (Lam (TB b _) e) = Lam b (deTagExpr e)
deTagExpr (Let bind body) = Let (deTagBind bind) (deTagExpr body)
deTagExpr (Case e (TB b _) ty alts) = Case (deTagExpr e) b ty (map deTagAlt alts)
deTagExpr (Tick t e) = Tick t (deTagExpr e)
deTagExpr (Cast e co) = Cast (deTagExpr e) co
deTagBind :: TaggedBind t -> CoreBind
deTagBind (NonRec (TB b _) rhs) = NonRec b (deTagExpr rhs)
deTagBind (Rec prs) = Rec [(b, deTagExpr rhs) | (TB b _, rhs) <- prs]
deTagAlt :: TaggedAlt t -> CoreAlt
deTagAlt (con, bndrs, rhs) = (con, [b | TB b _ <- bndrs], deTagExpr rhs)
\end{code} \end{code}
......
...@@ -98,8 +98,11 @@ mkSimpleUnfolding :: DynFlags -> CoreExpr -> Unfolding ...@@ -98,8 +98,11 @@ mkSimpleUnfolding :: DynFlags -> CoreExpr -> Unfolding
mkSimpleUnfolding dflags = mkUnfolding dflags InlineRhs False False mkSimpleUnfolding dflags = mkUnfolding dflags InlineRhs False False
mkDFunUnfolding :: [Var] -> DataCon -> [CoreExpr] -> Unfolding mkDFunUnfolding :: [Var] -> DataCon -> [CoreExpr] -> Unfolding
mkDFunUnfolding bndrs con ops mkDFunUnfolding bndrs con ops
= DFunUnfolding { df_bndrs = bndrs, df_con = con, df_args = ops } = DFunUnfolding { df_bndrs = bndrs
, df_con = con
, df_args = map occurAnalyseExpr ops }
-- See Note [Occurrrence analysis of unfoldings]
mkWwInlineRule :: CoreExpr -> Arity -> Unfolding mkWwInlineRule :: CoreExpr -> Arity -> Unfolding
mkWwInlineRule expr arity mkWwInlineRule expr arity
...@@ -143,6 +146,7 @@ mkCoreUnfolding :: UnfoldingSource -> Bool -> CoreExpr ...@@ -143,6 +146,7 @@ mkCoreUnfolding :: UnfoldingSource -> Bool -> CoreExpr
-- Occurrence-analyses the expression before capturing it -- Occurrence-analyses the expression before capturing it
mkCoreUnfolding src top_lvl expr arity guidance mkCoreUnfolding src top_lvl expr arity guidance
= CoreUnfolding { uf_tmpl = occurAnalyseExpr expr, = CoreUnfolding { uf_tmpl = occurAnalyseExpr expr,
-- See Note [Occurrrence analysis of unfoldings]
uf_src = src, uf_src = src,
uf_arity = arity, uf_arity = arity,
uf_is_top = top_lvl, uf_is_top = top_lvl,
...@@ -162,6 +166,7 @@ mkUnfolding dflags src top_lvl is_bottoming expr ...@@ -162,6 +166,7 @@ mkUnfolding dflags src top_lvl is_bottoming expr
= NoUnfolding -- See Note [Do not inline top-level bottoming functions] = NoUnfolding -- See Note [Do not inline top-level bottoming functions]
| otherwise | otherwise
= CoreUnfolding { uf_tmpl = occurAnalyseExpr expr, = CoreUnfolding { uf_tmpl = occurAnalyseExpr expr,
-- See Note [Occurrrence analysis of unfoldings]
uf_src = src, uf_src = src,
uf_arity = arity, uf_arity = arity,
uf_is_top = top_lvl, uf_is_top = top_lvl,
...@@ -176,6 +181,24 @@ mkUnfolding dflags src top_lvl is_bottoming expr ...@@ -176,6 +181,24 @@ mkUnfolding dflags src top_lvl is_bottoming expr
-- See Note [Calculate unfolding guidance on the non-occ-anal'd expression] -- See Note [Calculate unfolding guidance on the non-occ-anal'd expression]
\end{code} \end{code}
Note [Occurrence analysis of unfoldings]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We do occurrence-analysis of unfoldings once and for all, when the
unfolding is built, rather than each time we inline them.
But given this decision it's vital that we do
*always* do it. Consider this unfolding
\x -> letrec { f = ...g...; g* = f } in body
where g* is (for some strange reason) the loop breaker. If we don't
occ-anal it when reading it in, we won't mark g as a loop breaker, and
we may inline g entirely in body, dropping its binding, and leaving
the occurrence in f out of scope. This happened in Trac #8892, where
the unfolding in question was a DFun unfolding.
But more generally, the simplifier is designed on the
basis that it is looking at occurrence-analysed expressions, so better
ensure that they acutally are.
Note [Calculate unfolding guidance on the non-occ-anal'd expression] Note [Calculate unfolding guidance on the non-occ-anal'd expression]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Notice that we give the non-occur-analysed expression to Notice that we give the non-occur-analysed expression to
......
...@@ -117,7 +117,7 @@ guessSourceFile :: LHsBinds Id -> FilePath -> FilePath ...@@ -117,7 +117,7 @@ guessSourceFile :: LHsBinds Id -> FilePath -> FilePath
guessSourceFile binds orig_file = guessSourceFile binds orig_file =
-- Try look for a file generated from a .hsc file to a -- Try look for a file generated from a .hsc file to a
-- .hs file, by peeking ahead. -- .hs file, by peeking ahead.
let top_pos = catMaybes $ foldrBag (\ (_, (L pos _)) rest -> let top_pos = catMaybes $ foldrBag (\ (L pos _) rest ->
srcSpanFileName_maybe pos : rest) [] binds srcSpanFileName_maybe pos : rest) [] binds
in in
case top_pos of case top_pos of
...@@ -229,11 +229,7 @@ shouldTickPatBind density top_lev ...@@ -229,11 +229,7 @@ shouldTickPatBind density top_lev
-- Adding ticks to bindings -- Adding ticks to bindings
addTickLHsBinds :: LHsBinds Id -> TM (LHsBinds Id) addTickLHsBinds :: LHsBinds Id -> TM (LHsBinds Id)
addTickLHsBinds binds = mapBagM addTick binds addTickLHsBinds = mapBagM addTickLHsBind
where
addTick (origin, bind) = do
bind' <- addTickLHsBind bind
return (origin, bind')
addTickLHsBind :: LHsBind Id -> TM (LHsBind Id) addTickLHsBind :: LHsBind Id -> TM (LHsBind Id)
addTickLHsBind (L pos bind@(AbsBinds { abs_binds = binds, addTickLHsBind (L pos bind@(AbsBinds { abs_binds = binds,
......
...@@ -517,7 +517,7 @@ case bodies, containing the following fields: ...@@ -517,7 +517,7 @@ case bodies, containing the following fields:
\begin{code} \begin{code}
dsCmd ids local_vars stack_ty res_ty dsCmd ids local_vars stack_ty res_ty
(HsCmdCase exp (MG { mg_alts = matches, mg_arg_tys = arg_tys })) (HsCmdCase exp (MG { mg_alts = matches, mg_arg_tys = arg_tys, mg_origin = origin }))
env_ids = do env_ids = do
stack_id <- newSysLocalDs stack_ty stack_id <- newSysLocalDs stack_ty
...@@ -561,7 +561,7 @@ dsCmd ids local_vars stack_ty res_ty ...@@ -561,7 +561,7 @@ dsCmd ids local_vars stack_ty res_ty
in_ty = envStackType env_ids stack_ty in_ty = envStackType env_ids stack_ty
core_body <- dsExpr (HsCase exp (MG { mg_alts = matches', mg_arg_tys = arg_tys core_body <- dsExpr (HsCase exp (MG { mg_alts = matches', mg_arg_tys = arg_tys
, mg_res_ty = sum_ty })) , mg_res_ty = sum_ty, mg_origin = origin }))
-- Note that we replace the HsCase result type by sum_ty, -- Note that we replace the HsCase result type by sum_ty,
-- which is the type of matches' -- which is the type of matches'
......