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
  • MTaimoorZaeem/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
650 results
Show changes
Commits on Source (375)
Showing
with 690 additions and 273 deletions
...@@ -154,3 +154,11 @@ _darcs/ ...@@ -154,3 +154,11 @@ _darcs/
.tm_properties .tm_properties
VERSION VERSION
GIT_COMMIT_ID GIT_COMMIT_ID
# -------------------------------------------------------------------------------------
# when using a docker image, one can mount the source code directory as the home folder
# -------------------------------------------------------------------------------------
.arcrc
.ghc
.bash_history
.gitconfig
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
path = libraries/Cabal path = libraries/Cabal
url = ../packages/Cabal.git url = ../packages/Cabal.git
ignore = untracked ignore = untracked
branch = 1.22
[submodule "libraries/containers"] [submodule "libraries/containers"]
path = libraries/containers path = libraries/containers
url = ../packages/containers.git url = ../packages/containers.git
...@@ -102,7 +103,7 @@ ...@@ -102,7 +103,7 @@
path = utils/haddock path = utils/haddock
url = ../haddock.git url = ../haddock.git
ignore = none ignore = none
branch = ghc-head branch = master
[submodule "nofib"] [submodule "nofib"]
path = nofib path = nofib
url = ../nofib.git url = ../nofib.git
......
============================================================== ==============================================================
The (Interactive) Glasgow Haskell Compiler -- version 6.10.1 The (Interactive) Glasgow Haskell Compiler -- version 7.10.2
============================================================== ==============================================================
The GHC Team is pleased to announce a new major release of GHC. There The GHC Team is pleased to announce a new minor release of GHC. This is a
have been a number of significant changes since the last major release, bug-fix release and contains a number of important fixes,
including:
* Some new language features have been implemented: * Various typechecker issues have been fixed, including some bugs which allowed
* Record syntax: wild-card patterns, punning, and field disambiguation the user to write unsafeCoerce
* Generalised quasi-quotes
* Generalised list comprehensions
* View patterns
* Type families have been completely re-implemented * DWARF debug information is now more correct and supported on Windows
* Now comes with Haddock 2, which supports all GHC extensions * Portability issues resulting in crashes on SPARC, Linux/i386, ARM, AArch64,
and PowerPC have been fixed
* Parallel garbage collection * The event manager's multi-shot event registration functionality now works
correctly
* Base provides extensible exceptions * A bug where unaccounted for register aliasing could result in incorrect
floating-point results has been fixed
* The GHC API is easier to use * An infinite loop during program startup when iconv is unavailable hsa been
fixed
* External core (output only) now works again * The source location of the caller of a function is now available as an implicit
parameter to allow for better error reporting in the future
* Data Parallel Haskell (DPH) comes as part of GHC A more thorough list of the changes in the release can be found in the release
notes,
The full release notes are here: http://haskell.org/ghc/docs/7.10.2/html/users_guide/release-7-10-2.html
http://haskell.org/ghc/docs/6.10.1/html/users_guide/release-6-10-1.html
How to get it How to get it
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
...@@ -52,13 +53,12 @@ Background ...@@ -52,13 +53,12 @@ Background
Haskell is a standard lazy functional programming language. Haskell is a standard lazy functional programming language.
GHC is a state-of-the-art programming suite for Haskell. Included is GHC is a state-of-the-art programming suite for Haskell. Included is
an optimising compiler generating good code for a variety of an optimising compiler generating efficient code for a variety of
platforms, together with an interactive system for convenient, quick platforms, together with an interactive system for convenient, quick
development. The distribution includes space and time profiling development. The distribution includes space and time profiling
facilities, a large collection of libraries, and support for various facilities, a large collection of libraries, and support for various
language extensions, including concurrency, exceptions, and foreign language extensions, including concurrency, exceptions, and foreign
language interfaces (C, whatever). GHC is distributed under a language interfaces. GHC is distributed under a BSD-style open source license.
BSD-style open source license.
A wide variety of Haskell related resources (tutorials, libraries, A wide variety of Haskell related resources (tutorials, libraries,
specifications, documentation, compilers, interpreters, references, specifications, documentation, compilers, interpreters, references,
...@@ -107,13 +107,13 @@ Mailing lists ...@@ -107,13 +107,13 @@ Mailing lists
We run mailing lists for GHC users and bug reports; to subscribe, use We run mailing lists for GHC users and bug reports; to subscribe, use
the web interfaces at the web interfaces at
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-tickets
There are several other haskell and ghc-related mailing lists on There are several other haskell and ghc-related mailing lists on
www.haskell.org; for the full list, see www.haskell.org; for the full list, see
http://www.haskell.org/mailman/listinfo/ https://mail.haskell.org/cgi-bin/mailman/listinfo
Some GHC developers hang out on #haskell on IRC, too: Some GHC developers hang out on #haskell on IRC, too:
......
Building & Installing
=====================
For full information on building GHC, see the GHC Building Guide [1].
Here follows a summary - if you get into trouble, the Building Guide
has all the answers.
Before building GHC you may need to install some other tools and
libraries. See "Setting up your system for building GHC" [2].
NB. in particular you need GHC installed in order to build GHC,
because the compiler is itself written in Haskell. For instructions
on how to port GHC to a new platform, see the Building Guide [1].
For building library documentation, you'll need Haddock [3]. To build
the compiler documentation, you need a good DocBook XML toolchain and
dblatex.
Quick start: the following gives you a default build:
$ perl boot
$ ./configure
$ make
$ make install
The "perl boot" step is only necessary if this is a tree checked out
from git. For source distributions downloaded from GHC's web site,
this step has already been performed.
These steps give you the default build, which includes everything
optimised and built in various ways (eg. profiling libs are built).
It can take a long time. To customise the build, see the file
`HACKING.md`.
References
==========
[1] http://www.haskell.org/ghc/
[2] http://hackage.haskell.org/trac/ghc/wiki/Building/Preparation
[3] http://www.haskell.org/haddock/
Using the GHC build system
--------------------------
For a "Getting Started" guide, see:
http://ghc.haskell.org/trac/ghc/wiki/Building/Hacking
Common commands:
make
Builds everything: ghc stages 1 and 2, all libraries and tools.
make -j2
Parallel build: runs up to 2 commands at a time (use the number of
CPUs in your machine in place of '2')
cd <dir>; make
Builds everything in the given directory.
cd <dir>; make help
Shows the targets available in <dir>
make install
Installs GHC, libraries and tools under $(prefix)
make sdist
make binary-dist
Builds a source or binary distribution respectively
make show VALUE=<var>
Displays the value of make variable <var>
make clean
make distclean
make maintainer-clean
Various levels of cleaning: "clean" restores the tree to the
state after "./configure", "distclean" restores to the state
after "perl boot", and maintainer-clean restores the tree to the
completely clean checked-out state.
Quick `make` guide for GHC
==========================
For a "Getting Started" guide, see:
http://ghc.haskell.org/trac/ghc/wiki/Building/Hacking
Common commands:
- `make`
Builds everything: ghc stages 1 and 2, all libraries and tools.
- `make -j2`
Parallel build: runs up to 2 commands at a time.
- `cd <dir>; make`
Builds everything in the given directory.
- cd <dir>; make help
Shows the targets available in <dir>
- make install
Installs GHC, libraries and tools under $(prefix)
- make sdist
- make binary-dist
Builds a source or binary distribution respectively
- `make show VALUE=<var>`
Displays the value of make variable <var>
- make clean
- make distclean
- make maintainer-clean
Various levels of cleaning: "clean" restores the tree to the
state after "./configure", "distclean" restores to the state
after "perl boot", and maintainer-clean restores the tree to the
completely clean checked-out state.
Using `make` in subdirectories
==============================
- `make`
Builds everything in this directory (including dependencies elsewhere
in the tree, if necessary)
- `make fast`
The same as 'make', but omits some phases and does not
recalculate dependencies. Useful for saving time if you are sure
the rest of the tree is up to date.
- `make clean`
- `make distclean`
- `make maintainer-clean`
Clean just this directory
- `make html`
- `make pdf`
- `make ps`
Make documentation in this directory (if any)
- `make show VALUE=var`
Show the value of $(var)
- `make <file>`
Bring a particular file up to date, e.g. make dist/build/Module.o
The name <file> is relative to the current directory
...@@ -31,7 +31,7 @@ default : all ...@@ -31,7 +31,7 @@ default : all
# For help, type 'make help' # For help, type 'make help'
.PHONY: help .PHONY: help
help: help:
@cat MAKEHELP @cat MAKEHELP.md
ifneq "$(filter maintainer-clean distclean clean help,$(MAKECMDGOALS))" "" ifneq "$(filter maintainer-clean distclean clean help,$(MAKECMDGOALS))" ""
-include mk/config.mk -include mk/config.mk
......
make
Builds everything in this directory (including dependencies elsewhere
in the tree, if necessary)
make fast
The same as 'make', but omits some phases and does not
recalculate dependencies. Useful for saving time if you are sure
the rest of the tree is up to date.
make clean
make distclean
make maintainer-clean
Clean just this directory
make html
make pdf
make ps
Make documentation in this directory (if any)
make show VALUE=var
Show the value of $(var)
make <file>
Bring a particular file up to date, e.g. make dist/build/Module.o
The name <file> is relative to the current directory
...@@ -565,6 +565,14 @@ AC_DEFUN([FPTOOLS_SET_C_LD_FLAGS], ...@@ -565,6 +565,14 @@ AC_DEFUN([FPTOOLS_SET_C_LD_FLAGS],
$3="$$3 -D_HPUX_SOURCE" $3="$$3 -D_HPUX_SOURCE"
$5="$$5 -D_HPUX_SOURCE" $5="$$5 -D_HPUX_SOURCE"
;; ;;
arm*linux* | \
aarch64*linux* )
# On arm/linux, aarch64/linux, arm/android and aarch64/android, tell
# gcc to link using the gold linker.
# Forcing LD to be ld.gold is done in FIND_LD m4 macro.
$3="$$3 -fuse-ld=gold -Wl,-z,noexecstack"
$4="$$4 -z noexecstack"
;;
esac esac
# If gcc knows about the stack protector, turn it off. # If gcc knows about the stack protector, turn it off.
...@@ -1581,6 +1589,7 @@ if test "$RELEASE" = "NO"; then ...@@ -1581,6 +1589,7 @@ if test "$RELEASE" = "NO"; then
dnl less likely to go wrong. dnl less likely to go wrong.
PACKAGE_VERSION=${PACKAGE_VERSION}.`date +%Y%m%d` PACKAGE_VERSION=${PACKAGE_VERSION}.`date +%Y%m%d`
fi fi
fi
AC_MSG_CHECKING([for GHC Git commit id]) AC_MSG_CHECKING([for GHC Git commit id])
if test -d .git; then if test -d .git; then
...@@ -1598,7 +1607,6 @@ if test "$RELEASE" = "NO"; then ...@@ -1598,7 +1607,6 @@ if test "$RELEASE" = "NO"; then
PACKAGE_GIT_COMMIT_ID="0000000000000000000000000000000000000000" PACKAGE_GIT_COMMIT_ID="0000000000000000000000000000000000000000"
fi fi
fi
# Some renamings # Some renamings
AC_SUBST([ProjectName], [$PACKAGE_NAME]) AC_SUBST([ProjectName], [$PACKAGE_NAME])
...@@ -1826,6 +1834,28 @@ AC_DEFUN([FP_GMP], ...@@ -1826,6 +1834,28 @@ AC_DEFUN([FP_GMP],
AC_SUBST(GMP_LIB_DIRS) AC_SUBST(GMP_LIB_DIRS)
])# FP_GMP ])# FP_GMP
# FP_CURSES
# -------------
AC_DEFUN([FP_CURSES],
[
dnl--------------------------------------------------------------------
dnl * Deal with arguments telling us curses is somewhere odd
dnl--------------------------------------------------------------------
AC_ARG_WITH([curses-includes],
[AC_HELP_STRING([--with-curses-includes],
[directory containing curses headers])],
[CURSES_INCLUDE_DIRS=$withval])
AC_ARG_WITH([curses-libraries],
[AC_HELP_STRING([--with-curses-libraries],
[directory containing curses libraries])],
[CURSES_LIB_DIRS=$withval])
AC_SUBST(CURSES_INCLUDE_DIRS)
AC_SUBST(CURSES_LIB_DIRS)
])# FP_CURSES
# -------------------------------------------------------------- # --------------------------------------------------------------
# Calculate absolute path to build tree # Calculate absolute path to build tree
# -------------------------------------------------------------- # --------------------------------------------------------------
...@@ -2069,28 +2099,67 @@ AC_DEFUN([XCODE_VERSION],[ ...@@ -2069,28 +2099,67 @@ AC_DEFUN([XCODE_VERSION],[
# $1 = the variable to set # $1 = the variable to set
# $2 = the with option name # $2 = the with option name
# $3 = the command to look for # $3 = the command to look for
# $4 = the version of the command to look for
# #
AC_DEFUN([FIND_LLVM_PROG],[ AC_DEFUN([FIND_LLVM_PROG],[
FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL_NOTARGET([$1], [$2], [$3]) # Test for program with version name.
if test "$$1" == ""; then FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL_NOTARGET([$1], [$2], [$3-$4])
save_IFS=$IFS if test "$$1" = ""; then
IFS=":;" # Test for program without version name.
for p in ${PATH}; do FP_ARG_WITH_PATH_GNU_PROG_OPTIONAL_NOTARGET([$1], [$2], [$3])
if test -d "${p}"; then AC_MSG_CHECKING([$$1 is version $4])
if test "$windows" = YES; then if test `$$1 --version | grep -c "version $4"` -gt 0 ; then
$1=`${FindCmd} "${p}" -type f -maxdepth 1 -regex '.*/$3-[[0-9]]\.[[0-9]]' -or -type l -maxdepth 1 -regex '.*/$3-[[0-9]]\.[[0-9]]' | ${SortCmd} -n | tail -1` AC_MSG_RESULT(yes)
else else
$1=`${FindCmd} "${p}" -type f -perm \111 -maxdepth 1 -regex '.*/$3-[[0-9]]\.[[0-9]]' -or -type l -perm \111 -maxdepth 1 -regex '.*/$3-[[0-9]]\.[[0-9]]' | ${SortCmd} -n | tail -1` AC_MSG_RESULT(no)
fi $1=""
if test -n "$$1"; then fi
break fi
fi ])
fi
done # FIND_LD
IFS=$save_IFS # Find the version of `ld` to use. This is used in both in the top level
# configure.ac and in distrib/configure.ac.in.
#
# $1 = the variable to set
#
AC_DEFUN([FIND_LD],[
FP_ARG_WITH_PATH_GNU_PROG([LD], [ld], [ld])
case $target in
arm*linux* | \
aarch64*linux* )
# Arm and Aarch64 requires use of the binutils ld.gold linker.
# This case should catch at least arm-unknown-linux-gnueabihf,
# arm-linux-androideabi, arm64-unknown-linux and
# aarch64-linux-android
FP_ARG_WITH_PATH_GNU_PROG([LD_GOLD], [ld.gold], [ld.gold])
$1="$LD_GOLD"
;;
*)
$1="$LD"
;;
esac
])
# FIND_GHC_BOOTSTRAP_PROG()
# --------------------------------
# Parse the bootstrap GHC's compier settings file for the location of things
# like the `llc` and `opt` commands.
#
# $1 = the variable to set
# $2 = The bootstrap compiler.
# $3 = The string to grep for to find the correct line.
#
AC_DEFUN([FIND_GHC_BOOTSTRAP_PROG],[
BootstrapTmpCmd=`grep $3 $($2 --print-libdir)/settings 2>/dev/null | sed 's/.*", "//;s/".*//'`
if test -n "$BootstrapTmpCmd" && test `basename $BootstrapTmpCmd` = $BootstrapTmpCmd ; then
AC_PATH_PROG([$1], [$BootstrapTmpCmd], "")
else
$1=$BootstrapTmpCmd
fi fi
]) ])
# FIND_GCC() # FIND_GCC()
# -------------------------------- # --------------------------------
# Finds where gcc is # Finds where gcc is
......
...@@ -84,7 +84,9 @@ module BasicTypes( ...@@ -84,7 +84,9 @@ module BasicTypes(
FractionalLit(..), negateFractionalLit, integralFractionalLit, FractionalLit(..), negateFractionalLit, integralFractionalLit,
HValue(..) HValue(..),
SourceText
) where ) where
import FastString import FastString
...@@ -261,14 +263,15 @@ initialVersion = 1 ...@@ -261,14 +263,15 @@ initialVersion = 1
-} -}
-- reason/explanation from a WARNING or DEPRECATED pragma -- reason/explanation from a WARNING or DEPRECATED pragma
data WarningTxt = WarningTxt [Located FastString] -- For SourceText usage, see note [Pragma source text]
| DeprecatedTxt [Located FastString] data WarningTxt = WarningTxt (Located SourceText) [Located FastString]
| DeprecatedTxt (Located SourceText) [Located FastString]
deriving (Eq, Data, Typeable) deriving (Eq, Data, Typeable)
instance Outputable WarningTxt where instance Outputable WarningTxt where
ppr (WarningTxt ws) = doubleQuotes (vcat (map (ftext . unLoc) ws)) ppr (WarningTxt _ ws) = doubleQuotes (vcat (map (ftext . unLoc) ws))
ppr (DeprecatedTxt ds) = text "Deprecated:" <+> ppr (DeprecatedTxt _ ds) = text "Deprecated:" <+>
doubleQuotes (vcat (map (ftext . unLoc) ds)) doubleQuotes (vcat (map (ftext . unLoc) ds))
{- {-
************************************************************************ ************************************************************************
...@@ -446,6 +449,15 @@ instance Outputable Origin where ...@@ -446,6 +449,15 @@ instance Outputable Origin where
-- | The semantics allowed for overlapping instances for a particular -- | The semantics allowed for overlapping instances for a particular
-- instance. See Note [Safe Haskell isSafeOverlap] (in `InstEnv.lhs`) for a -- instance. See Note [Safe Haskell isSafeOverlap] (in `InstEnv.lhs`) for a
-- explanation of the `isSafeOverlap` field. -- explanation of the `isSafeOverlap` field.
--
-- - 'ApiAnnotation.AnnKeywordId' :
-- 'ApiAnnotation.AnnOpen' @'\{-\# OVERLAPPABLE'@ or
-- @'\{-\# OVERLAPPING'@ or
-- @'\{-\# OVERLAPS'@ or
-- @'\{-\# INCOHERENT'@,
-- 'ApiAnnotation.AnnClose' @`\#-\}`@,
-- For details on above see note [Api annotations] in ApiAnnotation
data OverlapFlag = OverlapFlag data OverlapFlag = OverlapFlag
{ overlapMode :: OverlapMode { overlapMode :: OverlapMode
, isSafeOverlap :: Bool , isSafeOverlap :: Bool
...@@ -458,27 +470,29 @@ setOverlapModeMaybe f (Just m) = f { overlapMode = m } ...@@ -458,27 +470,29 @@ setOverlapModeMaybe f (Just m) = f { overlapMode = m }
hasOverlappableFlag :: OverlapMode -> Bool hasOverlappableFlag :: OverlapMode -> Bool
hasOverlappableFlag mode = hasOverlappableFlag mode =
case mode of case mode of
Overlappable -> True Overlappable _ -> True
Overlaps -> True Overlaps _ -> True
Incoherent -> True Incoherent _ -> True
_ -> False _ -> False
hasOverlappingFlag :: OverlapMode -> Bool hasOverlappingFlag :: OverlapMode -> Bool
hasOverlappingFlag mode = hasOverlappingFlag mode =
case mode of case mode of
Overlapping -> True Overlapping _ -> True
Overlaps -> True Overlaps _ -> True
Incoherent -> True Incoherent _ -> True
_ -> False _ -> False
data OverlapMode -- See Note [Rules for instance lookup] in InstEnv data OverlapMode -- See Note [Rules for instance lookup] in InstEnv
= NoOverlap = NoOverlap SourceText
-- See Note [Pragma source text]
-- ^ This instance must not overlap another `NoOverlap` instance. -- ^ This instance must not overlap another `NoOverlap` instance.
-- However, it may be overlapped by `Overlapping` instances, -- However, it may be overlapped by `Overlapping` instances,
-- and it may overlap `Overlappable` instances. -- and it may overlap `Overlappable` instances.
| Overlappable | Overlappable SourceText
-- See Note [Pragma source text]
-- ^ Silently ignore this instance if you find a -- ^ Silently ignore this instance if you find a
-- more specific one that matches the constraint -- more specific one that matches the constraint
-- you are trying to resolve -- you are trying to resolve
...@@ -492,7 +506,8 @@ data OverlapMode -- See Note [Rules for instance lookup] in InstEnv ...@@ -492,7 +506,8 @@ data OverlapMode -- See Note [Rules for instance lookup] in InstEnv
-- its ambiguous which to choose) -- its ambiguous which to choose)
| Overlapping | Overlapping SourceText
-- See Note [Pragma source text]
-- ^ Silently ignore any more general instances that may be -- ^ Silently ignore any more general instances that may be
-- used to solve the constraint. -- used to solve the constraint.
-- --
...@@ -505,10 +520,12 @@ data OverlapMode -- See Note [Rules for instance lookup] in InstEnv ...@@ -505,10 +520,12 @@ data OverlapMode -- See Note [Rules for instance lookup] in InstEnv
-- it is ambiguous which to choose) -- it is ambiguous which to choose)
| Overlaps | Overlaps SourceText
-- See Note [Pragma source text]
-- ^ Equivalent to having both `Overlapping` and `Overlappable` flags. -- ^ Equivalent to having both `Overlapping` and `Overlappable` flags.
| Incoherent | Incoherent SourceText
-- See Note [Pragma source text]
-- ^ Behave like Overlappable and Overlapping, and in addition pick -- ^ Behave like Overlappable and Overlapping, and in addition pick
-- an an arbitrary one if there are multiple matching candidates, and -- an an arbitrary one if there are multiple matching candidates, and
-- don't worry about later instantiation -- don't worry about later instantiation
...@@ -527,11 +544,11 @@ instance Outputable OverlapFlag where ...@@ -527,11 +544,11 @@ instance Outputable OverlapFlag where
ppr flag = ppr (overlapMode flag) <+> pprSafeOverlap (isSafeOverlap flag) ppr flag = ppr (overlapMode flag) <+> pprSafeOverlap (isSafeOverlap flag)
instance Outputable OverlapMode where instance Outputable OverlapMode where
ppr NoOverlap = empty ppr (NoOverlap _) = empty
ppr Overlappable = ptext (sLit "[overlappable]") ppr (Overlappable _) = ptext (sLit "[overlappable]")
ppr Overlapping = ptext (sLit "[overlapping]") ppr (Overlapping _) = ptext (sLit "[overlapping]")
ppr Overlaps = ptext (sLit "[overlap ok]") ppr (Overlaps _) = ptext (sLit "[overlap ok]")
ppr Incoherent = ptext (sLit "[incoherent]") ppr (Incoherent _) = ptext (sLit "[incoherent]")
pprSafeOverlap :: Bool -> SDoc pprSafeOverlap :: Bool -> SDoc
pprSafeOverlap True = ptext $ sLit "[safe]" pprSafeOverlap True = ptext $ sLit "[safe]"
...@@ -763,6 +780,70 @@ succeeded Failed = False ...@@ -763,6 +780,70 @@ succeeded Failed = False
failed Succeeded = False failed Succeeded = False
failed Failed = True failed Failed = True
{-
************************************************************************
* *
\subsection{Source Text}
* *
************************************************************************
Keeping Source Text for source to source conversions
Note [Pragma source text]
~~~~~~~~~~~~~~~~~~~~~~~~~
The lexer does a case-insensitive match for pragmas, as well as
accepting both UK and US spelling variants.
So
{-# SPECIALISE #-}
{-# SPECIALIZE #-}
{-# Specialize #-}
will all generate ITspec_prag token for the start of the pragma.
In order to be able to do source to source conversions, the original
source text for the token needs to be preserved, hence the
`SourceText` field.
So the lexer will then generate
ITspec_prag "{ -# SPECIALISE"
ITspec_prag "{ -# SPECIALIZE"
ITspec_prag "{ -# Specialize"
for the cases above.
[without the space between '{' and '-', otherwise this comment won't parse]
Note [Literal source text]
~~~~~~~~~~~~~~~~~~~~~~~~~~
The lexer/parser converts literals from their original source text
versions to an appropriate internal representation. This is a problem
for tools doing source to source conversions, so the original source
text is stored in literals where this can occur.
Motivating examples for HsLit
HsChar '\n' == '\x20`
HsCharPrim '\x41`# == `A`
HsString "\x20\x41" == " A"
HsStringPrim "\x20"# == " "#
HsInt 001 == 1
HsIntPrim 002# == 2#
HsWordPrim 003## == 3##
HsInt64Prim 004## == 4##
HsWord64Prim 005## == 5##
HsInteger 006 == 6
For OverLitVal
HsIntegral 003 == 0x003
HsIsString "\x41nd" == "And"
-}
type SourceText = String -- Note [Literal source text],[Pragma source text]
{- {-
************************************************************************ ************************************************************************
* * * *
...@@ -798,7 +879,8 @@ data RuleMatchInfo = ConLike -- See Note [CONLIKE pragma] ...@@ -798,7 +879,8 @@ data RuleMatchInfo = ConLike -- See Note [CONLIKE pragma]
data InlinePragma -- Note [InlinePragma] data InlinePragma -- Note [InlinePragma]
= InlinePragma = InlinePragma
{ inl_inline :: InlineSpec { inl_src :: SourceText -- Note [Pragma source text]
, inl_inline :: InlineSpec
, inl_sat :: Maybe Arity -- Just n <=> Inline only when applied to n , inl_sat :: Maybe Arity -- Just n <=> Inline only when applied to n
-- explicit (non-type, non-dictionary) args -- explicit (non-type, non-dictionary) args
...@@ -888,7 +970,8 @@ isEmptyInlineSpec _ = False ...@@ -888,7 +970,8 @@ isEmptyInlineSpec _ = False
defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma
:: InlinePragma :: InlinePragma
defaultInlinePragma = InlinePragma { inl_act = AlwaysActive defaultInlinePragma = InlinePragma { inl_src = "{-# INLINE"
, inl_act = AlwaysActive
, inl_rule = FunLike , inl_rule = FunLike
, inl_inline = EmptyInlineSpec , inl_inline = EmptyInlineSpec
, inl_sat = Nothing } , inl_sat = Nothing }
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
module DataCon ( module DataCon (
-- * Main data types -- * Main data types
DataCon, DataConRep(..), HsBang(..), StrictnessMark(..), DataCon, DataConRep(..),
HsBang(..), HsSrcBang, HsImplBang,
StrictnessMark(..),
ConTag, ConTag,
-- ** Type construction -- ** Type construction
...@@ -26,11 +28,11 @@ module DataCon ( ...@@ -26,11 +28,11 @@ module DataCon (
dataConInstArgTys, dataConOrigArgTys, dataConOrigResTy, dataConInstArgTys, dataConOrigArgTys, dataConOrigResTy,
dataConInstOrigArgTys, dataConRepArgTys, dataConInstOrigArgTys, dataConRepArgTys,
dataConFieldLabels, dataConFieldType, dataConFieldLabels, dataConFieldType,
dataConStrictMarks, dataConSrcBangs,
dataConSourceArity, dataConRepArity, dataConRepRepArity, dataConSourceArity, dataConRepArity, dataConRepRepArity,
dataConIsInfix, dataConIsInfix,
dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitIds, dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitIds,
dataConRepStrictness, dataConRepBangs, dataConBoxer, dataConRepStrictness, dataConImplBangs, dataConBoxer,
splitDataProductType_maybe, splitDataProductType_maybe,
...@@ -248,6 +250,8 @@ Note that (Foo a) might not be an instance of Ord. ...@@ -248,6 +250,8 @@ Note that (Foo a) might not be an instance of Ord.
-- --
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen', -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose','ApiAnnotation.AnnComma' -- 'ApiAnnotation.AnnClose','ApiAnnotation.AnnComma'
-- For details on above see note [Api annotations] in ApiAnnotation
data DataCon data DataCon
= MkData { = MkData {
dcName :: Name, -- This is the name of the *source data con* dcName :: Name, -- This is the name of the *source data con*
...@@ -341,9 +345,14 @@ data DataCon ...@@ -341,9 +345,14 @@ data DataCon
-- The OrigResTy is T [a], but the dcRepTyCon might be :T123 -- The OrigResTy is T [a], but the dcRepTyCon might be :T123
-- Now the strictness annotations and field labels of the constructor -- Now the strictness annotations and field labels of the constructor
-- See Note [Bangs on data constructor arguments] dcSrcBangs :: [HsBang],
dcArgBangs :: [HsBang], -- See Note [Bangs on data constructor arguments]
-- Strictness annotations as decided by the compiler. -- For DataCons defined in this module:
-- the [HsSrcBang] as written by the programmer.
-- For DataCons imported from an interface file:
-- the [HsImplBang] determined when compiling the
-- defining module
--
-- Matches 1-1 with dcOrigArgTys -- Matches 1-1 with dcOrigArgTys
-- Hence length = dataConSourceArity dataCon -- Hence length = dataConSourceArity dataCon
...@@ -406,9 +415,9 @@ data DataConRep ...@@ -406,9 +415,9 @@ data DataConRep
, dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys
-- See also Note [Data-con worker strictness] in MkId.lhs -- See also Note [Data-con worker strictness] in MkId.lhs
, dcr_bangs :: [HsBang] -- The actual decisions made (including failures) , dcr_bangs :: [HsImplBang] -- The actual decisions made (including failures)
-- 1-1 with orig_arg_tys -- about the original arguments; 1-1 with orig_arg_tys
-- See Note [Bangs on data constructor arguments] -- See Note [Bangs on data constructor arguments]
} }
-- Algebraic data types always have a worker, and -- Algebraic data types always have a worker, and
...@@ -437,30 +446,79 @@ data DataConRep ...@@ -437,30 +446,79 @@ data DataConRep
-- when we bring bits of unfoldings together.) -- when we bring bits of unfoldings together.)
------------------------- -------------------------
-- HsBang describes what the *programmer* wrote -- HsBang describes the strictness/unpack status of one
-- This info is retained in the DataCon.dcStrictMarks field -- of the original data constructor arguments (i.e. *not*
-- of the representation data constructor which may have
-- more arguments after the originals have been unpacked)
-- See Note [Bangs on data constructor arguments]
data HsBang data HsBang
= HsUserBang -- The user's source-code request = HsNoBang -- Equivalent to (HsSrcBang Nothing False)
| HsSrcBang -- What the user wrote in the source code
(Maybe SourceText) -- Note [Pragma source text] in BasicTypes
(Maybe Bool) -- Just True {-# UNPACK #-} (Maybe Bool) -- Just True {-# UNPACK #-}
-- Just False {-# NOUNPACK #-} -- Just False {-# NOUNPACK #-}
-- Nothing no pragma -- Nothing no pragma
Bool -- True <=> '!' specified Bool -- True <=> '!' specified
-- (HsSrcBang (Just True) False) makes no sense
-- We emit a warning (in checkValidDataCon) and treat it
-- just like (HsSrcBang Nothing False)
| HsNoBang -- Lazy field -- Definite implementation commitments, generated by the compiler
-- HsUserBang Nothing False means the same as HsNoBang -- after consulting HsSrcBang (if any), flags, etc
| HsUnpack -- Definite commitment: this field is strict and unboxed | HsUnpack -- Definite commitment: this field is strict and unboxed
(Maybe Coercion) -- co :: arg-ty ~ product-ty (Maybe Coercion) -- co :: arg-ty ~ product-ty
| HsStrict -- Definite commitment: this field is strict but not unboxed | HsStrict -- Definite commitment: this field is strict but not unboxed
deriving (Data.Data, Data.Typeable) deriving (Data.Data, Data.Typeable)
-- Two type-insecure, but useful, synonyms
type HsSrcBang = HsBang -- What the user wrote; hence always HsNoBang or HsSrcBang
type HsImplBang = HsBang -- A HsBang implementation decision,
-- as determined by the compiler
-- Never HsSrcBang
------------------------- -------------------------
-- StrictnessMark is internal only, used to indicate strictness -- StrictnessMark is internal only, used to indicate strictness
-- of the DataCon *worker* fields -- of the DataCon *worker* fields
data StrictnessMark = MarkedStrict | NotMarkedStrict data StrictnessMark = MarkedStrict | NotMarkedStrict
{- {- Note [Bangs on data constructor arguments]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
data T = MkT !Int {-# UNPACK #-} !Int Bool
When compiling the module, GHC will decide how to represent
MkT, depending on the optimisation level, and settings of
flags like -funbox-small-strict-fields.
Terminology:
* HsSrcBang: What the user wrote
Constructors: HsNoBang, HsUserBang
* HsImplBang: What GHC decided
Constructors: HsNoBang, HsStrict, HsUnpack
* If T was defined in this module, MkT's dcSrcBangs field
records the [HsSrcBang] of what the user wrote; in the example
[ HsSrcBang Nothing True
, HsSrcBang (Just True) True
, HsNoBang]
* However, if T was defined in an imported module, MkT's dcSrcBangs
field gives the [HsImplBang] recording the decisions of the
defining module. The importing module must follow those decisions,
regardless of the flag settings in the importing module.
* The dcr_bangs field of the dcRep field records the [HsImplBang]
If T was defined in this module, Without -O the dcr_bangs might be
[HsStrict, HsStrict, HsNoBang]
With -O it might be
[HsStrict, HsUnpack, HsNoBang]
With -funbox-small-strict-fields it might be
[HsUnpack, HsUnpack, HsNoBang]
Note [Data con representation] Note [Data con representation]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The dcRepType field contains the type of the representation of a contructor The dcRepType field contains the type of the representation of a contructor
...@@ -479,26 +537,6 @@ but the rep type is ...@@ -479,26 +537,6 @@ but the rep type is
Trep :: Int# -> a -> T a Trep :: Int# -> a -> T a
Actually, the unboxed part isn't implemented yet! Actually, the unboxed part isn't implemented yet!
Note [Bangs on data constructor arguments]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
data T = MkT !Int {-# UNPACK #-} !Int Bool
Its dcArgBangs field records the *users* specifications, in this case
[ HsUserBang Nothing True
, HsUserBang (Just True) True
, HsNoBang]
See the declaration of HsBang in BasicTypes
The dcr_bangs field of the dcRep field records the *actual, decided*
representation of the data constructor. Without -O this might be
[HsStrict, HsStrict, HsNoBang]
With -O it might be
[HsStrict, HsUnpack, HsNoBang]
With -funbox-small-strict-fields it might be
[HsUnpack, HsUnpack, HsNoBang]
For imported data types, the dcArgBangs field is just the same as the
dcr_bangs field; we don't know what the user originally said.
************************************************************************ ************************************************************************
...@@ -539,11 +577,11 @@ instance Data.Data DataCon where ...@@ -539,11 +577,11 @@ instance Data.Data DataCon where
dataTypeOf _ = mkNoRepType "DataCon" dataTypeOf _ = mkNoRepType "DataCon"
instance Outputable HsBang where instance Outputable HsBang where
ppr HsNoBang = empty ppr HsNoBang = empty
ppr (HsUserBang prag bang) = pp_unpk prag <+> ppWhen bang (char '!') ppr (HsSrcBang _ prag bang) = pp_unpk prag <+> ppWhen bang (char '!')
ppr (HsUnpack Nothing) = ptext (sLit "Unpk") ppr (HsUnpack Nothing) = ptext (sLit "Unpk")
ppr (HsUnpack (Just co)) = ptext (sLit "Unpk") <> parens (ppr co) ppr (HsUnpack (Just co)) = ptext (sLit "Unpk") <> parens (ppr co)
ppr HsStrict = ptext (sLit "SrictNotUnpacked") ppr HsStrict = ptext (sLit "SrictNotUnpacked")
pp_unpk :: Maybe Bool -> SDoc pp_unpk :: Maybe Bool -> SDoc
pp_unpk Nothing = empty pp_unpk Nothing = empty
...@@ -558,15 +596,16 @@ instance Outputable StrictnessMark where ...@@ -558,15 +596,16 @@ instance Outputable StrictnessMark where
eqHsBang :: HsBang -> HsBang -> Bool eqHsBang :: HsBang -> HsBang -> Bool
eqHsBang HsNoBang HsNoBang = True eqHsBang HsNoBang HsNoBang = True
eqHsBang HsStrict HsStrict = True eqHsBang HsStrict HsStrict = True
eqHsBang (HsUserBang u1 b1) (HsUserBang u2 b2) = u1==u2 && b1==b2 eqHsBang (HsSrcBang _ u1 b1) (HsSrcBang _ u2 b2) = u1==u2 && b1==b2
eqHsBang (HsUnpack Nothing) (HsUnpack Nothing) = True eqHsBang (HsUnpack Nothing) (HsUnpack Nothing) = True
eqHsBang (HsUnpack (Just c1)) (HsUnpack (Just c2)) = eqType (coercionType c1) (coercionType c2) eqHsBang (HsUnpack (Just c1)) (HsUnpack (Just c2)) = eqType (coercionType c1) (coercionType c2)
eqHsBang _ _ = False eqHsBang _ _ = False
isBanged :: HsBang -> Bool isBanged :: HsBang -> Bool
isBanged HsNoBang = False isBanged HsNoBang = False
isBanged (HsUserBang Nothing bang) = bang isBanged (HsSrcBang _ _ bang) = bang
isBanged _ = True isBanged (HsUnpack {}) = True
isBanged (HsStrict {}) = True
isMarkedStrict :: StrictnessMark -> Bool isMarkedStrict :: StrictnessMark -> Bool
isMarkedStrict NotMarkedStrict = False isMarkedStrict NotMarkedStrict = False
...@@ -583,7 +622,8 @@ isMarkedStrict _ = True -- All others are strict ...@@ -583,7 +622,8 @@ isMarkedStrict _ = True -- All others are strict
-- | Build a new data constructor -- | Build a new data constructor
mkDataCon :: Name mkDataCon :: Name
-> Bool -- ^ Is the constructor declared infix? -> Bool -- ^ Is the constructor declared infix?
-> [HsBang] -- ^ Strictness annotations written in the source file -> [HsBang] -- ^ Strictness/unpack annotations, from user;
-- or, for imported DataCons, from the interface file
-> [FieldLabel] -- ^ Field labels for the constructor, if it is a record, -> [FieldLabel] -- ^ Field labels for the constructor, if it is a record,
-- otherwise empty -- otherwise empty
-> [TyVar] -- ^ Universally quantified type variables -> [TyVar] -- ^ Universally quantified type variables
...@@ -626,7 +666,7 @@ mkDataCon name declared_infix ...@@ -626,7 +666,7 @@ mkDataCon name declared_infix
dcStupidTheta = stupid_theta, dcStupidTheta = stupid_theta,
dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty, dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty,
dcRepTyCon = rep_tycon, dcRepTyCon = rep_tycon,
dcArgBangs = arg_stricts, dcSrcBangs = arg_stricts,
dcFields = fields, dcTag = tag, dcRepType = rep_ty, dcFields = fields, dcTag = tag, dcRepType = rep_ty,
dcWorkId = work_id, dcWorkId = work_id,
dcRep = rep, dcRep = rep,
...@@ -764,10 +804,10 @@ dataConFieldType con label ...@@ -764,10 +804,10 @@ dataConFieldType con label
Just ty -> ty Just ty -> ty
Nothing -> pprPanic "dataConFieldType" (ppr con <+> ppr label) Nothing -> pprPanic "dataConFieldType" (ppr con <+> ppr label)
-- | The strictness markings decided on by the compiler. Does not include those for -- | The strictness markings written by the porgrammer.
-- existential dictionaries. The list is in one-to-one correspondence with the arity of the 'DataCon' -- The list is in one-to-one correspondence with the arity of the 'DataCon'
dataConStrictMarks :: DataCon -> [HsBang] dataConSrcBangs :: DataCon -> [HsSrcBang]
dataConStrictMarks = dcArgBangs dataConSrcBangs = dcSrcBangs
-- | Source-level arity of the data constructor -- | Source-level arity of the data constructor
dataConSourceArity :: DataCon -> Arity dataConSourceArity :: DataCon -> Arity
...@@ -800,10 +840,13 @@ dataConRepStrictness dc = case dcRep dc of ...@@ -800,10 +840,13 @@ dataConRepStrictness dc = case dcRep dc of
NoDataConRep -> [NotMarkedStrict | _ <- dataConRepArgTys dc] NoDataConRep -> [NotMarkedStrict | _ <- dataConRepArgTys dc]
DCR { dcr_stricts = strs } -> strs DCR { dcr_stricts = strs } -> strs
dataConRepBangs :: DataCon -> [HsBang] dataConImplBangs :: DataCon -> [HsImplBang]
dataConRepBangs dc = case dcRep dc of -- The implementation decisions about the strictness/unpack of each
NoDataConRep -> dcArgBangs dc -- source program argument to the data constructor
DCR { dcr_bangs = bangs } -> bangs dataConImplBangs dc
= case dcRep dc of
NoDataConRep -> replicate (dcSourceArity dc) HsNoBang
DCR { dcr_bangs = bangs } -> bangs
dataConBoxer :: DataCon -> Maybe DataConBoxer dataConBoxer :: DataCon -> Maybe DataConBoxer
dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer
......
...@@ -18,6 +18,7 @@ module Demand ( ...@@ -18,6 +18,7 @@ module Demand (
lubDmd, bothDmd, apply1Dmd, apply2Dmd, lubDmd, bothDmd, apply1Dmd, apply2Dmd,
isTopDmd, isBotDmd, isAbsDmd, isSeqDmd, isTopDmd, isBotDmd, isAbsDmd, isSeqDmd,
peelUseCall, cleanUseDmd_maybe, strictenDmd, bothCleanDmd, peelUseCall, cleanUseDmd_maybe, strictenDmd, bothCleanDmd,
addCaseBndrDmd,
DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType, DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType,
nopDmdType, botDmdType, mkDmdType, nopDmdType, botDmdType, mkDmdType,
...@@ -25,7 +26,7 @@ module Demand ( ...@@ -25,7 +26,7 @@ module Demand (
BothDmdArg, mkBothDmdArg, toBothDmdArg, BothDmdArg, mkBothDmdArg, toBothDmdArg,
DmdEnv, emptyDmdEnv, DmdEnv, emptyDmdEnv,
peelFV, peelFV, findIdDemand,
DmdResult, CPRResult, DmdResult, CPRResult,
isBotRes, isTopRes, isBotRes, isTopRes,
...@@ -47,8 +48,8 @@ module Demand ( ...@@ -47,8 +48,8 @@ module Demand (
argOneShots, argsOneShots, argOneShots, argsOneShots,
trimToType, TypeShape(..), trimToType, TypeShape(..),
isSingleUsed, reuseEnv, zapDemand, zapStrictSig, isSingleUsed, reuseEnv,
killUsageDemand, killUsageSig, zapUsageDemand,
strictifyDictDmd strictifyDictDmd
) where ) where
...@@ -200,6 +201,10 @@ seqMaybeStr Lazy = () ...@@ -200,6 +201,10 @@ seqMaybeStr Lazy = ()
seqMaybeStr (Str s) = seqStrDmd s seqMaybeStr (Str s) = seqStrDmd s
-- Splitting polymorphic demands -- Splitting polymorphic demands
splitMaybeStrProdDmd :: Int -> MaybeStr -> Maybe [MaybeStr]
splitMaybeStrProdDmd n Lazy = Just (replicate n Lazy)
splitMaybeStrProdDmd n (Str s) = splitStrProdDmd n s
splitStrProdDmd :: Int -> StrDmd -> Maybe [MaybeStr] splitStrProdDmd :: Int -> StrDmd -> Maybe [MaybeStr]
splitStrProdDmd n HyperStr = Just (replicate n strBot) splitStrProdDmd n HyperStr = Just (replicate n strBot)
splitStrProdDmd n HeadStr = Just (replicate n strTop) splitStrProdDmd n HeadStr = Just (replicate n strTop)
...@@ -352,7 +357,49 @@ peelUseCall :: UseDmd -> Maybe (Count, UseDmd) ...@@ -352,7 +357,49 @@ peelUseCall :: UseDmd -> Maybe (Count, UseDmd)
peelUseCall (UCall c u) = Just (c,u) peelUseCall (UCall c u) = Just (c,u)
peelUseCall _ = Nothing peelUseCall _ = Nothing
{- addCaseBndrDmd :: Demand -- On the case binder
-> [Demand] -- On the components of the constructor
-> [Demand] -- Final demands for the components of the constructor
-- See Note [Demand on case-alternative binders]
addCaseBndrDmd (JD { strd = ms, absd = mu }) alt_dmds
= case mu of
Abs -> alt_dmds
Use _ u -> zipWith bothDmd alt_dmds (mkJointDmds ss us)
where
Just ss = splitMaybeStrProdDmd arity ms -- Guaranteed not to be a call
Just us = splitUseProdDmd arity u -- Ditto
where
arity = length alt_dmds
{- Note [Demand on case-alternative binders]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The demand on a binder in a case alternative comes
(a) From the demand on the binder itself
(b) From the demand on the case binder
Forgetting (b) led directly to Trac #10148.
Example. Source code:
f x@(p,_) = if p then foo x else True
foo (p,True) = True
foo (p,q) = foo (q,p)
After strictness analysis:
f = \ (x_an1 [Dmd=<S(SL),1*U(U,1*U)>] :: (Bool, Bool)) ->
case x_an1
of wild_X7 [Dmd=<L,1*U(1*U,1*U)>]
{ (p_an2 [Dmd=<S,1*U>], ds_dnz [Dmd=<L,A>]) ->
case p_an2 of _ {
False -> GHC.Types.True;
True -> foo wild_X7 }
It's true that ds_dnz is *itself* absent, b ut the use of wild_X7 means
that it is very much alive and demanded. See Trac #10148 for how the
consequences play out.
This is needed even for non-product types, in case the case-binder
is used but the components of the case alternative are not.
Note [Don't optimise UProd(Used) to Used] Note [Don't optimise UProd(Used) to Used]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These two UseDmds: These two UseDmds:
...@@ -586,7 +633,8 @@ f g = (snd (g 3), True) ...@@ -586,7 +633,8 @@ f g = (snd (g 3), True)
should be: <L,C(U(AU))>m should be: <L,C(U(AU))>m
-} -}
data CleanDemand = CD { sd :: StrDmd, ud :: UseDmd } data CleanDemand -- A demand that is at least head-strict
= CD { sd :: StrDmd, ud :: UseDmd }
deriving ( Eq, Show ) deriving ( Eq, Show )
instance Outputable CleanDemand where instance Outputable CleanDemand where
...@@ -1339,6 +1387,10 @@ peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) ...@@ -1339,6 +1387,10 @@ peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv)
addDemand :: Demand -> DmdType -> DmdType addDemand :: Demand -> DmdType -> DmdType
addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res
findIdDemand :: DmdType -> Var -> Demand
findIdDemand (DmdType fv _ res) id
= lookupVarEnv fv id `orElse` defaultDmd res
{- {-
Note [Default demand on free variables] Note [Default demand on free variables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -1663,21 +1715,34 @@ of arguments, says conservatively if the function is going to diverge ...@@ -1663,21 +1715,34 @@ of arguments, says conservatively if the function is going to diverge
or not. or not.
Zap absence or one-shot information, under control of flags Zap absence or one-shot information, under control of flags
Note [Killing usage information]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The flags -fkill-one-shot and -fkill-absence let you switch off the generation
of absence or one-shot information altogether. This is only used for performance
tests, to see how important they are.
-} -}
zapDemand :: DynFlags -> Demand -> Demand zapUsageDemand :: Demand -> Demand
zapDemand dflags dmd -- Remove the usage info, but not the strictness info, from the demand
| Just kfs <- killFlags dflags = zap_dmd kfs dmd zapUsageDemand = kill_usage (True, True)
killUsageDemand :: DynFlags -> Demand -> Demand
-- See Note [Killing usage information]
killUsageDemand dflags dmd
| Just kfs <- killFlags dflags = kill_usage kfs dmd
| otherwise = dmd | otherwise = dmd
zapStrictSig :: DynFlags -> StrictSig -> StrictSig killUsageSig :: DynFlags -> StrictSig -> StrictSig
zapStrictSig dflags sig@(StrictSig (DmdType env ds r)) -- See Note [Killing usage information]
| Just kfs <- killFlags dflags = StrictSig (DmdType env (map (zap_dmd kfs) ds) r) killUsageSig dflags sig@(StrictSig (DmdType env ds r))
| Just kfs <- killFlags dflags = StrictSig (DmdType env (map (kill_usage kfs) ds) r)
| otherwise = sig | otherwise = sig
type KillFlags = (Bool, Bool) type KillFlags = (Bool, Bool)
killFlags :: DynFlags -> Maybe KillFlags killFlags :: DynFlags -> Maybe KillFlags
-- See Note [Killing usage information]
killFlags dflags killFlags dflags
| not kill_abs && not kill_one_shot = Nothing | not kill_abs && not kill_one_shot = Nothing
| otherwise = Just (kill_abs, kill_one_shot) | otherwise = Just (kill_abs, kill_one_shot)
...@@ -1685,8 +1750,8 @@ killFlags dflags ...@@ -1685,8 +1750,8 @@ killFlags dflags
kill_abs = gopt Opt_KillAbsence dflags kill_abs = gopt Opt_KillAbsence dflags
kill_one_shot = gopt Opt_KillOneShot dflags kill_one_shot = gopt Opt_KillOneShot dflags
zap_dmd :: KillFlags -> Demand -> Demand kill_usage :: KillFlags -> Demand -> Demand
zap_dmd kfs (JD {strd = s, absd = u}) = JD {strd = s, absd = zap_musg kfs u} kill_usage kfs (JD {strd = s, absd = u}) = JD {strd = s, absd = zap_musg kfs u}
zap_musg :: KillFlags -> MaybeUsed -> MaybeUsed zap_musg :: KillFlags -> MaybeUsed -> MaybeUsed
zap_musg (kill_abs, _) Abs zap_musg (kill_abs, _) Abs
......
...@@ -45,8 +45,9 @@ module Id ( ...@@ -45,8 +45,9 @@ module Id (
setIdExported, setIdNotExported, setIdExported, setIdNotExported,
globaliseId, localiseId, globaliseId, localiseId,
setIdInfo, lazySetIdInfo, modifyIdInfo, maybeModifyIdInfo, setIdInfo, lazySetIdInfo, modifyIdInfo, maybeModifyIdInfo,
zapLamIdInfo, zapDemandIdInfo, zapFragileIdInfo, transferPolyIdInfo, zapLamIdInfo, zapIdDemandInfo, zapIdUsageInfo, zapFragileIdInfo,
zapIdStrictness, zapIdStrictness,
transferPolyIdInfo,
-- ** Predicates on Ids -- ** Predicates on Ids
isImplicitId, isDeadBinder, isImplicitId, isDeadBinder,
...@@ -738,8 +739,11 @@ zapLamIdInfo = zapInfo zapLamInfo ...@@ -738,8 +739,11 @@ zapLamIdInfo = zapInfo zapLamInfo
zapFragileIdInfo :: Id -> Id zapFragileIdInfo :: Id -> Id
zapFragileIdInfo = zapInfo zapFragileInfo zapFragileIdInfo = zapInfo zapFragileInfo
zapDemandIdInfo :: Id -> Id zapIdDemandInfo :: Id -> Id
zapDemandIdInfo = zapInfo zapDemandInfo zapIdDemandInfo = zapInfo zapDemandInfo
zapIdUsageInfo :: Id -> Id
zapIdUsageInfo = zapInfo zapUsageInfo
{- {-
Note [transferPolyIdInfo] Note [transferPolyIdInfo]
......
...@@ -24,7 +24,7 @@ module IdInfo ( ...@@ -24,7 +24,7 @@ module IdInfo (
-- ** Zapping various forms of Info -- ** Zapping various forms of Info
zapLamInfo, zapFragileInfo, zapLamInfo, zapFragileInfo,
zapDemandInfo, zapDemandInfo, zapUsageInfo,
-- ** The ArityInfo type -- ** The ArityInfo type
ArityInfo, ArityInfo,
...@@ -484,10 +484,14 @@ zapLamInfo info@(IdInfo {occInfo = occ, demandInfo = demand}) ...@@ -484,10 +484,14 @@ zapLamInfo info@(IdInfo {occInfo = occ, demandInfo = demand})
is_safe_dmd dmd = not (isStrictDmd dmd) is_safe_dmd dmd = not (isStrictDmd dmd)
-- | Remove demand info on the 'IdInfo' if it is present, otherwise return @Nothing@ -- | Remove all demand info on the 'IdInfo'
zapDemandInfo :: IdInfo -> Maybe IdInfo zapDemandInfo :: IdInfo -> Maybe IdInfo
zapDemandInfo info = Just (info {demandInfo = topDmd}) zapDemandInfo info = Just (info {demandInfo = topDmd})
-- | Remove usage (but not strictness) info on the 'IdInfo'
zapUsageInfo :: IdInfo -> Maybe IdInfo
zapUsageInfo info = Just (info {demandInfo = zapUsageDemand (demandInfo info)})
zapFragileInfo :: IdInfo -> Maybe IdInfo zapFragileInfo :: IdInfo -> Maybe IdInfo
-- ^ Zap info that depends on free variables -- ^ Zap info that depends on free variables
zapFragileInfo info zapFragileInfo info
......
...@@ -28,6 +28,7 @@ module Lexeme ( ...@@ -28,6 +28,7 @@ module Lexeme (
) where ) where
import FastString import FastString
import Util ((<||>))
import Data.Char import Data.Char
import qualified Data.Set as Set import qualified Data.Set as Set
...@@ -194,7 +195,8 @@ okConSymOcc str = all okSymChar str && ...@@ -194,7 +195,8 @@ okConSymOcc str = all okSymChar str &&
-- but not worrying about case or clashing with reserved words? -- but not worrying about case or clashing with reserved words?
okIdOcc :: String -> Bool okIdOcc :: String -> Bool
okIdOcc str okIdOcc str
= let hashes = dropWhile okIdChar str in -- TODO. #10196. Only allow modifier letters in the suffix of an identifier.
= let hashes = dropWhile (okIdChar <||> okIdSuffixChar) str in
all (== '#') hashes -- -XMagicHash allows a suffix of hashes all (== '#') hashes -- -XMagicHash allows a suffix of hashes
-- of course, `all` says "True" to an empty list -- of course, `all` says "True" to an empty list
...@@ -210,6 +212,13 @@ okIdChar c = case generalCategory c of ...@@ -210,6 +212,13 @@ okIdChar c = case generalCategory c of
OtherNumber -> True OtherNumber -> True
_ -> c == '\'' || c == '_' _ -> c == '\'' || c == '_'
-- | Is this character acceptable in the suffix of an identifier.
-- See alexGetByte in Lexer.x
okIdSuffixChar :: Char -> Bool
okIdSuffixChar c = case generalCategory c of
ModifierLetter -> True -- See #10196
_ -> False
-- | Is this character acceptable in a symbol (after the first char)? -- | Is this character acceptable in a symbol (after the first char)?
-- See alexGetByte in Lexer.x -- See alexGetByte in Lexer.x
okSymChar :: Char -> Bool okSymChar :: Char -> Bool
......
...@@ -32,6 +32,7 @@ module MkId ( ...@@ -32,6 +32,7 @@ module MkId (
voidPrimId, voidArgId, voidPrimId, voidArgId,
nullAddrId, seqId, lazyId, lazyIdKey, nullAddrId, seqId, lazyId, lazyIdKey,
coercionTokenId, magicDictId, coerceId, coercionTokenId, magicDictId, coerceId,
proxyHashId,
-- Re-export error Ids -- Re-export error Ids
module PrelRules module PrelRules
...@@ -519,7 +520,7 @@ mkDataConRep dflags fam_envs wrap_name data_con ...@@ -519,7 +520,7 @@ mkDataConRep dflags fam_envs wrap_name data_con
wrap_ty = dataConUserType data_con wrap_ty = dataConUserType data_con
ev_tys = eqSpecPreds eq_spec ++ theta ev_tys = eqSpecPreds eq_spec ++ theta
all_arg_tys = ev_tys ++ orig_arg_tys all_arg_tys = ev_tys ++ orig_arg_tys
orig_bangs = map mk_pred_strict_mark ev_tys ++ dataConStrictMarks data_con orig_bangs = map mk_pred_strict_mark ev_tys ++ dataConSrcBangs data_con
wrap_arg_tys = theta ++ orig_arg_tys wrap_arg_tys = theta ++ orig_arg_tys
wrap_arity = length wrap_arg_tys wrap_arity = length wrap_arg_tys
...@@ -580,19 +581,26 @@ newLocal ty = do { uniq <- getUniqueM ...@@ -580,19 +581,26 @@ newLocal ty = do { uniq <- getUniqueM
dataConArgRep dataConArgRep
:: DynFlags :: DynFlags
-> FamInstEnvs -> FamInstEnvs
-> Type -> HsBang -> Type
-> ( HsBang -- Like input but with HsUnpackFailed if necy -> HsSrcBang -- For DataCons defined in this module, this is the
-- bang/unpack annotation that the programmer wrote
-- For DataCons imported from an interface file, this
-- is the HsImplBang implementation decision taken
-- by the compiler in the defining module; just follow
-- it slavishly, so that we make the same decision as
-- in the defining module
-> ( HsImplBang -- Implementation decision about unpack strategy
, [(Type, StrictnessMark)] -- Rep types , [(Type, StrictnessMark)] -- Rep types
, (Unboxer, Boxer) ) , (Unboxer, Boxer) )
dataConArgRep _ _ arg_ty HsNoBang dataConArgRep _ _ arg_ty HsNoBang
= (HsNoBang, [(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer)) = (HsNoBang, [(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer))
dataConArgRep _ _ arg_ty (HsUserBang _ False) -- No '!' dataConArgRep _ _ arg_ty (HsSrcBang _ _ False) -- No '!'
= (HsNoBang, [(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer)) = (HsNoBang, [(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer))
dataConArgRep dflags fam_envs arg_ty dataConArgRep dflags fam_envs arg_ty
(HsUserBang unpk_prag True) -- {-# UNPACK #-} ! (HsSrcBang _ unpk_prag True) -- {-# UNPACK #-} !
| not (gopt Opt_OmitInterfacePragmas dflags) -- Don't unpack if -fomit-iface-pragmas | not (gopt Opt_OmitInterfacePragmas dflags) -- Don't unpack if -fomit-iface-pragmas
-- Don't unpack if we aren't optimising; rather arbitrarily, -- Don't unpack if we aren't optimising; rather arbitrarily,
-- we use -fomit-iface-pragmas as the indication -- we use -fomit-iface-pragmas as the indication
...@@ -625,7 +633,7 @@ dataConArgRep _ _ _ (HsUnpack (Just co)) ...@@ -625,7 +633,7 @@ dataConArgRep _ _ _ (HsUnpack (Just co))
, (rep_tys, wrappers) <- dataConArgUnpack co_rep_ty , (rep_tys, wrappers) <- dataConArgUnpack co_rep_ty
= (HsUnpack (Just co), rep_tys, wrapCo co co_rep_ty wrappers) = (HsUnpack (Just co), rep_tys, wrapCo co co_rep_ty wrappers)
strict_but_not_unpacked :: Type -> (HsBang, [(Type,StrictnessMark)], (Unboxer, Boxer)) strict_but_not_unpacked :: Type -> (HsImplBang, [(Type,StrictnessMark)], (Unboxer, Boxer))
strict_but_not_unpacked arg_ty strict_but_not_unpacked arg_ty
= (HsStrict, [(arg_ty, MarkedStrict)], (seqUnboxer, unitBoxer)) = (HsStrict, [(arg_ty, MarkedStrict)], (seqUnboxer, unitBoxer))
...@@ -716,15 +724,15 @@ isUnpackableType fam_envs ty ...@@ -716,15 +724,15 @@ isUnpackableType fam_envs ty
= True = True
ok_con_args tcs con ok_con_args tcs con
= all (ok_arg tcs) (dataConOrigArgTys con `zip` dataConStrictMarks con) = all (ok_arg tcs) (dataConOrigArgTys con `zip` dataConSrcBangs con)
-- NB: dataConStrictMarks gives the *user* request; -- NB: dataConSrcBangs gives the *user* request;
-- We'd get a black hole if we used dataConRepBangs -- We'd get a black hole if we used dataConImplBangs
attempt_unpack (HsUnpack {}) = True attempt_unpack (HsUnpack {}) = True
attempt_unpack (HsUserBang (Just unpk) bang) = bang && unpk attempt_unpack (HsSrcBang _ (Just unpk) bang) = bang && unpk
attempt_unpack (HsUserBang Nothing bang) = bang -- Be conservative attempt_unpack (HsSrcBang _ Nothing bang) = bang -- Be conservative
attempt_unpack HsStrict = False attempt_unpack HsStrict = False
attempt_unpack HsNoBang = False attempt_unpack HsNoBang = False
{- {-
Note [Unpack one-wide fields] Note [Unpack one-wide fields]
...@@ -789,7 +797,7 @@ heavy lifting. This one line makes every GADT take a word less ...@@ -789,7 +797,7 @@ heavy lifting. This one line makes every GADT take a word less
space for each equality predicate, so it's pretty important! space for each equality predicate, so it's pretty important!
-} -}
mk_pred_strict_mark :: PredType -> HsBang mk_pred_strict_mark :: PredType -> HsSrcBang
mk_pred_strict_mark pred mk_pred_strict_mark pred
| isEqPred pred = HsUnpack Nothing -- Note [Unpack equality predicates] | isEqPred pred = HsUnpack Nothing -- Note [Unpack equality predicates]
| otherwise = HsNoBang | otherwise = HsNoBang
...@@ -1078,10 +1086,15 @@ nullAddrId = pcMiscPrelId nullAddrName addrPrimTy info ...@@ -1078,10 +1086,15 @@ nullAddrId = pcMiscPrelId nullAddrName addrPrimTy info
seqId :: Id -- See Note [seqId magic] seqId :: Id -- See Note [seqId magic]
seqId = pcMiscPrelId seqName ty info seqId = pcMiscPrelId seqName ty info
where where
info = noCafIdInfo `setInlinePragInfo` alwaysInlinePragma info = noCafIdInfo `setInlinePragInfo` inline_prag
`setUnfoldingInfo` mkCompulsoryUnfolding rhs `setUnfoldingInfo` mkCompulsoryUnfolding rhs
`setSpecInfo` mkSpecInfo [seq_cast_rule] `setSpecInfo` mkSpecInfo [seq_cast_rule]
inline_prag = alwaysInlinePragma `setInlinePragmaActivation` ActiveAfter 0
-- Make 'seq' not inline-always, so that simpleOptExpr
-- (see CoreSubst.simple_app) won't inline 'seq' on the
-- LHS of rules. That way we can have rules for 'seq';
-- see Note [seqId magic]
ty = mkForAllTys [alphaTyVar,betaTyVar] ty = mkForAllTys [alphaTyVar,betaTyVar]
(mkFunTy alphaTy (mkFunTy betaTy betaTy)) (mkFunTy alphaTy (mkFunTy betaTy betaTy))
...@@ -1091,17 +1104,18 @@ seqId = pcMiscPrelId seqName ty info ...@@ -1091,17 +1104,18 @@ seqId = pcMiscPrelId seqName ty info
rhs = mkLams [alphaTyVar,betaTyVar,x,y] (Case (Var x) x betaTy [(DEFAULT, [], Var y)]) rhs = mkLams [alphaTyVar,betaTyVar,x,y] (Case (Var x) x betaTy [(DEFAULT, [], Var y)])
-- See Note [Built-in RULES for seq] -- See Note [Built-in RULES for seq]
-- NB: ru_nargs = 3, not 4, to match the code in
-- Simplify.rebuildCase which tries to apply this rule
seq_cast_rule = BuiltinRule { ru_name = fsLit "seq of cast" seq_cast_rule = BuiltinRule { ru_name = fsLit "seq of cast"
, ru_fn = seqName , ru_fn = seqName
, ru_nargs = 4 , ru_nargs = 3
, ru_try = match_seq_of_cast , ru_try = match_seq_of_cast }
}
match_seq_of_cast :: RuleFun match_seq_of_cast :: RuleFun
-- See Note [Built-in RULES for seq] -- See Note [Built-in RULES for seq]
match_seq_of_cast _ _ _ [Type _, Type res_ty, Cast scrut co, expr] match_seq_of_cast _ _ _ [Type _, Type res_ty, Cast scrut co]
= Just (Var seqId `mkApps` [Type (pFst (coercionKind co)), Type res_ty, = Just (Var seqId `mkApps` [Type (pFst (coercionKind co)), Type res_ty,
scrut, expr]) scrut])
match_seq_of_cast _ _ _ _ = Nothing match_seq_of_cast _ _ _ _ = Nothing
------------------------------------------------ ------------------------------------------------
...@@ -1207,16 +1221,24 @@ transform to ...@@ -1207,16 +1221,24 @@ transform to
Rather than attempt some general analysis to support this, I've added Rather than attempt some general analysis to support this, I've added
enough support that you can do this using a rewrite rule: enough support that you can do this using a rewrite rule:
RULE "f/seq" forall n. seq (f n) e = seq n e RULE "f/seq" forall n. seq (f n) = seq n
You write that rule. When GHC sees a case expression that discards You write that rule. When GHC sees a case expression that discards
its result, it mentally transforms it to a call to 'seq' and looks for its result, it mentally transforms it to a call to 'seq' and looks for
a RULE. (This is done in Simplify.rebuildCase.) As usual, the a RULE. (This is done in Simplify.rebuildCase.) As usual, the
correctness of the rule is up to you. correctness of the rule is up to you.
To make this work, we need to be careful that the magical desugaring VERY IMPORTANT: to make this work, we give the RULE an arity of 1, not 2.
done in Note [seqId magic] item (c) is *not* done on the LHS of a rule. If we wrote
Or rather, we arrange to un-do it, in DsBinds.decomposeRuleLhs. RULE "f/seq" forall n e. seq (f n) e = seq n e
with rule arity 2, then two bad things would happen:
- The magical desugaring done in Note [seqId magic] item (c)
for saturated application of 'seq' would turn the LHS into
a case expression!
- The code in Simplify.rebuildCase would need to actually supply
the value argument, which turns out to be awkward.
Note [Built-in RULES for seq] Note [Built-in RULES for seq]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -326,11 +326,13 @@ stablePackageKeyCmp p1 p2 = packageKeyFS p1 `compare` packageKeyFS p2 ...@@ -326,11 +326,13 @@ stablePackageKeyCmp p1 p2 = packageKeyFS p1 `compare` packageKeyFS p2
instance Outputable PackageKey where instance Outputable PackageKey where
ppr pk = getPprStyle $ \sty -> sdocWithDynFlags $ \dflags -> ppr pk = getPprStyle $ \sty -> sdocWithDynFlags $ \dflags ->
text (packageKeyPackageIdString dflags pk) case packageKeyPackageIdString dflags pk of
-- Don't bother qualifying if it's wired in! Nothing -> ftext (packageKeyFS pk)
<> (if qualPackage sty pk && not (pk `elem` wiredInPackageKeys) Just pkg -> text pkg
then char '@' <> ftext (packageKeyFS pk) -- Don't bother qualifying if it's wired in!
else empty) <> (if qualPackage sty pk && not (pk `elem` wiredInPackageKeys)
then char '@' <> ftext (packageKeyFS pk)
else empty)
instance Binary PackageKey where instance Binary PackageKey where
put_ bh pid = put_ bh (packageKeyFS pid) put_ bh pid = put_ bh (packageKeyFS pid)
......
...@@ -189,7 +189,6 @@ nameSrcSpan name = n_loc name ...@@ -189,7 +189,6 @@ nameSrcSpan name = n_loc name
************************************************************************ ************************************************************************
-} -}
nameIsLocalOrFrom :: Module -> Name -> Bool
isInternalName :: Name -> Bool isInternalName :: Name -> Bool
isExternalName :: Name -> Bool isExternalName :: Name -> Bool
isSystemName :: Name -> Bool isSystemName :: Name -> Bool
...@@ -218,9 +217,32 @@ nameModule_maybe (Name { n_sort = External mod}) = Just mod ...@@ -218,9 +217,32 @@ nameModule_maybe (Name { n_sort = External mod}) = Just mod
nameModule_maybe (Name { n_sort = WiredIn mod _ _}) = Just mod nameModule_maybe (Name { n_sort = WiredIn mod _ _}) = Just mod
nameModule_maybe _ = Nothing nameModule_maybe _ = Nothing
nameIsLocalOrFrom :: Module -> Name -> Bool
-- ^ Returns True if the name is
-- (a) Internal
-- (b) External but from the specified module
-- (c) External but from the 'interactive' package
--
-- The key idea is that
-- False means: the entity is defined in some other module
-- you can find the details (type, fixity, instances)
-- in some interface file
-- those details will be stored in the EPT or HPT
--
-- True means: the entity is defined in this module or earlier in
-- the GHCi session
-- you can find details (type, fixity, instances) in the
-- TcGblEnv or TcLclEnv
--
-- The isInteractiveModule part is because successive interactions of a GCHi session
-- each give rise to a fresh module (Ghci1, Ghci2, etc), but they all come
-- from the magic 'interactive' package; and all the details are kept in the
-- TcLclEnv, TcGblEnv, NOT in the HPT or EPT.
-- See Note [The interactive package] in HscTypes
nameIsLocalOrFrom from name nameIsLocalOrFrom from name
| isExternalName name = from == nameModule name | Just mod <- nameModule_maybe name = from == mod || isInteractiveModule mod
| otherwise = True | otherwise = True
isTyVarName :: Name -> Bool isTyVarName :: Name -> Bool
isTyVarName name = isTvOcc (nameOccName name) isTyVarName name = isTvOcc (nameOccName name)
...@@ -334,7 +356,8 @@ localiseName n = n { n_sort = Internal } ...@@ -334,7 +356,8 @@ localiseName n = n { n_sort = Internal }
-- |Create a localised variant of a name. -- |Create a localised variant of a name.
-- --
-- If the name is external, encode the original's module name to disambiguate. -- If the name is external, encode the original's module name to disambiguate.
-- -- SPJ says: this looks like a rather odd-looking function; but it seems to
-- be used only during vectorisation, so I'm not going to worry
mkLocalisedOccName :: Module -> (Maybe String -> OccName -> OccName) -> Name -> OccName mkLocalisedOccName :: Module -> (Maybe String -> OccName -> OccName) -> Name -> OccName
mkLocalisedOccName this_mod mk_occ name = mk_occ origin (nameOccName name) mkLocalisedOccName this_mod mk_occ name = mk_occ origin (nameOccName name)
where where
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
(c) The GRASP/AQUA Project, Glasgow University, 1992-1998 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-} -}
{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveDataTypeable, BangPatterns #-}
-- | -- |
-- #name_types# -- #name_types#
...@@ -793,6 +793,29 @@ type TidyOccEnv = UniqFM Int ...@@ -793,6 +793,29 @@ type TidyOccEnv = UniqFM Int
* When looking for a renaming for "foo2" we strip off the "2" and start * When looking for a renaming for "foo2" we strip off the "2" and start
with "foo". Otherwise if we tidy twice we get silly names like foo23. with "foo". Otherwise if we tidy twice we get silly names like foo23.
However, if it started with digits at the end, we always make a name
with digits at the end, rather than shortening "foo2" to just "foo",
even if "foo" is unused. Reasons:
- Plain "foo" might be used later
- We use trailing digits to subtly indicate a unification variable
in typechecker error message; see TypeRep.tidyTyVarBndr
We have to take care though! Consider a machine-generated module (Trac #10370)
module Foo where
a1 = e1
a2 = e2
...
a2000 = e2000
Then "a1", "a2" etc are all marked taken. But now if we come across "a7" again,
we have to do a linear search to find a free one, "a20001". That might just be
acceptable once. But if we now come across "a8" again, we don't want to repeat
that search.
So we use the TidyOccEnv mapping for "a" (not "a7" or "a8") as our base for
starting the search; and we make sure to update the starting point for "a"
after we allocate a new one.
-} -}
type TidyOccEnv = UniqFM Int -- The in-scope OccNames type TidyOccEnv = UniqFM Int -- The in-scope OccNames
...@@ -809,24 +832,30 @@ initTidyOccEnv = foldl add emptyUFM ...@@ -809,24 +832,30 @@ initTidyOccEnv = foldl add emptyUFM
tidyOccName :: TidyOccEnv -> OccName -> (TidyOccEnv, OccName) tidyOccName :: TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
tidyOccName env occ@(OccName occ_sp fs) tidyOccName env occ@(OccName occ_sp fs)
= case lookupUFM env fs of = case lookupUFM env fs of
Just n -> find n Nothing -> (addToUFM env fs 1, occ) -- Desired OccName is free
Nothing -> (addToUFM env fs 1, occ) Just {} -> case lookupUFM env base1 of
Nothing -> (addToUFM env base1 2, OccName occ_sp base1)
Just n -> find 1 n
where where
base :: String -- Drop trailing digits (see Note [TidyOccEnv]) base :: String -- Drop trailing digits (see Note [TidyOccEnv])
base = dropWhileEndLE isDigit (unpackFS fs) base = dropWhileEndLE isDigit (unpackFS fs)
base1 = mkFastString (base ++ "1")
find n find !k !n
= case lookupUFM env new_fs of = case lookupUFM env new_fs of
Just n' -> find (n1 `max` n') Just {} -> find (k+1 :: Int) (n+k)
-- The max ensures that n increases, avoiding loops -- By using n+k, the n arguemt to find goes
Nothing -> (addToUFM (addToUFM env fs n1) new_fs n1, -- 1, add 1, add 2, add 3, etc which
OccName occ_sp new_fs) -- moves at quadratic speed through a dense patch
-- We update only the beginning and end of the
-- chain that find explores; it's a little harder to Nothing -> (new_env, OccName occ_sp new_fs)
-- update the middle and there's no real need.
where where
n1 = n+1
new_fs = mkFastString (base ++ show n) new_fs = mkFastString (base ++ show n)
new_env = addToUFM (addToUFM env new_fs 1) base1 (n+1)
-- Update: base_fs, so that next time we'll start whwere we left off
-- new_fs, so that we know it is taken
-- If they are the same (n==1), the former wins
-- See Note [TidyOccEnv]
{- {-
************************************************************************ ************************************************************************
......
...@@ -86,6 +86,22 @@ import Data.Data ...@@ -86,6 +86,22 @@ import Data.Data
-- | Do not use the data constructors of RdrName directly: prefer the family -- | Do not use the data constructors of RdrName directly: prefer the family
-- of functions that creates them, such as 'mkRdrUnqual' -- of functions that creates them, such as 'mkRdrUnqual'
--
-- - Note: A Located RdrName will only have API Annotations if it is a
-- compound one,
-- e.g.
--
-- > `bar`
-- > ( ~ )
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnType',
-- 'ApiAnnotation.AnnOpen' @'('@ or @'['@ or @'[:'@,
-- 'ApiAnnotation.AnnClose' @')'@ or @']'@ or @':]'@,,
-- 'ApiAnnotation.AnnBackquote' @'`'@,
-- 'ApiAnnotation.AnnVal','ApiAnnotation.AnnTildehsh',
-- 'ApiAnnotation.AnnTilde',
-- For details on above see note [Api annotations] in ApiAnnotation
data RdrName data RdrName
= Unqual OccName = Unqual OccName
-- ^ Used for ordinary, unqualified occurrences, e.g. @x@, @y@ or @Foo@. -- ^ Used for ordinary, unqualified occurrences, e.g. @x@, @y@ or @Foo@.
......