GHC(1)

📦
version 9.12.4 · 5 versions
, in epel 10

💖 GHC(1) — Glasgow Haskell Compiler 💖

okay bestie, welcome to the ghc manual page. This is the Glasgow Haskell Compiler, and we're gonna keep every single flag intact while making the vibe immaculate. ✨

🌸 NAME 🌸

ghc — the Glasgow Haskell Compiler.

🦋 SYNOPSIS 🦋

ghc [option|filename]
ghci [option|filename]

✨ DESCRIPTION ✨

This manual page documents briefly the ghc and ghci commands. Yes, briefly — it's a whole vibe. 💅

🫶 heads up, bestie: ghci is not yet available on all architectures.

Extensive documentation is available in various other formats including PDF https://downloads.haskell.org/ghc/latest/docs/users_guide.pdf and HTML https://downloads.haskell.org/ghc/latest/docs/html/.

Each of GHC's command line options is classified as either static or dynamic. A static flag may only be specified on the command line, whereas a dynamic flag may also be given in an OPTIONS pragma in a source file or set from the GHCi command-line with :set.

As a rule of thumb, all the language options are dynamic, as are the warning options and the debugging options.

The rest are static, with the notable exceptions of -v, -cpp, -fasm, -fvia-C, -fllvm, and -#include. The OPTIONS sections lists the status of each flag. That's the official word, no cap.

Common suffixes of file names for Haskell are:

  • .hs — Haskell source code; preprocess, compile
  • .lhs — literate Haskell source; unlit, preprocess, compile
  • .hi — Interface file; contains information about exported symbols
  • .hc — intermediate C files
  • .⟨way⟩_o — object files for "way" ⟨way⟩; common ways are:
    • dyn — dynamically-linked
    • p — built with profiling
  • .⟨way⟩_hi — interface files for "way" ⟨way⟩; common ways are:

🌈 OPTIONS 🌈

Flag wall time, bestie. Every option below is kept exactly as written — no renaming, no merging, no invented nonsense. 🎀

⚙️ Code generation ⚙️

-dynamic-too -fasm -fllvm -fbyte-code -fbyte-code-and-object-code
-fexpose-internal-symbols -fexternal-dynamic-refs -fllvm -fasm
-fno-code -fobject-code -fPIC -fPIE -fprefer-byte-code
-fwrite-if-simplified-core -fwrite-interface

🐛 Debugging the compiler 🐛

-dasm-lint -dcmm-lint -dcore-lint -ddisable-js-c-sources
-ddisable-js-minifier -ddump-asm -ddump-asm-conflicts
-ddump-asm-liveness -ddump-asm-native -ddump-asm-regalloc
-ddump-asm-regalloc-stages -ddump-asm-stats -ddump-bcos
-ddump-c-backend -ddump-call-arity -ddump-cfg-weights -ddump-cmm
-ddump-cmm-caf -ddump-cmm-cbe -ddump-cmm-cfg -ddump-cmm-cps
-ddump-cmm-from-stg -ddump-cmm-info -ddump-cmm-opt
-ddump-cmm-proc -ddump-cmm-procmap -ddump-cmm-raw -ddump-cmm-sink
-ddump-cmm-sp -ddump-cmm-split -ddump-cmm-switch
-ddump-cmm-thread-sanitizer -ddump-cmm-verbose
-ddump-cmm-verbose-by-proc -ddump-core-stats
-ddump-cpr-signatures -ddump-cpranal -ddump-cs-trace -ddump-cse
-ddump-debug -ddump-deriv -ddump-dmd-signatures -ddump-dmdanal
-ddump-ds -ddump-ds-preopt -ddump-ec-trace -ddump-exitify
-ddump-faststrings -ddump-file-prefix=⟨str⟩ -ddump-float-in
-ddump-foreign -ddump-full-laziness -ddump-float-out -ddump-hie
-ddump-hpc -ddump-if-trace -ddump-inlinings -ddump-js -ddump-json
-ddump-late-cc -ddump-liberate-case -ddump-llvm -ddump-mod-map
-ddump-occur-anal -ddump-opt-cmm -ddump-parsed -ddump-parsed-ast
-ddump-prep -ddump-rn -ddump-rn-ast -ddump-rn-stats
-ddump-rn-trace -ddump-rtti -ddump-rule-firings
-ddump-rule-rewrites -ddump-rules -ddump-simpl
-ddump-simpl-iterations -ddump-simpl-stats -ddump-simpl-trace
-ddump-spec -ddump-spec-constr -ddump-splices
-ddump-static-argument-transformation -ddump-stg -ddump-stg-cg
-ddump-stg-final -ddump-stg-from-core -ddump-stg-tags
-ddump-stg-unarised -ddump-str-signatures -ddump-stranal
-ddump-tc -ddump-tc-ast -ddump-tc-trace -ddump-ticked
-ddump-timings -ddump-to-file -ddump-types
-ddump-verbose-inlinings -ddump-view-pattern-commoning
-ddump-worker-wrapper -dfaststring-stats -dhex-word-literals
-dinitial-unique=⟨s⟩ -dinline-check=⟨str⟩ -dipe-stats
-dkeep-comments -dlinear-core-lint -dlint -dno-debug-output
-ddebug-output -dno-typeable-binds -dppr-case-as-let
-dppr-cols=⟨n⟩ -dppr-debug -dppr-user-length -drule-check=⟨str⟩
-dshow-passes -dstg-lint -dsuppress-all -dsuppress-coercion-types
-dsuppress-coercions -dsuppress-core-sizes -dsuppress-idinfo
-dsuppress-module-prefixes -dsuppress-stg-free-vars
-dsuppress-stg-reps -dsuppress-ticks -dsuppress-timestamps
-dsuppress-type-applications -dsuppress-type-signatures
-dsuppress-unfoldings -dsuppress-uniques -dsuppress-var-kinds
-dtag-inference-checks -dth-dec-file -dunique-increment=⟨i⟩
-dverbose-core2core -dverbose-stg2stg -fadd-bco-name
-fno-add-bco-name -falignment-sanitisation
-fcatch-nonexhaustive-cases -fcheck-prim-bounds
-fcmm-thread-sanitizer -fdistinct-constructor-tables
-fdump-with-ways -finfo-table-map -finfo-table-map-with-fallback
-fno-info-table-map-with-fallback -finfo-table-map-with-stack
-fno-info-table-map-with-stack -fllvm-fill-undef-with-garbage
-fno-info-table-map-with-fallback -finfo-table-map-with-fallback
-fno-info-table-map-with-stack -finfo-table-map-with-stack
-forig-thunk-info -fproc-alignment
-funoptimized-core-for-interpreter
-fno-unoptimized-core-for-interpreter -g -g⟨n⟩

🧪 C pre-processor 🧪

-cpp -D⟨symbol⟩[=⟨value⟩] -U⟨symbol⟩ -I⟨dir⟩ -U⟨symbol⟩

🔎 Finding imports 🔎

-i -i⟨dir⟩[:⟨dir⟩]*

💬 Interactive mode 💬

-fbreak-on-error -fno-break-on-error -fbreak-on-exception
-fno-break-on-exception -fbreak-points -fno-break-points
-fghci-hist-size=⟨n⟩ -fghci-leak-check -fno-ghci-leak-check
-fimplicit-import-qualified -fno-implicit-import-qualified
-flocal-ghci-history -fno-local-ghci-history -fno-it -fno-no-it
-fprint-bind-result -fno-print-bind-result -fprint-evld-with-show
-fshow-loaded-modules -ghci-script -ignore-dot-ghci
-no-ignore-dot-ghci -interactive-print ⟨name⟩

🗂️ Interface files 🗂️

--show-iface ⟨file⟩ -ddump-hi -ddump-hi-diffs
-ddump-minimal-imports

🧹 Keeping intermediate files 🧹

-keep-hc-file -keep-hc-files -keep-hi-files -no-keep-hi-files
-keep-hscpp-file -keep-hscpp-files -keep-llvm-file
-keep-llvm-files -keep-o-files -no-keep-o-files -keep-s-file
-keep-s-files -keep-tmp-files

🗣️ Language options 🗣️

The big -X wall. Every single one is here, bestie — no skipping. 💅

-XAllowAmbiguousTypes -XApplicativeDo -XArrows -XBangPatterns
-XBinaryLiterals -XBlockArguments -XCApiFFI
-XConstrainedClassMethods -XConstraintKinds -XCPP -XCUSKs
-XDataKinds -XDatatypeContexts -XDeepSubsumption
-XDefaultSignatures -XDeriveAnyClass -XDeriveDataTypeable
-XDeriveFoldable -XDeriveFunctor -XDeriveGeneric -XDeriveLift
-XDeriveTraversable -XDerivingStrategies -XDerivingVia
-XDisambiguateRecordFields -XDuplicateRecordFields -XEmptyCase
-XEmptyDataDecls -XEmptyDataDeriving -XExistentialQuantification
-XExplicitForAll -XExplicitNamespaces -XExtendedDefaultRules
-XExtendedLiterals -XFieldSelectors -XFlexibleContexts
-XFlexibleInstances -XForeignFunctionInterface
-XFunctionalDependencies -XGADTs -XGADTSyntax
-XGeneralisedNewtypeDeriving -XGeneralizedNewtypeDeriving
-XGHC2021 -XGHC2024 -XGHCForeignImportPrim -XHaskell2010
-XHaskell98 -XHexFloatLiterals -XImplicitParams -XImplicitPrelude
-XImportQualifiedPost -XImpredicativeTypes -XIncoherentInstances
-XInstanceSigs -XInterruptibleFFI -XKindSignatures -XLambdaCase
-XLexicalNegation -XLiberalTypeSynonyms -XLinearTypes
-XListTuplePuns -XMagicHash -XMonadComprehensions
-XMonoLocalBinds -XMonomorphismRestriction -XMultilineStrings
-XMultiParamTypeClasses -XMultiWayIf -XNamedDefaults
-XNamedFieldPuns -XNamedWildCards -XNegativeLiterals
-XNondecreasingIndentation -XNPlusKPatterns -XNullaryTypeClasses
-XNumDecimals -XNumericUnderscores -XOrPatterns
-XOverlappingInstances -XOverloadedLabels -XOverloadedLists
-XOverloadedRecordDot -XOverloadedRecordUpdate
-XOverloadedStrings -XPackageImports -XParallelListComp
-XPartialTypeSignatures -XPatternGuards -XPatternSynonyms
-XPolyKinds -XPostfixOperators -XQualifiedDo
-XQuantifiedConstraints -XQuasiQuotes -XRank2Types -XRankNTypes
-XRebindableSyntax -XRecordWildCards -XRecursiveDo
-XRequiredTypeArguments -XRoleAnnotations -XSafe
-XScopedTypeVariables -XStandaloneDeriving
-XStandaloneKindSignatures -XStarIsType -XStaticPointers -XStrict
-XStrictData -XTemplateHaskell -XTemplateHaskellQuotes
-XTraditionalRecordSyntax -XTransformListComp -XTrustworthy
-XTupleSections -XTypeAbstractions -XTypeApplications -XTypeData
-XTypeFamilies -XTypeFamilyDependencies -XTypeInType
-XTypeOperators -XTypeSynonymInstances -XUnboxedSums
-XUnboxedTuples -XUndecidableInstances -XUndecidableSuperClasses
-XUnicodeSyntax -XUnliftedDatatypes -XUnliftedFFITypes
-XUnliftedNewtypes -XUnsafe -XViewPatterns

🔗 Linking options 🔗

-c -debug -dylib-install-name ⟨path⟩ -dynamic -dynload -eventlog
-fcompact-unwind -fkeep-cafs -flink-rts -fno-embed-manifest
-fno-gen-manifest -fno-shared-implib -framework ⟨name⟩
-framework-path ⟨dir⟩ -fsplit-sections -split-sections
-fno-split-sections -fuse-rpaths -fwhole-archive-hs-libs -L ⟨dir⟩
-l ⟨lib⟩ -main-is ⟨thing⟩ -no-hs-main -no-pie -pie
-no-rtsopts-suggestions -package ⟨name⟩ -pie -no-pie -rdynamic
-rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] -shared
-single-threaded -threaded -static -staticlib -threaded
-single-threaded -with-rtsopts=⟨opts⟩

🎲 Miscellaneous options 🎲

-ddump-mod-cycles -fdefer-out-of-scope-variables
-fno-defer-out-of-scope-variables -fdefer-type-errors
-fno-defer-type-errors -fdefer-typed-holes -fno-defer-typed-holes
-fexternal-interpreter -ffamily-application-cache
-fno-family-application-cache -fglasgow-exts -fno-glasgow-exts
-fno-safe-haskell -ghcversion-file ⟨path to ghcversion.h⟩ -H
⟨size⟩ -hidden-module ⟨module name⟩ -j[⟨n⟩] -jsem
-reexported-module ⟨reexport-spec⟩ -this-package-name ⟨unit-id⟩
-unit @⟨filename⟩ -working-dir ⟨dir⟩

💅 Modes of operation 💅

ok bestie, this first block is the big one — it's literally "what do you want GHC to do today". One of these is your whole vibe. Pick your main character moment 🎀

  • --frontend ⟨module⟩ — you're telling GHC to use that module as its frontend. name the module, that's the deal.
  • --help, -? — the classic. it prints help. that's the whole bit. slay.
  • --info — prints info. yes that's it. she's simple, she's iconic.
  • --interactive — interactive mode, so GHC talks back to you 💬
  • --make — make mode. the compiler pretends to be a build system, and honestly? she ate.
  • --numeric-version — the version, but numbers only, no extra chatter.
  • --print-booter-version — prints the booter version.
  • --print-build-platform — prints the build platform.
  • --print-c-compiler-flags — prints the C compiler flags.
  • --print-c-compiler-link-flags — prints the C compiler link flags. yes, different from the other one.
  • --print-debug-on — prints debug-on.
  • --print-global-package-db — prints the global package db.
  • --print-have-interpreter — prints whether there's an interpreter. lowkey nosy but go off.
  • --print-have-native-code-generator — prints whether there's a native code generator.
  • --print-host-platform — prints the host platform.
  • --print-ld-flags — prints the ld flags.
  • --print-leading-underscore — prints the leading underscore situation.
  • --print-libdir — prints the libdir. very "where do the libs live" of her 🏠
  • --print-object-splitting-supported — prints whether object splitting is supported.
  • --print-project-git-commit-id — prints the project git commit id 🔖
  • --print-project-version — prints the project version.
  • --print-rts-ways — prints the RTS ways.
  • --print-stage — prints the stage.
  • --print-support-smp — prints whether SMP is supported.
  • --print-tables-next-to-code — prints the tables-next-to-code situation.
  • --print-target-platform — prints the target platform.
  • --print-unregisterised — prints the unregisterised situation.
  • --run ⟨file⟩ — run that file. give her a file, she runs it 🏃‍♀️
  • --show-iface ⟨file⟩ — show the interface for that file.
  • --show-options — shows you the options. meta, honestly. obsessed.
  • --supported-extensions — lists the supported extensions.
  • --supported-languages — lists the supported languages.
  • --version, -V — version time 💫
  • -e ⟨expr⟩ — evaluate expr right there on the spot.
  • -M — the M mode. capital M. she's mysterious, she's iconic.
  • -shared — shared. yes queen, share it with the group 🫶

🔥 Individual optimizations 🔥

bestie. sit down. this is the big list — every single little optimisation knob GHC has, and there are like a hundred of them 🙈

quick vibe check before we go: almost every one of these comes as a pair, and the -fno- version is the "turn it off" twin. the ones with =⟨n⟩ want a number from you. that's the pattern, now go wild:

  • -fasm-shortcutting, -fno-asm-shortcutting — asm shortcutting: on, or off. simple as.
  • -fbinary-blob-threshold=⟨n⟩ — takes a number. binary blob threshold, you know the one.
  • -fblock-layout-cfg, -fno-block-layout-cfg — block layout cfg, on/off 💅
  • -fblock-layout-weightless, -fno-block-layout-weightless — the weightless version. iconique.
  • -fblock-layout-weights — and here's the one with weights. no -fno- twin for this one, she stands alone.
  • -fcall-arity, -fno-call-arity — call arity toggle 🎚️
  • -fcase-folding, -fno-case-folding — case folding, yes/no.
  • -fcase-merge, -fno-case-merge — case merge, yes/no.
  • -fcmm-control-flow, -fno-cmm-control-flow — cmm control flow.
  • -fcmm-elim-common-blocks, -fno-cmm-elim-common-blocks — cmm elim common blocks.
  • -fcmm-sink, -fno-cmm-sink — cmm sink. she sinks. it's fine.
  • -fcmm-static-pred, -fno-cmm-static-pred — cmm static pred.
  • -fcore-constant-folding, -fno-core-constant-folding — core constant folding, the OG.
  • -fcpr-anal, -fno-cpr-anal — cpr anal 💀
  • -fcross-module-specialise, -fno-cross-module-specialise — cross module specialise.
  • -fcse, -fno-cse — cse my beloved.
  • -fdicts-cheap, -fno-dicts-cheap — dicts cheap. budget dictionaries fr fr.
  • -fdicts-strict, -fno-dicts-strict — dicts strict.
  • -fdmd-tx-dict-sel, -fno-dmd-tx-dict-sel — dmd tx dict sel (yes, really).
  • -fdmd-unbox-width=⟨n⟩ — takes a number. dmd unbox width.
  • -fdo-clever-arg-eta-expansion, -fno-do-clever-arg-eta-expansion — the clever arg eta expansion. she's clever, it's in the name ✨
  • -fdo-eta-reduction, -fno-do-eta-reduction — eta reduction.
  • -fdo-lambda-eta-expansion, -fno-do-lambda-eta-expansion — lambda eta expansion.
  • -feager-blackholing — eager blackholing. no off switch listed. she's just eager 🖤
  • -fenable-rewrite-rules, -fno-enable-rewrite-rules — rewrite rules: enabled or not.
  • -fexcess-precision, -fno-excess-precision — excess precision.
  • -fexitification, -fno-exitification — exitification 🚪
  • -fexpose-all-unfoldings, -fno-expose-all-unfoldings — expose all the unfoldings. no secrets, no privacy, we're all exposed 💅
  • -fexpose-overloaded-unfoldings, -fno-expose-overloaded-unfoldings — the overloaded ones this time.
  • -ffloat-in, -fno-float-in — float in.
  • -ffull-laziness, -fno-full-laziness — full laziness. lazy girlie rights 😴
  • -ffun-to-thunk, -fno-fun-to-thunk — fun to thunk. cute.
  • -fignore-asserts, -fno-ignore-asserts — ignore asserts, or don't.
  • -fignore-interface-pragmas, -fno-ignore-interface-pragmas — ignore interface pragmas.
  • -finline-generics, -fno-inline-generics — inline generics.
  • -finline-generics-aggressively, -fno-inline-generics-aggressively — inline generics but make it aggressive 🔥
  • -finter-module-far-jumps, -fno-inter-module-far-jumps — inter module far jumps. far. jumps.
  • -fkeep-auto-rules, -fno-keep-auto-rules — keep auto rules, or toss 'em.
  • -flate-dmd-anal, -fno-late-dmd-anal — late dmd anal. fashionably late ⏰
  • -flate-specialise, -fno-late-specialise — late specialise.
  • -fliberate-case, -fno-liberate-case — liberate case 🕊️
  • -fliberate-case-threshold=⟨n⟩, -fno-liberate-case-threshold — the numeric threshold version, plus its off switch.
  • -fllvm-pass-vectors-in-regs — llvm pass vectors in regs. no off twin here.
  • -flocal-float-out, -fno-local-float-out — local float out.
  • -flocal-float-out-top-level, -fno-local-float-out-top-level — same but top level 👑
  • -floopification, -fno-loopification — loopification, obviously.
  • -fmax-forced-spec-args=⟨n⟩ — takes a number. max forced spec args.
  • -fmax-inline-alloc-size=⟨n⟩ — takes a number. max inline alloc size.
  • -fmax-inline-memcpy-insns=⟨n⟩ — takes a number. max inline memcpy insns.
  • -fmax-inline-memset-insns=⟨n⟩ — takes a number. max inline memset insns.
  • -fmax-simplifier-iterations=⟨n⟩ — takes a number. max simplifier iterations.
  • -fmax-uncovered-patterns=⟨n⟩ — takes a number. max uncovered patterns.
  • -fmax-worker-args=⟨n⟩ — takes a number. max worker args.
  • -fno-opt-coercion — opt coercion, but off. no on version listed here.
  • -fno-pre-inlining — pre inlining, off.
  • -fno-state-hack — the state hack, off. (only the off listed, bestie, don't @ me)
  • -fobject-determinism, -fno-object-determinism — object determinism.
  • -fomit-interface-pragmas, -fno-omit-interface-pragmas — omit interface pragmas.
  • -fomit-yields, -fno-omit-yields — omit yields.
  • -foptimal-applicative-do, -fno-optimal-applicative-do — optimal applicative do ✨
  • -fpedantic-bottoms, -fno-pedantic-bottoms — pedantic bottoms 🙈
  • -fpolymorphic-specialisation, -fno-polymorphic-specialisation — polymorphic specialisation.
  • -fregs-graph, -fno-regs-graph — regs graph.
  • -fregs-iterative, -fno-regs-iterative — regs iterative.
  • -fsimpl-tick-factor=⟨n⟩ — takes a number. simpl tick factor.
  • -fsimplifier-phases=⟨n⟩ — takes a number. simplifier phases.
  • -fsolve-constant-dicts, -fno-solve-constant-dicts — solve constant dicts.
  • -fspec-constr, -fno-spec-constr — spec constr.
  • -fspec-constr-count=⟨n⟩, -fno-spec-constr-count — the numeric one plus its off switch.
  • -fspec-constr-keen, -fno-spec-constr-keen — spec constr but keen 🫡
  • -fspec-constr-threshold=⟨n⟩, -fno-spec-constr-threshold — threshold version + off switch.
  • -fspec-eval, -fno-spec-eval — spec eval.
  • -fspec-eval-dictfun, -fno-spec-eval-dictfun — spec eval dictfun.
  • -fspecialise, -fno-specialise — specialise.
  • -fspecialise-aggressively, -fno-specialise-aggressively — aggressive specialise, she's not playing 🔥
  • -fspecialise-incoherents, -fno-specialise-incoherents — specialise incoherents 💀
  • -fstatic-argument-transformation, -fno-static-argument-transformation — static argument transformation.
  • -fstg-cse, -fno-stg-cse — stg cse.
  • -fstg-lift-lams, -fno-stg-lift-lams — stg lift lams.
  • -fstg-lift-lams-known, -fno-stg-lift-lams-known — stg lift lams, known variant.
  • -fstg-lift-lams-non-rec-args — stg lift lams non rec args. no off twin.
  • -fstg-lift-lams-non-rec-args-any — and the -any version of that one.
  • -fstg-lift-lams-rec-args — stg lift lams rec args.
  • -fstg-lift-lams-rec-args-any — the -any version of that one.
  • -fstrictness, -fno-strictness — strictness.
  • -fstrictness-before=⟨n⟩ — takes a number. strictness, but before.
  • -funbox-small-strict-fields, -fno-unbox-small-strict-fields — box/unbox the small strict fields (yes, the off one is spelled unbox, keep your eyes peeled 👀)
  • -funbox-strict-fields, -fno-unbox-strict-fields — same energy, without "small".
  • -funfolding-case-scaling=⟨n⟩ — takes a number. unfolding case scaling.
  • -funfolding-case-threshold=⟨n⟩ — takes a number. unfolding case threshold.
  • -funfolding-creation-threshold=⟨n⟩ — takes a number. unfolding creation threshold.
  • -funfolding-dict-discount=⟨n⟩ — takes a number. unfolding dict discount 🏷️
  • -funfolding-fun-discount=⟨n⟩ — takes a number. unfolding fun discount.
  • -funfolding-keeness-factor=⟨n⟩ — takes a number. (spelled keeness, that's canon, don't fix it 💅)
  • -funfolding-use-threshold=⟨n⟩ — takes a number. unfolding use threshold.
  • -fworker-wrapper — worker wrapper 🫶
  • -fworker-wrapper-cbv — worker wrapper, cbv flavour.
  • -fwrite-if-compression=⟨n⟩ — takes a number. write if compression.

like… that's the whole list. ngl I need a minute 😭


⚡ Optimization levels ⚡

the fast-food menu of optimisation: pick a level, any level 🍟

-O -O1 -O0 -O0 -O2 -O0 -O⟨n⟩ -O0
  • -O — the plain one.
  • -O1 — level one.
  • -O0 — level zero. she appears several times in this list, and bestie I'm not the one who wrote it, I'm just reporting it faithfully 🫡
  • -O0 — yep. again.
  • -O2 — level two, the spicy one.
  • -O0 — third time's the charm 💀
  • -O⟨n⟩ — your number, your level. pick a number, any number 🔢
  • -O0 — and one more for the road.

📦 Package options 📦

package management hours, bestie — this is how you tell GHC which packages exist, which ones you trust, and which ones you're side-eyeing 🧐

  • -clear-package-db — clears the package db. poof, gone.
  • -distrust ⟨pkg⟩ — you do NOT trust pkg. she's on thin ice 🙅‍♀️
  • -distrust-all-packages — trust issues, but make it global 💀
  • -fpackage-trust — enables package trust behaviour.
  • -global-package-db — the global package db.
  • -hide-all-packages — hide every single one. nobody's invited.
  • -hide-package ⟨pkg⟩ — hide just pkg. targeted.
  • -ignore-package ⟨pkg⟩ — ignore pkg entirely.
  • -no-auto-link-packages — no auto link packages.
  • -no-global-package-db — no global package db.
  • -no-user-package-db — no user package db.
  • -package ⟨pkg⟩ — invite pkg to the party 🎉
  • -package-db ⟨file⟩ — point at file as your package db.
  • -package-env ⟨file⟩|⟨name⟩ — package env, by file or by name. both valid, choose your fighter.
  • -package-id ⟨unit-id⟩ — package id, by unit-id.
  • -this-unit-id ⟨unit-id⟩ — this unit id, by unit-id.
  • -trust ⟨pkg⟩ — ok fine, you trust pkg. character development 🫶
  • -user-package-db — the user package db.

🧚 Phases of compilation 🧚

where in the pipeline do you wanna stop? pick a phase, she'll do the rest ✨

  • --merge-objs — merge objs.
  • -C — the -C phase.
  • -c — the lowercase -c phase. yes, case matters, bestie, always.
  • -E — the -E phase.
  • -F — the -F phase.
  • -S — the -S phase.
  • -x ⟨suffix⟩ — specify a suffix 🏷️

🌸 Overriding external programs 🌸

sometimes you're like "no, I have my OWN C compiler" and GHC is like "ok bestie, noted" — that's this whole section. every one of these takes a ⟨cmd⟩ 💅

  • -pgma ⟨cmd⟩ — override the a program with cmd.
  • -pgmc ⟨cmd⟩ — override the C compiler with cmd.
  • -pgmCmmP ⟨cmd⟩ — override the CmmP program with cmd.
  • -pgmcxx ⟨cmd⟩ — override the C++ compiler with cmd.
  • -pgmF ⟨cmd⟩ — override the F program with cmd.
  • -pgmi ⟨cmd⟩ — override the i program with cmd.
  • -pgminstall_name_tool ⟨cmd⟩ — override install_name_tool with cmd. that's the literal name, underscores and all, don't touch it.
  • -pgmJSP ⟨cmd⟩ — override the JSP program with cmd.
  • -pgmL ⟨cmd⟩ — override uppercase L with cmd.
  • -pgml ⟨cmd⟩ — override lowercase l with cmd. (yes, both, they're different, iykyk)
  • -pgmlas ⟨cmd⟩ — override las with cmd.
  • -pgmlc ⟨cmd⟩ — override lc with cmd.
  • -pgmlm ⟨cmd⟩ — override lm with cmd.
  • -pgmlo ⟨cmd⟩ — override lo with cmd.
  • -pgmotool ⟨cmd⟩ — override otool with cmd.
  • -pgmP ⟨cmd⟩ — override the P program with cmd.
  • -pgms ⟨cmd⟩ — override the s program with cmd.
  • -pgmwindres ⟨cmd⟩ — override windres with cmd.

🎀 Phase-specific options 🎀

same energy as above but you're not swapping the program — you're slipping an extra ⟨option⟩ to a specific phase 🫶

  • -opta ⟨option⟩ — pass option to the a phase.
  • -optc ⟨option⟩ — pass option to the C phase.
  • -optCmmP ⟨option⟩ — pass option to the CmmP phase.
  • -optcxx ⟨option⟩ — pass option to the C++ phase.
  • -optF ⟨option⟩ — pass option to the F phase.
  • -opti ⟨option⟩ — pass option to the i phase.
  • -optJSP ⟨option⟩ — pass option to the JSP phase.
  • -optL ⟨option⟩ — pass option to uppercase L.
  • -optl ⟨option⟩ — pass option to lowercase l.
  • -optlas ⟨option⟩ — pass option to las.
  • -optlc ⟨option⟩ — pass option to lc.
  • -optlm ⟨option⟩ — pass option to lm.
  • -optlo ⟨option⟩ — pass option to lo.
  • -optP ⟨option⟩ — pass option to the P phase.
  • -optwindres ⟨option⟩ — pass option to windres.
  • -pgmc-supports-no-pie — flags that the C compiler supports no-pie.
  • -pgml-supports-no-pie — same, but for the l program.

💜 Platform-specific options 💜

CPU feature flags, aka "please emit the fancy instructions, my machine can handle it" 💅

  • -mavx — avx ✨
  • -mavx2 — avx2 ✨
  • -mavx512cd — avx512cd
  • -mavx512er — avx512er
  • -mavx512f — avx512f
  • -mavx512pf — avx512pf
  • -mbmi — bmi
  • -mbmi2 — bmi2
  • -mfma — fma
  • -msse — sse
  • -msse2 — sse2
  • -msse3 — sse3
  • -msse4 — sse4
  • -msse4.2 — sse4.2 (dot and all, keep it exact 🎯)

🦋 Compiler plugins 🦋

letting other code into the compiler's brain. very "group project but the group is a plugin system" energy 🧠

  • -fclear-plugins — clears all the plugins. clean slate, fresh start ✨
  • -fplugin-library=⟨file-path⟩;⟨unit-id⟩;⟨module⟩;⟨args⟩ — load a plugin from a library. four semicolon-separated pieces, in that exact order: file path, unit id, module, args. don't lose the semicolons, bestie 🫶
  • -fplugin-opt=⟨module⟩:⟨args⟩ — pass args to the plugin module. note the colon.
  • -fplugin-trustworthy — declare the plugin trustworthy. big trust fall energy.
  • -fplugin=⟨module⟩ — load the plugin from module.
  • -hide-all-plugin-packages — hide all plugin packages.
  • -plugin-package ⟨pkg⟩ — make pkg available as a plugin package.
  • -plugin-package-id ⟨pkg-id⟩ — same but by pkg-id.

👑 Profiling 👑

time to find out where your program is spending all its time. she's nosy and honestly? we love that for her 🔍

  • -auto — auto.
  • -auto-all — auto, but all.
  • -caf-all — caf all.
  • -fno-prof-count-entries, -fprof-count-entries — prof count entries: off, or on.
  • -fprof-auto, -fno-prof-auto — prof auto.
  • -fprof-auto-calls, -fno-prof-auto — prof auto calls, with the shared -fno-prof-auto off switch.
  • -fprof-auto-exported, -fno-prof-auto — prof auto exported, same off switch again.
  • -fprof-auto-top, -fno-prof-auto — prof auto top, same off switch. (the page really does list -fno-prof-auto four times, she's thorough 💀)
  • -fprof-cafs, -fno-prof-cafs — prof cafs.
  • -fprof-callers=⟨name⟩ — takes a name. prof callers.
  • -fprof-late, -fno-prof-late — prof late.
  • -fprof-late-inline, -fno-prof-late-inline — prof late inline.
  • -fprof-late-overloaded, -fno-prof-late-overloaded — prof late overloaded.
  • -fprof-late-overloaded-calls, -fno-prof-late-overloaded-calls — prof late overloaded calls.
  • -fprof-manual, -fno-prof-manual — prof manual.
  • -no-auto — no auto.
  • -no-auto-all — no auto all.
  • -no-caf-all — no caf all.
  • -prof — the big one: prof.
  • -ticky — ticky 📊
  • -ticky-allocd — ticky, allocd.
  • -ticky-ap-thunk — ticky ap thunk.
  • -ticky-dyn-thunk — ticky dyn thunk.
  • -ticky-LNE — ticky LNE (caps, keep 'em).
  • -ticky-tag-checks — ticky tag checks.

🍓 Program coverage 🍓

did your tests actually run that line? now we know 🌈

  • -fhpc — hpc mode on.
  • -hpcdir⟨dir⟩ — the hpc dir. heads up: no space before the ⟨dir⟩ here, that's how it's written, so write it like that 🫶

⭐ Recompilation checking ⭐

GHC's "do I really have to rebuild this?" instincts. she's efficient, she's got places to be 💅

  • -exclude-module=⟨file⟩ — exclude file from the recompilation party.
  • -fforce-recomp, -fno-force-recomp — force recompilation, or don't.
  • -fignore-hpc-changes, -fno-ignore-hpc-changes — ignore hpc changes, or don't.
  • -fignore-optim-changes, -fno-ignore-optim-changes — ignore optim changes, or don't.
  • -include-cpp-deps — include cpp deps.
  • -include-pkg-deps — include pkg deps.

🌈 Redirecting output 🌈

where do the files GO? this is the "everything has a place and I have opinions about it" section 🗂️

  • -dep-makefile ⟨file⟩ — dep makefile goes to file.
  • -dep-suffix ⟨suffix⟩ — dep suffix is suffix.
  • -dumpdir ⟨dir⟩ — dump stuff into dir.
  • -dynhisuf ⟨suffix⟩ — dynhi suffix.
  • -dyno ⟨file⟩ — dyno output goes to file.
  • -dynohi ⟨file⟩ — dynohi output goes to file.
  • -dynosuf ⟨suffix⟩ — dyno suffix.
  • -hcsuf ⟨suffix⟩ — hc suffix.
  • -hidir ⟨dir⟩ — hi files into dir.
  • -hiedir ⟨dir⟩ — hie files into dir.
  • -hiesuf ⟨suffix⟩ — hie suffix.
  • -hisuf ⟨suffix⟩ — hi suffix.
  • -o ⟨file⟩ — the classic -o. output goes to file 🎯
  • -odir ⟨dir⟩ — object files into dir.
  • -ohi ⟨file⟩ — hi file goes to file.
  • -osuf ⟨suffix⟩ — object suffix.
  • -outputdir ⟨dir⟩ — the general output dir.
  • -stubdir ⟨dir⟩ — stub files into dir.

🧊 Temporary files 🧊

one (1) option. she's lowkey but essential.

  • -tmpdir ⟨dir⟩ — put temporary files in dir. give the girl a home 🏠

💀 Verbosity options 💀

ok this is the diagnostics-and-vibes section — error messages, hole fits, colour, timing, all of it. deep breath, bestie, we're going in 🔥

  • -fabstract-refinement-hole-fits, -fno-abstract-refinement-hole-fits — abstract refinement hole fits.
  • -fdefer-diagnostics — defer diagnostics. procrastination, but for the compiler.
  • -fdiagnostics-as-json — diagnostics as json. for the machines 🤖
  • -fdiagnostics-color=⟨always|auto|never⟩ — colour, and you choose from exactly always, auto, or never. three options, no more, don't get creative 🎨
  • -fdiagnostics-show-caret, -fno-diagnostics-show-caret — show the caret, or don't ^
  • -ferror-spans — error spans.
  • -fhide-source-paths — hide source paths.
  • -fkeep-going — keep going. she's not giving up on you fr fr 💪
  • -fmax-refinement-hole-fits=⟨n⟩, -fno-max-refinement-hole-fits — numeric max, or off.
  • -fmax-relevant-binds=⟨n⟩, -fno-max-relevant-binds — numeric max, or off.
  • -fmax-valid-hole-fits=⟨n⟩, -fno-max-valid-hole-fits — numeric max, or off.
  • -fno-show-valid-hole-fits — show valid hole fits, off. (only the off listed here 👀)
  • -fno-sort-valid-hole-fits, -fsort-valid-hole-fits — sorting, off then on.
  • -fprint-axiom-incomps, -fno-print-axiom-incomps — print axiom incomps.
  • -fprint-equality-relations, -fno-print-equality-relations — print equality relations.
  • -fprint-error-index-links=⟨always|auto|never⟩ — error index links, always, auto, or never. same three, every time 🎚️
  • -fprint-expanded-synonyms, -fno-print-expanded-synonyms — print expanded synonyms.
  • -fprint-explicit-coercions, -fno-print-explicit-coercions — print explicit coercions.
  • -fprint-explicit-foralls, -fno-print-explicit-foralls — print explicit foralls.
  • -fprint-explicit-kinds, -fno-print-explicit-kinds — print explicit kinds.
  • -fprint-explicit-runtime-reps, -fno-print-explicit-runtime-reps — print explicit runtime reps.
  • -fprint-potential-instances, -fno-print-potential-instances — print potential instances.
  • -fprint-redundant-promotion-ticks, -fno-print-redundant-promotion-ticks — print redundant promotion ticks.
  • -fprint-typechecker-elaboration, -fno-print-typechecker-elaboration — print typechecker elaboration.
  • -fprint-unicode-syntax, -fno-print-unicode-syntax — print unicode syntax 🌸
  • -frefinement-level-hole-fits=⟨n⟩, -fno-refinement-level-hole-fits — numeric level, or off.
  • -freverse-errors, -fno-reverse-errors — reverse errors.
  • -fshow-docs-of-hole-fits, -fno-show-docs-of-hole-fits — show docs of hole fits.
  • -fshow-error-context, -fno-show-error-context — show error context.
  • -fshow-hole-constraints — show hole constraints. no off twin here.
  • -fshow-hole-matches-of-hole-fits, -fno-show-hole-matches-of-hole-fits — show hole matches of hole fits.
  • -fshow-provenance-of-hole-fits, -fno-show-provenance-of-hole-fits — show provenance of hole fits.
  • -fshow-type-app-of-hole-fits, -fno-show-type-app-of-hole-fits — show type app of hole fits.
  • -fshow-type-app-vars-of-hole-fits, -fno-show-type-app-vars-of-hole-fits — show type app vars of hole fits.
  • -fshow-type-of-hole-fits, -fno-show-type-of-hole-fits — show type of hole fits.
  • -fsort-by-size-hole-fits, -fno-sort-by-size-hole-fits — sort by size.
  • -fsort-by-subsumption-hole-fits, -fno-sort-by-subsumption-hole-fits — sort by subsumption.
  • -funclutter-valid-hole-fits — unclutter valid hole fits ✨ she's doing her best to tidy up.
  • -Rghc-timing — report ghc timing ⏱️
  • -v — verbose. she's talking now.
  • -v⟨n⟩ — verbose with a number, because sometimes you need more talking 🔢

and that's where this part lands, bestie — more chaos incoming, don't go anywhere 💖

⚠️ Warnings ⚠️

okay bestie, deep breath 💖 this next bit is the warning-flag motherload — it's a wall of -W flags and honestly it's giving "shouted the entire dictionary at me". Every single one is listed below, in the exact order they show up, because we do not skip entries in this house 💅 the -W version turns the warning on, the -Wno- version turns it back off. iykyk 🦋

  • -fenable-th-splice-warnings, -fno-enable-th-splice-warnings
  • -fhelpful-errors, -fno-helpful-errors
  • -fmax-pmcheck-models=⟨n⟩
  • -fshow-warning-groups, -fno-show-warning-groups
  • -fvia-C
  • -W, -Wno-extra
  • -w
  • -Wall, -Wno-all
  • -Wall-missed-specialisations, -Wno-all-missed-specialisations
  • -Wall-missed-specializations, -Wno-all-missed-specializations
  • -Wambiguous-fields
  • -Wauto-orphans
  • -Wbadly-staged-types, -Wno-badly-staged-types
  • -Wcompat, -Wno-compat
  • -Wcompat-unqualified-imports, -Wno-compat-unqualified-imports
  • -Wcpp-undef
  • -Wdata-kinds-tc, -Wno-data-kinds-tc
  • -Wdefault, -Wno-default
  • -Wdefaulted-exception-context, -Wnop-defaulted-exception-context
  • -Wdeferred-out-of-scope-variables, -Wno-deferred-out-of-scope-variables
  • -Wdeferred-type-errors, -Wno-deferred-type-errors
  • -Wdeprecated-flags, -Wno-deprecated-flags
  • -Wdeprecated-type-abstractions, -Wno-deprecated-type-abstractions
  • -Wdeprecations, -Wno-deprecations
  • -Wderiving-defaults, -Wno-deriving-defaults
  • -Wderiving-typeable, -Wno-deriving-typeable
  • -Wdodgy-exports, -Wno-dodgy-exports
  • -Wdodgy-foreign-imports, -Wno-dodgy-foreign-imports
  • -Wdodgy-imports, -Wno-dodgy-imports
  • -Wduplicate-constraints, -Wno-duplicate-constraints
  • -Wduplicate-exports, -Wno-duplicate-exports
  • -Wempty-enumerations, -Wno-empty-enumerations
  • -Werror, -Wwarn
  • -Weverything
  • -w
  • -Wextended-warnings, -Wno-extended-warnings
  • -Wextra, -Wno-extra
  • -Wforall-identifier
  • -Wgadt-mono-local-binds, -Wno-gadt-mono-local-binds
  • -Whi-shadowing, -Wno-hi-shadowing
  • -Widentities, -Wno-identities
  • -Wimplicit-kind-vars, -Wno-implicit-kind-vars
  • -Wimplicit-lift, -Wno-implicit-lift
  • -Wimplicit-prelude, -Wno-implicit-prelude
  • -Wimplicit-rhs-quantification, -Wno-implicit-rhs-quantification
  • -Winaccessible-code, -Wno-inaccessible-code
  • -Wincomplete-export-warnings, -Wno-incomplete-export-warnings
  • -Wincomplete-patterns, -Wno-incomplete-patterns
  • -Wincomplete-record-selectors, -Wno-incomplete-record-selectors
  • -Wincomplete-record-updates, -Wno-incomplete-record-updates
  • -Wincomplete-uni-patterns, -Wno-incomplete-uni-patterns
  • -Winconsistent-flags, -Wno-inconsistent-flags
  • -Winferred-safe-imports, -Wno-inferred-safe-imports
  • -Winline-rule-shadowing, -Wno-inline-rule-shadowing
  • -Winvalid-haddock, -Wno-invalid-haddock
  • -Wloopy-superclass-solve, -Wno-loopy-superclass-solve
  • -Wmisplaced-pragmas, -Wno-misplaced-pragmas
  • -Wmissed-extra-shared-lib, -Wno-missed-extra-shared-lib
  • -Wmissed-specialisations, -Wno-missed-specialisations
  • -Wmissed-specializations, -Wno-missed-specializations
  • -Wmissing-deriving-strategies, -Wno-missing-deriving-strategies
  • -Wmissing-export-lists, -Wno-missing-export-lists
  • -Wmissing-exported-pattern-synonym-signatures, -Wno-missing-exported-pattern-synonym-signatures
  • -Wmissing-exported-signatures, -Wno-missing-exported-signatures
  • -Wmissing-exported-sigs, -Wno-missing-exported-sigs
  • -Wmissing-fields, -Wno-missing-fields
  • -Wmissing-home-modules, -Wno-missing-home-modules
  • -Wmissing-import-lists, -Wno-missing-import-lists
  • -Wmissing-kind-signatures, -Wno-missing-kind-signatures
  • -Wmissing-local-signatures, -Wno-missing-local-signatures
  • -Wmissing-local-sigs, -Wno-missing-local-sigs
  • -Wmissing-methods, -Wno-missing-methods
  • -Wmissing-monadfail-instances, -Wno-missing-monadfail-instances
  • -Wmissing-pattern-synonym-signatures, -Wno-missing-pattern-synonym-signatures
  • -Wmissing-poly-kind-signatures, -Wno-missing-poly-kind-signatures
  • -Wmissing-role-annotations, -Wno-role-annotations-signatures
  • -Wmissing-safe-haskell-mode, -Wno-missing-safe-haskell-mode
  • -Wmissing-signatures, -Wno-missing-signatures
  • -Wmissing-space-after-bang
  • -Wmonomorphism-restriction, -Wno-monomorphism-restriction
  • -Wname-shadowing, -Wno-name-shadowing
  • -Wnoncanonical-monad-instances, -Wno-noncanonical-monad-instances
  • -Wnoncanonical-monadfail-instances, -Wno-noncanonical-monadfail-instances
  • -Wnoncanonical-monoid-instances, -Wno-noncanonical-monoid-instances
  • -Wnot
  • -Woperator-whitespace, -Wno-operator-whitespace
  • -Woperator-whitespace-ext-conflict, -Wno-operator-whitespace-ext-conflict
  • -Worphans, -Wno-orphans
  • -Woverflowed-literals, -Wno-overflowed-literals
  • -Woverlapping-patterns, -Wno-overlapping-patterns
  • -Wpartial-fields, -Wno-partial-fields
  • -Wpartial-type-signatures, -Wno-partial-type-signatures
  • -Wprepositive-qualified-module, -Wno-prepositive-qualified-module
  • -Wredundant-bang-patterns, -Wno-redundant-bang-patterns
  • -Wredundant-constraints, -Wno-redundant-constraints
  • -Wredundant-record-wildcards, -Wno-redundant-record-wildcards
  • -Wredundant-strictness-flags, -Wno-redundant-strictness-flags
  • -Wsafe, -Wno-safe
  • -Wsemigroup, -Wno-semigroup
  • -Wsimplifiable-class-constraints, -Wno-simplifiable-class-constraints
  • -Wstar-binder, -Wno-star-binder
  • -Wstar-is-type, -Wno-star-is-type
  • -Wtabs, -Wno-tabs
  • -Wterm-variable-capture
  • -Wtrustworthy-safe, -Wno-safe
  • -Wtype-defaults, -Wno-type-defaults
  • -Wtype-equality-out-of-scope, -Wno-type-equality-out-of-scope
  • -Wtype-equality-requires-operators, -Wno-type-equality-requires-operators
  • -Wtyped-holes, -Wno-typed-holes
  • -Wunbanged-strict-patterns, -Wno-unbanged-strict-patterns
  • -Wunicode-bidirectional-format-characters
  • -Wunrecognised-pragmas, -Wno-unrecognised-pragmas
  • -Wunrecognised-warning-flags, -Wno-unrecognised-warning-flags
  • -Wunsafe, -Wno-unsafe
  • -Wunsupported-calling-conventions, -Wno-unsupported-calling-conventions
  • -Wunsupported-llvm-version, -Wno-unsupported-llvm-version
  • -Wunticked-promoted-constructors, -Wno-unticked-promoted-constructors
  • -Wunused-binds, -Wno-unused-binds
  • -Wunused-do-bind, -Wno-unused-do-bind
  • -Wunused-foralls, -Wno-unused-foralls
  • -Wunused-imports, -Wno-unused-imports
  • -Wunused-local-binds, -Wno-unused-local-binds
  • -Wunused-matches, -Wno-unused-matches
  • -Wunused-packages, -Wno-unused-packages
  • -Wunused-pattern-binds, -Wno-unused-pattern-binds
  • -Wunused-record-wildcards, -Wno-unused-record-wildcards
  • -Wunused-top-binds, -Wno-unused-top-binds
  • -Wunused-type-patterns, -Wno-unused-type-patterns
  • -Wview-pattern-signatures, -Wno-view-pattern-signatures
  • -Wwarn, -Werror
  • -Wwarnings-deprecations, -Wno-warnings-deprecations
  • -Wwrong-do-bind, -Wno-wrong-do-bind
  • -Wx-⟨category⟩, -Wno-x-⟨category⟩

and THAT'S the whole list, no cap 🫶 if you made it here, you're literally built different 👑


🛠️ Code generation 🛠️

this is the part where GHC decides what kind of output it's actually making — object files, byte-code, LLVM, whatever ✨ it's giving "choose your fighter" and honestly every option is iconic in its own way 💅

  • -dynamic-too — build the dynamic object files and the static object files while it's compiling. both. at once. multitalented king behaviour 👑
  • -fasm — use the native code generator 🔥
  • -fbyte-code — generate byte-code 🦋
  • -fbyte-code-and-object-code — generate object code and byte-code. why choose 🎀
  • -fexpose-internal-symbols — produce symbols for all functions, including the internal ones. nothing to hide, main character energy 💫
  • -fexternal-dynamic-refs — generate code for linking against dynamic libraries
  • -fllvm — compile using the LLVM code generator 🧚
  • -fno-code — omit code generation entirely. we're just vibing, no output 💀
  • -fobject-code — generate object code
  • -fPIC — generate position-independent code (where available)
  • -fPIE — generate code for a position-independent executable (where available)
  • -fprefer-byte-code — use byte-code if it's available for evaluating TH splices
  • -fwrite-if-simplified-core — write an interface file containing the simplified core of the module 📝
  • -fwrite-interface — always write interface files. always always 🌸

🔬 Debugging the compiler 🔬

okay so this section is for when you're down bad for GHC's internals 😭 it's basically all the -d flags — sanity checks on one side, and a whole buffet of -ddump- flags that dump out every intermediate stage you could possibly want to stare at. it's giving "behind the scenes" and honestly? obsessed 🍓

sanity checking & misc

  • -dasm-lint — ASM pass sanity checking
  • -dcmm-lint — C-- pass sanity checking
  • -dcore-lint — turn on internal sanity checking 🔍
  • -ddisable-js-c-sources — disable the link with C sources compiled to JavaScript
  • -ddisable-js-minifier — generate pretty-printed JavaScript code instead of minified (compacted) code ✨

dumping the assembly pipeline

  • -ddump-asm — dump final assembly
  • -ddump-asm-conflicts — dump register conflicts from the register allocator 👀
  • -ddump-asm-liveness — dump assembly augmented with register liveness
  • -ddump-asm-native — dump initial assembly
  • -ddump-asm-regalloc — dump the result of register allocation
  • -ddump-asm-regalloc-stages — dump the build/spill stages of the -fregs-graph register allocator
  • -ddump-asm-stats — dump statistics from the register allocator 📊

dumping everything else in the back end

  • -ddump-bcos — dump interpreter byte code
  • -ddump-c-backend — dump C code produced by the C (unregisterised) backend
  • -ddump-call-arity — dump output of the call arity analysis pass
  • -ddump-cfg-weights — dump the assumed weights of the CFG
  • -ddump-cmm — dump the final C-- output
  • -ddump-cmm-caf — dump the results of the C-- CAF analysis pass
  • -ddump-cmm-cbe — dump the results of common block elimination
  • -ddump-cmm-cfg — dump the results of the C-- control flow optimisation pass
  • -ddump-cmm-cps — dump the results of the CPS pass
  • -ddump-cmm-from-stg — dump STG-to-C-- output
  • -ddump-cmm-info — dump the results of the C-- info table augmentation pass
  • -ddump-cmm-opt — dump the results of C-- to C-- optimising passes
  • -ddump-cmm-proc — dump the results of proc-point analysis
  • -ddump-cmm-procmap — dump the results of the C-- proc-point map pass
  • -ddump-cmm-raw — dump raw C--
  • -ddump-cmm-sink — dump the results of the C-- sinking pass
  • -ddump-cmm-sp — dump the results of the C-- stack layout pass
  • -ddump-cmm-split — dump the results of the C-- proc-point splitting pass
  • -ddump-cmm-switch — dump the results of switch lowering passes
  • -ddump-cmm-thread-sanitizer — dump the results of the C-- ThreadSanitizer elaboration pass
  • -ddump-cmm-verbose — write output from main C-- pipeline passes to files 📁
  • -ddump-cmm-verbose-by-proc — show output from main C-- pipeline passes (grouped by proc)

core & analysis dumps

  • -ddump-core-stats — print a one-line summary of the size of the Core program at the end of the optimisation pipeline 📏
  • -ddump-cpr-signatures — dump CPR signatures
  • -ddump-cpranal — dump CPR analysis output
  • -ddump-cs-trace — trace constraint solver
  • -ddump-cse — dump CSE output
  • -ddump-debug — spills out the generated DWARF debug information 🐛 like it's showing you the receipts of your own binary, bestie.
  • -ddump-deriv — dumps the whole deriving output, so you can see exactly what the compiler manifested for you ✨.
  • -ddump-dmd-signatures — dumps the top-level demand signatures. very serious analysis energy, ngl.
  • -ddump-dmdanal — dumps the demand analysis output 💅 the compiler's little "who actually needs what, and when" report.
  • -ddump-ds — dumps the desugarer output, periodt. that's the core after all the syntactic sugar got dissolved.
  • -ddump-ec-trace — traces the exhaustiveness checker 🔍 so you can watch it check whether your patterns cover everything.
  • -ddump-exitify — dumps output of the exitification pass. yes that's the real name, iconic.
  • -ddump-faststrings — dumps the whole FastString table when it's all finished 🫶 the entire vibe, archived.
  • *-ddump-file-prefix=str* — sets the prefix of the filenames used for debugging output 📁 so your dumps get cute little name tags.
  • -ddump-float-in — dumps float in output. floating, literally.
  • -ddump-foreign — dumps foreign export stubs 🌍 for when your Haskell is talking to the outside world.
  • -ddump-full-laziness — dumps full laziness pass output. being lazy but make it productive ✨.
  • -ddump-hie — dumps the hie file syntax tree 🌳 the whole tree-shaped truth.
  • -ddump-hpc — an alias for -ddump-ticked 🎀 (yes, it's giving "same energy, different name").
  • -ddump-if-trace — traces interface files, iykyk. every step of the interface-file saga, on display.
  • -ddump-inlinings — dumps the inlinings performed by the simplifier 💫 so you can see what got folded in where.
  • -ddump-js — dumps the final JavaScript code, bestie. full backend reveal 🦋.
  • -ddump-json — deprecated, so use -fdiagnostics-as-json instead 💀 no cap, the old one's on its way out.
  • -ddump-late-cc — dumps core with late cost centres added, so your profiling instrumentation is right there in the middle of the core 🔥.
  • -ddump-liberate-case — dumps liberate case output. freeing the case expressions, main character energy.
  • -ddump-llvm — dumps LLVM intermediate code 👑 for when you're going through the LLVM backend.
  • -ddump-mod-map — dumps the state of the module mapping database 🗂️ a little snapshot of who maps to what.
  • -ddump-occur-anal — dumps occurrence analysis output ✨ the analysis where the compiler clocks who shows up and how often.
  • -ddump-opt-cmm — dumps the results of C-- to C-- optimising passes 💅 C-- stays winning.
  • -ddump-parsed — dumps the parse tree 🌳 pure syntax-tree realness, before anything else has touched it.
  • -ddump-parsed-ast — dumps parser output as a syntax tree ✨ the AST version of the same vibe.
  • -ddump-prep — dumps prepared core, which is core in its prepped era 🎀.
  • -ddump-rn — dumps renamer output. the renamer said what it said.
  • -ddump-rn-ast — dumps renamer output as a syntax tree 🌳.
  • -ddump-rn-stats — renamer stats 📊 numbers about the renaming, slay.
  • -ddump-rn-trace — traces the renamer 🔍.
  • -ddump-rtti — traces runtime type inference 💫 types, inferred, at runtime.
  • -ddump-rule-firings — dumps rule firing info 🔥 literally the rules going off.
  • -ddump-rule-rewrites — dumps detailed rule firing info 🔥🔥 extra detailed, because you deserve the full story.
  • -ddump-rules — dumps rewrite rules. the rulebook, unedited 💅.
  • -ddump-simpl — dumps the final simplifier output ✨ the simplifier's final form, iconic.
  • -ddump-simpl-iterations — dumps output from each simplifier iteration 🔁 one dump per round, no skipping.
  • -ddump-simpl-stats — dumps simplifier stats 📊.
  • -ddump-simpl-trace — dumps trace messages in the simplifier 🔍.
  • -ddump-spec — dumps specialiser output ✨ the specialiser's greatest hits.
  • -ddump-spec-constr — dumps specialiser output from SpecConstr 🎀 constructor-flavoured specialization.
  • -ddump-splices — dumps TH spliced expressions, and what they evaluate to 💫 template Haskell showing off its handiwork.
  • -ddump-static-argument-transformation — dumps static argument transformation output. SAT, but the compiler kind, not the vibe-killer exam.
  • -ddump-stg — deprecated, it's an alias for -ddump-stg-from-core 💀.
  • -ddump-stg-cg — shows output after Stg2Stg 🌸 the post-pass glow-up.
  • -ddump-stg-final — shows output of the last STG pass 👑 the final form.
  • -ddump-stg-from-core — shows CoreToStg output, the moment core becomes STG 🦋.
  • -ddump-stg-tags — shows output of the tag inference pass 🏷️ tagged and thriving.
  • -ddump-stg-unarised — shows unarised STG. yes, unarised is the word, bestie.
  • -ddump-str-signatures — deprecated, alias for -ddump-dmd-signatures 💀.
  • -ddump-stranal — deprecated, alias for -ddump-dmdanal 💀.
  • -ddump-tc — dumps typechecker output 🌈 the typechecker checked, and now you get to see it.
  • -ddump-tc-ast — dumps typechecker output as a syntax tree 🌳.
  • -ddump-tc-trace — traces the typechecker 🔍 every single typechecking moment, exposed.
  • -ddump-ticked — dumps the code instrumented by HPC (Observing Code Coverage) 🎯 coverage ticks and all.
  • -ddump-timings — dumps per-pass timing and allocation statistics ⏱️ so you know exactly which pass is eating your build time.
  • -ddump-to-file — dumps to files instead of stdout 📁 which, honestly, is the move when the dump is huge.
  • -ddump-types — dumps type signatures 🖊️ the types, in writing.
  • -ddump-verbose-inlinings — dumps all considered inlinings 💅 not just the ones that won, but every candidate.
  • -ddump-view-pattern-commoning — dumps commoned view patterns ✨.
  • -ddump-worker-wrapper — dumps worker-wrapper output 🔧 the classic worker/wrapper transformation, on display.
  • -dfaststring-stats — shows statistics for fast string usage when finished 📊.
  • -dhex-word-literals — prints values of type Word# in hexadecimal 🧮 hex girl summer.
  • *-dinitial-unique=s* — starts UniqSupply allocation from s 🎀 pick your starting point.
  • *-dinline-check=str* — dumps information about inlining decisions 🔍 so you can see why the inliner did what it did.
  • -dipe-stats — shows statistics about IPE information 📊.
  • -dkeep-comments — includes comments in the parser 🫶 useful in combination with -ddump-parsed-ast, so keep that in mind.
  • -dlinear-core-lint — turns on internal sanity checking 🧠 not a vibe check, an actual sanity check.
  • -dlint — enables several common internal sanity checkers ✅ the all-in-one sanity bundle.
  • -dno-debug-output — suppresses unsolicited debugging output 🙈 the compiler stops oversharing.
  • -dno-typeable-binds — doesn't generate bindings for Typeable methods 🚫.
  • -dppr-case-as-let — prints single alternative case expressions as strict lets 💅 a formatting choice, and honestly a look.
  • *-dppr-cols=n* — sets the width of debugging output 📏 for example -dppr-cols200.
  • -dppr-debug — turns on debug printing, which is more verbose 🔍 so much more verbose.
  • -dppr-user-length — sets the depth for printing expressions in error msgs 🎀 so your errors stay readable.
  • *-drule-check=str* — dumps information about potential rule application 🔍 the almost-fired rules.
  • -dshow-passes — prints out each pass name as it happens 📢 live commentary from the compiler.
  • -dstg-lint — STG pass sanity checking 🧠.
  • -dsuppress-all — in dumps, suppresses everything (except for uniques) that is suppressible 🙈 maximum minimalism.
  • -dsuppress-coercion-types — suppresses the printing of coercion types in Core dumps to make them shorter ✂️ shorter dumps, less scrolling.
  • -dsuppress-coercions — suppresses the printing of coercions in Core dumps to make them shorter ✂️.
  • -dsuppress-core-sizes — suppresses the printing of core size stats per binding (since 9.4) 📉.
  • -dsuppress-idinfo — suppresses extended information about identifiers where they are bound 🙈.
  • -dsuppress-module-prefixes — suppresses the printing of module qualification prefixes 🚫 so no more M. everywhere.
  • -dsuppress-stg-free-vars — suppresses the printing of closure free variable lists in STG output ✂️.
  • -dsuppress-stg-reps — suppresses rep annotations on STG args 💅.
  • -dsuppress-ticks — suppresses "ticks" in the pretty-printer output 🎀.
  • -dsuppress-timestamps — suppresses timestamps in dumps ⏱️ which is lowkey essential for clean diffs.
  • -dsuppress-type-applications — suppresses type applications 🚫.
  • -dsuppress-type-signatures — suppresses type signatures 🚫.
  • -dsuppress-unfoldings — suppresses the printing of the stable unfolding of a variable at its binding site ✂️.
  • -dsuppress-uniques — suppresses the printing of uniques in debug output (easier to use diff) 🫶 genuinely so helpful for diffing.
  • -dsuppress-var-kinds — suppresses the printing of variable kinds 🚫.
  • -dtag-inference-checks — affirms tag inference results are correct at runtime ✅ runtime confirmation, no cap.
  • -dth-dec-file — dumps evaluated TH declarations into *.th.hs files 📁.
  • *-dunique-increment=i* — sets the increment for the generated Unique's to i 🎀.
  • -dverbose-core2core — shows output from each core-to-core pass 🔁 every pass, out loud.
  • -dverbose-stg2stg — shows output from each STG-to-STG pass 🔁.
  • -fadd-bco-name — adds BCO_NAME instructions in generated bytecode 🏷️.
  • -falignment-sanitisation — compiles with alignment checks for all info table dereferences 🛡️.
  • -fcatch-nonexhaustive-cases — adds a default error alternative to case expressions without a default alternative 🚨 so a non-exhaustive case becomes a runtime error instead of undefined chaos.
  • -fcheck-prim-bounds — instruments array primops with bounds checks 🚧 safety first, bestie.
  • -fcmm-thread-sanitizer — enables ThreadSanitizer instrumentation of memory accesses 🧵 catching the races.
  • -fdistinct-constructor-tables — generates a fresh info table for each usage of a data constructor 🎀 every single one gets its own table.
  • -fdump-with-ways — includes the tag of the enabled ways in the extension of dump files 🏷️.
  • -finfo-table-map — embeds a lookup table in the generated binary which maps the address of an info table to the source position the closure originated from 🗺️ the ultimate "where did this come from" map.
  • -finfo-table-map-with-fallback — includes info tables with no source location information in the info table map 🫶.
  • -finfo-table-map-with-stack — includes info tables for STACK closures in the info table map 🥞.
  • -fllvm-fill-undef-with-garbage — instructs LLVM to fill dead STG registers with garbage 🗑️ (yes, deliberately garbage, it's on purpose).
  • -fno-info-table-map-with-fallback — omits info tables with no source location information from the info table map 🚫.
  • -fno-info-table-map-with-stack — omits info tables for STACK closures from the info table map 🚫.
  • -forig-thunk-info — generates stg_orig_thunk_info stack frames on thunk entry 🧵.
  • -fproc-alignment — aligns functions at given boundary 📐.
  • -funoptimized-core-for-interpreter — disables optimizations with the interpreter 🐢 unoptimized but interpretable.
  • -g — produces DWARF debug information in compiled object files 🐛 n can be 0, 1, or 2, with higher numbers producing richer output. If n is omitted, level 2 is assumed ✨.

🎀 C pre-processor 🎀

  • -cpp — runs the C pre-processor on Haskell source files 🏃‍♀️ yes, on Haskell files, that's the whole bit.
  • -D<symbol>[=<value>] — defines a symbol in the C pre-processor 🏷️.
  • -I<dir> — adds dir to the directory search list for #include files 📁.
  • -U<symbol> — undefines a symbol in the C pre-processor 🚫.

🧚 Finding imports 🧚

  • -i — empties the import directory list 🧹 a clean slate, bestie.
  • -i<dir>[:<dir>]* — adds dir, dir2, etc. to the import path 🛤️ one or many, colon-separated.

💅 Interactive mode 💅

  • -fbreak-on-error — breaks on uncaught exceptions and errors 🛑.
  • -fbreak-on-exception — breaks on any exception thrown 💥.
  • -fbreak-points — inserts breakpoints in the GHCi debugger 🎯 debugging era.
  • *-fghci-hist-size=n* — sets the number of entries GHCi keeps for :history 📜 see The GHCi Debugger.
  • -fghci-leak-check — (debugging only) checks for space leaks when loading new modules in GHCi 🫧 leak hunting, but only for debugging.
  • -fimplicit-import-qualified — puts in scope qualified identifiers for every loaded module 🌈.
  • -flocal-ghci-history — uses current directory for the GHCi command history file .ghci-history 📁 keeping it local, keeping it cute.
  • -fno-it — no longer sets the special variable it 🚫 that variable's era is over.
  • -fprint-bind-result — turns on printing of binding results in GHCi 🖨️.
  • -fprint-evld-with-show — instructs :print to use Show instances where possible 💅.
  • -fshow-loaded-modules — shows the names of modules that GHCi loaded after a :load command 📋.
  • -ghci-script — reads additional .ghci files 📜 more scripts, more power.
  • -ignore-dot-ghci — disables reading of .ghci files 🙈.
  • -interactive-print name — selects the function to use for printing evaluated expressions in GHCi 🖨️ you pick the printer, you're the main character.

🫶 Interface files 🫶

  • --show-iface file — see Modes of operation 👀.
  • -ddump-hi — dumps the new interface to stdout 📤 the interface, right there in your terminal.
  • -ddump-hi-diffs — shows you the diff between the new interface and the old one 🫶 like a glow-up reveal for your .hi files.
  • -ddump-minimal-imports — dumps out the most minimal set of imports that would still make your module work. iykyk, it's giving "declutter your room" energy 🎀

🧚 Keeping intermediate files 🧚

okay so normally GHC cleans up after itself like a good roommate, but if you want to keep the mess around for inspection, these are your girls ✨

  • -keep-hc-file — keeps the intermediate .hc files around 💅
  • -keep-hi-files — keeps the intermediate .hi files. lowkey this one is already the default, no cap.
  • -keep-hscpp-file — keeps the intermediate .hscpp files, for when you gotta see the post-preprocessor tea ☕
  • -keep-llvm-file — keeps the intermediate LLVM .ll files. heads up bestie: this one implies -fllvm 🔥
  • -keep-o-files — keeps the intermediate .o files. also the default already, so it's giving "yes queen we know" 💀
  • -keep-s-file — keeps the intermediate .s files, assembly girlies rise 🌸
  • -keep-tmp-files — keeps all the intermediate temporary files. every last one. no crumbs left behind 🙈

✨ Language options ✨

this is the section that goes on forever and honestly? iconic. every -X flag you could ever want, one per bullet, all facts intact 💖

  • -XAllowAmbiguousTypes — lets you write ambiguous types, and lets the type inference engine infer them too ✨
  • -XApplicativeDo — lets do-notation statements desugar via Applicative instead of only Monad. slay.
  • -XArrows — allows arrow notation, e.g. proc 🏹
  • -XBangPatterns — allows bang pattern syntax. ! goes brr.
  • -XBinaryLiterals — allows binary literal syntax. 0b1010 bestie 💅
  • -XBlockArguments — allows do blocks and other constructs to be passed as function arguments 🫶
  • -XCApiFFI — allows foreign imports to be declared with the capi calling convention.
  • -XConstrainedClassMethods — allows class methods to have non-empty contexts 👑
  • -XConstraintKinds — allows constraints to be used as types of kind Constraint.
  • -XCPP — resolves C preprocessor directives. yes the preprocessor is crashing the function party 🎉
  • -XCUSKs — detects complete user-supplied kind signatures. (yes, CUSKs. that's the real acronym. we love her.)
  • -XDataKinds — allows use of data constructors in types 🌈
  • -XDatatypeContexts — allows contexts on data types.
  • -XDeepSubsumption — uses GHC's deep subsumption checking.
  • -XDefaultSignatures — allows default signatures for typeclass methods 💜
  • -XDeriveAnyClass — allows deriving syntax to be used for any class. any. periodt.
  • -XDeriveDataTypeable — allows deriving for the Data class.
  • -XDeriveFoldable — allows deriving for the Foldable class.
  • -XDeriveFunctor — allows deriving for the Functor class.
  • -XDeriveGeneric — allows deriving of Generic instances.
  • -XDeriveLift — allows deriving for the Lift class.
  • -XDeriveTraversable — allows deriving for the Traversable class.
  • -XDerivingStrategies — allows use of instance deriving strategies 🎀
  • -XDerivingVia — allows deriving instances via types of the same runtime representation. it's giving "same vibe, different wrapper" ✨
  • -XDisambiguateRecordFields — automatically disambiguates some record field references. so thoughtful of her.
  • -XDuplicateRecordFields — allows definition of record types with identically-named fields. literally two fields, one name, zero drama 💅
  • -XEmptyCase — allows case expressions with no alternatives. empty but make it fashion 💀
  • -XEmptyDataDecls — allows definition of empty data types.
  • -XEmptyDataDeriving — allows deriving instances of standard type classes for empty data types 🫶
  • -XExistentialQuantification — allows existentially quantified type variables in types.
  • -XExplicitForAll — allows explicit universal quantification. forall said out loud 🗣️
  • -XExplicitNamespaces — allows use of the keyword type to specify the namespace of entries in imports and exports.
  • -XExtendedDefaultRules — uses GHCi's extended default rules in a normal module. GHCi behaviour, main character energy 👑
  • -XExtendedLiterals — allows numeric literal postfix syntax for unboxed integers.
  • -XFieldSelectors — makes record field selector functions visible in expressions 👀
  • -XFlexibleContexts — removes some restrictions on class contexts.
  • -XFlexibleInstances — allows instance heads to mention arbitrary nested types 🌸
  • -XForeignFunctionInterface — allows foreign function interface syntax. hello C, nice to meet you 🤝
  • -XFunctionalDependencies — allows functional dependencies to be given on typeclass declarations.
  • -XGADTs — allows definition of generalised algebraic data types ✨
  • -XGADTSyntax — allows generalised algebraic data type syntax.
  • -XGeneralisedNewtypeDeriving — allows instances to be derived via newtype deriving. (the British spelling, we stan 🇬🇧)
  • -XGeneralizedNewtypeDeriving — allows instances to be derived via newtype deriving. (the American spelling, equally valid 🦅)
  • -XGHC2021 — uses GHC's set of default language extensions from 2021. vintage but not that vintage 💅
  • -XGHC2024 — uses GHC's set of default language extensions from 2024. fresh out the oven 🔥
  • -XGHCForeignImportPrim — allows the prim calling convention. intended for internal use only bestie, so like… stay out of there 🙈
  • -XHaskell2010 — uses the Haskell 2010 language edition.
  • -XHaskell98 — uses the Haskell 98 language edition. ancient, respect her 🏛️
  • -XHexFloatLiterals — allows hexadecimal floating-point literal syntax.
  • -XImplicitParams — allows implicit parameter constraints.
  • -XImplicitPrelude — implicitly imports Prelude. the default of defaults.
  • -XImportQualifiedPost — allows the syntax import M qualified.
  • -XImpredicativeTypes — allows impredicative types. don't ask, just know she's powerful 😭
  • -XIncoherentInstances — allows definitions of instances that may result in incoherence. chaotic, but on purpose 💀
  • -XInstanceSigs — allows type signatures to be written for instance methods ✨
  • -XInterruptibleFFI — allows interruptible FFI imports.
  • -XKindSignatures — allows kind signatures to be given for types 🎀
  • -XLambdaCase — allows \case expressions. so much cleaner, obsessed.
  • -XLexicalNegation — uses whitespace to determine whether the minus sign stands for negation or subtraction. whitespace is doing work here 👑
  • -XLiberalTypeSynonyms — relaxes many of Haskell 98's rules on type synonym definitions.
  • -XLinearTypes — allows writing of linear arrow types. implies MonoLocalBinds 🫶
  • -XListTuplePuns — enables punning for list, tuple and sum types.
  • -XMagicHash — allows # as a postfix modifier on identifiers. magic by name, magic by nature 🔮
  • -XMonadComprehensions — allows list comprehension syntax to be used at monads other than List.
  • -XMonoLocalBinds — does not generalise types of local bindings. no generalising, we stay specific 💅
  • -XMonomorphismRestriction — applies the Haskell 2010 monomorphism restriction.
  • -XMultilineStrings — enables multiline string literals. finally, room to breathe 📝
  • -XMultiParamTypeClasses — enables multi-parameter type classes.
  • -XMultiWayIf — allows multi-way if-expressions.
  • -XNamedDefaults — enables default declarations with explicitly named class, extending Type class defaulting ✨
  • -XNamedFieldPuns — allows record field punning syntax.
  • -XNamedWildCards — allows named wildcards in types.
  • -XNegativeLiterals — allows negative numeric literal syntax. minus signs, but make it literal.
  • -XNondecreasingIndentation — allows nested contexts to be at the same indentation level as its enclosing context 🌸
  • -XNPlusKPatterns — allows use of n+k patterns.
  • -XNullaryTypeClasses — deprecated, does nothing. nullary type classes are now enabled using MultiParamTypeClasses. so like… retire her 💀
  • -XNumDecimals — allows use of scientific notation syntax for integer literals.
  • -XNumericUnderscores — allows underscores in numeric literals. 1_000_000 my beloved 🥰
  • -XOrPatterns — enables or-patterns.
  • -XOverlappingInstances — allows definition of overlapping instances.
  • -XOverloadedLabels — allows overloaded label syntax.
  • -XOverloadedLists — desugars list syntax via the IsList class.
  • -XOverloadedRecordDot — allows . to be used for record field access. dot notation girlies we are SO back 💅
  • -XOverloadedRecordUpdate — allows . syntax in record updates.
  • -XOverloadedStrings — desugars string literals via the IsString class.
  • -XPackageImports — allows package-qualified import syntax.
  • -XParallelListComp — allows parallel list comprehension syntax ⚡
  • -XPartialTypeSignatures — allows type signatures to contain wildcards 🎀
  • -XPatternGuards — allows pattern guards syntax.
  • -XPatternSynonyms — allows definition of pattern synonyms.
  • -XPolyKinds — allows kind polymorphism 🌈
  • -XPostfixOperators — allows the use of postfix operators.
  • -XQualifiedDo — allows qualified do-notation desugaring.
  • -XQuantifiedConstraints — allows forall quantifiers in constraints 👑
  • -XQuasiQuotes — allows quasiquotation syntax.
  • -XRank2Types — enables rank-2 types.
  • -XRankNTypes — allows types of rank greater than one.
  • -XRebindableSyntax — allows rebinding of builtin syntax. yes you can change the builtins, no I'm not scared 😭
  • -XRecordWildCards — allows use of record wildcard syntax.
  • -XRecursiveDo — allows recursive do (e.g. mdo) notation.
  • -XRequiredTypeArguments — allows use of required type argument syntax in terms.
  • -XRoleAnnotations — allows role annotation syntax.
  • -XSafe — enables the Safe Haskell Safe mode 🛡️
  • -XScopedTypeVariables — lexically scopes explicitly-introduced type variables.
  • -XStandaloneDeriving — allows standalone instance deriving declarations.
  • -XStandaloneKindSignatures — allows standalone kind signature declarations ✨
  • -XStarIsType — treats * as Data.Kind.Type.
  • -XStaticPointers — allows static syntax.
  • -XStrict — makes bindings in the current module strict by default. no laziness in this house 🫶
  • -XStrictData — treats datatype fields as strict by default.
  • -XTemplateHaskell — allows Template Haskell's splice and quotation syntax.
  • -XTemplateHaskellQuotes — allows Template Haskell's quotation syntax. (quotes only, not the splices, okurrr)
  • -XTraditionalRecordSyntax — allows traditional record syntax (e.g. C {f = x}).
  • -XTransformListComp — allows generalised list comprehension syntax.
  • -XTrustworthy — enables the Safe Haskell Trustworthy mode 🤝
  • -XTupleSections — allows use of tuple section syntax.
  • -XTypeAbstractions — allows type abstraction syntax in patterns and type variable binders.
  • -XTypeApplications — allows type application syntax in terms and types 🌸
  • -XTypeData — allows type data declarations.
  • -XTypeFamilies — allows definition of type families. found family but make it types 💖
  • -XTypeFamilyDependencies — allows injectivity annotations on type families.
  • -XTypeInType — deprecated. enables kind polymorphism and datatype promotion. she's retired bestie, move on 💀
  • -XTypeOperators — allows type constructors to be given operator names.
  • -XTypeSynonymInstances — allows type synonyms to be mentioned in instance heads.
  • -XUnboxedSums — allows the use of unboxed sum syntax.
  • -XUnboxedTuples — allows the use of unboxed tuple syntax.
  • -XUndecidableInstances — allows definition of instances which may make solving undecidable. highkey risky, but she's iconic for it 🔥
  • -XUndecidableSuperClasses — lets you have literally all the superclass constraints, even the ones that might make the typechecker spin forever. non-termination? she's allowed 💅
  • -XUnicodeSyntax — unicode syntax ON, bestie ✨
  • -XUnliftedDatatypes — lets you define unlifted data types 🦋
  • -XUnliftedFFITypes — lets foreign imports have certain unlifted types in their signatures 🔥
  • -XUnliftedNewtypes — lets you define unlifted newtypes. iconic 💜
  • -XUnsafe — turns on Safe Haskell Unsafe mode 🚨
  • -XViewPatterns — allows view pattern syntax 👑

🔗 Linking options 🫶

  • -c — stop after generating the object (.o) file, that's it, we're done here ✋
  • -debug — use the debugging runtime 🐛
  • -dylib-install-name ⟨path⟩ — sets the install name (it's passed to Apple's linker as -install_name), and you give it the full install path of the library file. Any libraries or executables that link with it later will pick up that path as their runtime search location for it. Darwin/OS X only 🍎
  • -dynamic — build dynamically-linked object files and executables 💫
  • -dynload — picks one of a number of modes for finding shared libraries at runtime 🔍
  • -eventlog — enable runtime event tracing 📊
  • -fcompact-unwind — tells the linker to produce a __compact_unwind section 🌀
  • -fkeep-cafs — do not garbage-collect CAFs (top-level expressions) at runtime, they stay 🫶
  • -flink-rts — link the runtime when generating a shared or static library 🔗
  • -fno-embed-manifest — don't embed the manifest in the executable (Windows only) 🪟
  • -fno-gen-manifest — don't generate a manifest file (Windows only) 🪟
  • -fno-shared-implib — don't generate an import library for a DLL (Windows only) 🪟
  • -framework ⟨name⟩ — Darwin/OS X/iOS only: link in the framework ⟨name⟩. This option corresponds to the -framework option for Apple's Linker 🍏
  • -framework-path ⟨dir⟩ — Darwin/OS X/iOS only: add ⟨dir⟩ to the list of directories searched for frameworks. This one corresponds to the -F option for Apple's Linker 🍏
  • -fsplit-sections — split sections so link-time dead-code stripping can do its thing ✂️
  • -fuse-rpaths — set the rpath based on -L flags 🛤️
  • -fwhole-archive-hs-libs — when linking a binary executable, this inserts the flag -Wl,--whole-archive before any -l flags for Haskell libraries, and -Wl,--no-whole-archive after them 📦
  • -L ⟨dir⟩ — add ⟨dir⟩ to the list of directories searched for libraries 📁
  • -l ⟨lib⟩ — link in library ⟨lib⟩ 🔗
  • -main-is ⟨thing⟩ — set the main module and function 🎯
  • -no-hs-main — don't assume this program contains main 🙈
  • -no-pie — don't instruct the linker to produce a position-independent executable 🚫
  • -no-rtsopts-suggestions — don't print RTS suggestions about linking with -rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] 🤫
  • -package ⟨name⟩ — expose package ⟨pkg⟩ 📦
  • -pie — instruct the linker to produce a position-independent executable ✨
  • -rdynamic — tells the linker to add all symbols to the dynamic symbol table, not just the used ones. Currently Linux and Windows/MinGW32 only. It's equivalent to using -optl -rdynamic on Linux, and -optl -export-all-symbols on Windows 🔥
  • -rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] — controls whether the RTS behaviour can be tweaked via command-line flags and the GHCRTS environment variable. Let's break it down, bestie:
    • none means no RTS flags can be given at all
    • some means only a minimum of safe options can be given (this is the default, if -rtsopts is not passed)
    • all means all RTS flags are permitted (this is the default, if -rtsopts is passed with no argument)
    • ignore means RTS flags can be given, but they're treated as regular arguments and passed to the Haskell program as arguments
    • ignoreAll is the same as ignore, but GHCRTS is also ignored
ngl this one's important: -rtsopts does not affect -with-rtsopts behavior. Flags passed via -with-rtsopts are used regardless of -rtsopts 💀
  • -shared — generate a shared library (as opposed to an executable) 📚
  • -single-threaded — use the single-threaded runtime 1️⃣
  • -static — use static Haskell libraries 🗿
  • -staticlib — generate a standalone static library (as opposed to an executable). This is useful when cross compiling. The library, together with all its dependencies, ends up in a single static library that you can link against 🧱
  • -threaded — use the threaded runtime 🧵
  • -with-rtsopts=⟨opts⟩ — set the default RTS options to ⟨opts⟩ ⚙️

🧩 Miscellaneous options 🍓

  • -ddump-mod-cycles — dump module cycles 🔄
  • -fdefer-out-of-scope-variables — converts "variable out of scope" errors into warnings. It's implied by -fdefer-type-errors. See also -Wdeferred-out-of-scope-variables 🙈
  • -fdefer-type-errors — turns type errors into warnings, deferring the error until runtime. Implies -fdefer-typed-holes and -fdefer-out-of-scope-variables. See also -Wdeferred-type-errors 😭
  • -fdefer-typed-holes — converts typed hole errors into warnings, deferring the error until runtime. Implied by -fdefer-type-errors. See also -Wtyped-holes 🕳️
  • -fexternal-interpreter — run interpreted code in a separate process 🧚
  • -ffamily-application-cache — use a cache when reducing type family applications 🗄️
  • -fglasgow-exts — deprecated ⚠️ enables most language extensions; see Controlling editions and extensions for exactly which ones
  • -fno-safe-haskell — disable Safe Haskell 🛑
  • -ghcversion-file ⟨path to ghcversion.h⟩ — (GHC as a C compiler only) use this ghcversion.h file 📄
  • -H ⟨size⟩ — set the minimum size of the heap to ⟨size⟩ 📏
  • -hidden-module ⟨module name⟩ — a module which should not be visible outside its unit 🙈
  • -j[⟨n⟩] — when compiling with --make, compile ⟨n⟩ modules in parallel ⚡
  • -jsem — when compiling with --make, coordinate with other processes through the semaphore ⟨sem⟩ to compile modules in parallel 🤝
  • -reexported-module ⟨reexport-spec⟩ — a module which should be reexported from this unit 🔁
  • -this-package-name ⟨unit-id⟩ — the name of the package which this module would be part of when installed 📦
  • -unit @⟨filename⟩ — specify the options to build a specific unit 🧱
  • -working-dir ⟨dir⟩ — specify the directory a unit is expected to be compiled in 📁

🎛️ Modes of operation 👑

  • --frontend ⟨module⟩ — run GHC with the given frontend plugin; see Frontend plugins for the deets 🔌
  • --help — display help 🆘
  • --info — display information about the compiler ℹ️
  • --interactive — interactive mode — normally used by just running ghci; see Using GHCi for details 💬
  • --make — build a multi-module Haskell program, automatically figuring out dependencies. Likely to be much easier, and faster, than using make; see Using ghc --make for details 🏗️
  • --numeric-version — display GHC version (numeric only) 🔢
  • --print-booter-version — display bootstrap compiler version 🥾
  • --print-build-platform — display platform on which GHC was built 🏭
  • --print-c-compiler-flags — C compiler flags used to build GHC 🅲
  • --print-c-compiler-link-flags — C linker flags used to build GHC 🔗
  • --print-debug-on — print whether GHC was built with -DDEBUG 🐛
  • --print-global-package-db — display GHC's global package database directory 📚
  • --print-have-interpreter — display whether GHC was built with interactive support 💬
  • --print-have-native-code-generator — display whether target platform has NCG support ⚙️
  • --print-host-platform — display host platform of GHC 🖥️
  • --print-ld-flags — display linker flags used to compile GHC 🔧
  • --print-leading-underscore — display use of leading underscores on symbol names _
  • --print-libdir — display GHC library directory 📁
  • --print-object-splitting-supported — display whether GHC supports object splitting ✂️
  • --print-project-git-commit-id — display Git commit id GHC is built from 🔖
  • --print-project-version — display GHC version 🏷️
  • --print-rts-ways — display which way RTS was built 🛠️
  • --print-stage — display stage number of GHC 🪜
  • --print-support-smp — display whether GHC was compiled with SMP support 🧵
  • --print-tables-next-to-code — display whether GHC was compiled with --enable-tables-next-to-code 📊
  • --print-target-platform — display target platform of GHC 🎯
  • --print-unregisterised — display whether this GHC was built in unregisterised mode 🗿
  • --run ⟨file⟩ — run a Haskell program 🏃
  • --show-iface ⟨file⟩ — display the contents of an interface file 📄
  • --show-options — display the supported command line options 📋
  • --supported-extensions — display the supported language extensions 🧩
  • --version — display GHC version 🏷️
  • -e ⟨expr⟩ — evaluate expr; see Expression evaluation mode for details 🧮
  • -M — generate dependency information suitable for use in a Makefile; see Dependency generation for details 📝
  • -shared — create a shared object 📚

⚡ Individual optimizations 🔥

  • -fasm-shortcutting — enable shortcutting on assembly. Implied by -O2 ✂️
  • -fbinary-blob-threshold=⟨n⟩ — default: 500K. tweak the assembly generator for binary blobs 🧱
  • -fblock-layout-cfg — use the new cfg based block layout algorithm. Implied by -O 🗺️
  • -fblock-layout-weightless — ignore cfg weights for code layout ⚖️
  • -fblock-layout-weights — sets edge weights used by the new code layout algorithm 🏋️
  • -fcall-arity — enable call-arity optimisation. Implied by -O 📞
  • -fcase-folding — enable constant folding in case expressions. Implied by -O 🧊
  • -fcase-merge — enable case-merging. Implied by -O 🔀
  • -fcmm-control-flow — enable control flow optimisation in the Cmm backend. Implied by -O 🌊
  • -fcmm-elim-common-blocks — enable Cmm common block elimination. Implied by -O 🧹
  • -fcmm-sink — enable Cmm sinking. Implied by -O 🕳️
  • -fcmm-static-pred — enable static control flow prediction. Implied by -O 🔮
  • -fcore-constant-folding — enable constant folding in Core. Implied by -O 🧊
  • -fcpr-anal — turn on Constructed Product Result analysis. Implied by -O 🎀
  • -fcross-module-specialise — turns on specialisation of overloaded functions imported from other modules. Implied by -O. no cap ✨
  • -fcse — enables common sub-expression elimination. Implied by -O. slay 💅
  • -fdicts-cheap — makes dictionary-valued expressions seem cheap to the optimiser. lowkey bribing the optimiser 🎀
  • -fdicts-strict — makes dictionaries strict. Implied by -O2. 🦋
  • -fdmd-tx-dict-sel — (deprecated) use a special demand transformer for dictionary selectors. 💀
  • -fdmd-unbox-width=⟨n⟩ — default: 3. Boxity analysis pretends that returned records with this many fields can be unboxed. 🌸
  • -fdo-clever-arg-eta-expansion — enables sophisticated argument eta-expansion. Implied by -O2. 🧚
  • -fdo-eta-reduction — enables eta-reduction. Always enabled by default. ⭐
  • -fdo-lambda-eta-expansion — enables lambda eta-expansion. Always enabled by default. 🌈
  • -feager-blackholing — turns on eager blackholing. 🔥
  • -fenable-rewrite-rules — switches on all rewrite rules (including rules generated by automatic specialisation of overloaded functions). Implied by -O. 💅
  • -fexcess-precision — enables excess intermediate precision. 🎀
  • -fexitification — enables exitification optimisation. Implied by -O. ✨
  • -fexpose-all-unfoldings — exposes all unfoldings, even for very large or recursive functions. 👑
  • -fexpose-overloaded-unfoldings — exposes unfoldings carrying constraints, even for very large or recursive functions. 🦋
  • -ffloat-in — turns on the float-in transformation. Implied by -O. 🌸
  • -ffull-laziness — turns on full laziness (floating bindings outwards). Implied by -O. 🧚
  • -ffun-to-thunk — (deprecated) superseded by -ffull-laziness. 💀
  • -fignore-asserts — ignores assertions in the source. Implied by -O. 🙈
  • -fignore-interface-pragmas — ignores pragmas in interface files. Implied by -O0 only. 🫠
  • -finline-generics — annotates methods of derived Generic and Generic1 instances with INLINE[1] pragmas based on heuristics. Implied by -O. ✨
  • -finline-generics-aggressively — annotates methods of all derived Generic and Generic1 instances with INLINE[1] pragmas. 🔥
  • -finter-module-far-jumps — assumes code sections can be very large. 🦋
  • -fkeep-auto-rules — keeps all "auto" rules, generated by specialisation. 🎀
  • -flate-dmd-anal — runs demand analysis again, at the end of the simplification pipeline. 🌀
  • -flate-specialise — runs a late specialisation pass. ✨
  • -fliberate-case — turns on the liberate-case transformation. Implied by -O2. 💅
  • -fliberate-case-threshold=⟨n⟩ — default: 2000. Sets the size threshold for the liberate-case transformation to ⟨n⟩. 🌸
  • -fllvm-pass-vectors-in-regs — (deprecated) does nothing. 💀
  • -flocal-float-out — enables local floating definitions out of let-binds. 🦋
  • -flocal-float-out-top-level — enables local floating to float top-level bindings. 🧚
  • -floopification — turns saturated self-recursive tail-calls into local jumps in the generated assembly. Implied by -O. 🔥
  • -fmax-forced-spec-args=⟨n⟩ — default: 333. Maximum number of value arguments for forced SpecConstr specializations. 👑
  • -fmax-inline-alloc-size=⟨n⟩ — default: 128. Sets the maximum size of inline array allocations to ⟨n⟩ bytes (default: 128). 🎀
  • -fmax-inline-memcpy-insns=⟨n⟩ — default: 32. Inline memcpy calls if they would generate no more than ⟨n⟩ pseudo instructions. 🌸
  • -fmax-inline-memset-insns=⟨n⟩ — default: 32. Inline memset calls if they would generate no more than ⟨n⟩ pseudo instructions. 🦋
  • -fmax-simplifier-iterations=⟨n⟩ — default: 4. Sets the max iterations for the simplifier. 🌀
  • -fmax-uncovered-patterns=⟨n⟩ — default: 4. Sets the maximum number of patterns to display in warnings about non-exhaustive ones. 👀
  • -fmax-worker-args=⟨n⟩ — default: 10. Maximum number of value arguments for a worker. 💪
  • -fno-opt-coercion — turns off the coercion optimiser. 🚫
  • -fno-pre-inlining — turns off pre-inlining. 🚫
  • -fno-state-hack — turns off the state hack — the thing where any lambda with a real-world state token as argument is considered to be single-entry. Hence it’s OK to inline things inside it. 🫶
  • -fobject-determinism — produces fully deterministic object code. 🎯
  • -fomit-interface-pragmas — doesn’t generate interface pragmas. Implied by -O0 only. 🙈
  • -fomit-yields — omits heap checks when no allocation is being performed. 💅
  • -foptimal-applicative-do — uses a slower but better algorithm for ApplicativeDo. 🐢✨
  • -fpedantic-bottoms — makes GHC more precise about its treatment of bottom (but see also -fno-state-hack). In particular, GHC will not eta-expand through a case expression. 🧐
  • -fpolymorphic-specialisation — allows specialisation to abstract over free type variables. 🌈
  • -fregs-graph — uses the graph colouring register allocator for register allocation in the native code generator. 🎨
  • -fregs-iterative — uses the iterative coalescing graph colouring register allocator in the native code generator. 🌀
  • -fsimpl-tick-factor=⟨n⟩ — default: 100. Sets the percentage factor for simplifier ticks. ⏱️
  • -fsimplifier-phases=⟨n⟩ — default: 2. Sets the number of phases for the simplifier. Ignored with -O0. 🌸
  • -fsolve-constant-dicts — when solving constraints, tries to eagerly solve super classes using available dictionaries. Implied by -O. 🧠
  • -fspec-constr — turns on the SpecConstr transformation. Implied by -O2. 🔥
  • -fspec-constr-count=⟨n⟩ — default: 3.* Sets to ⟨n⟩ the maximum number of specialisations that will be created for any one function by the SpecConstr transformation. ⭐
  • -fspec-constr-keen — specializes a call with an explicit constructor argument, even if the argument is not scrutinised in the body of the function. 🔍
  • -fspec-constr-threshold=⟨n⟩ — default: 2000. Sets the size threshold for the SpecConstr transformation to ⟨n⟩. 🎀
  • -fspec-eval — enables speculative evaluation. ✨
  • -fspec-eval-dictfun — enables speculative evaluation of dictionary functions. 🦋
  • -fspecialise — turns on specialisation of overloaded functions. Implied by -O. 💅
  • -fspecialise-aggressively — turns on specialisation of overloaded functions regardless of size, if unfolding is available. 💥
  • -fspecialise-incoherents — enables specialisation on incoherent instances. 🌀
  • -fstatic-argument-transformation — turns on the static argument transformation. 🎀
  • -fstg-cse — enables common sub-expression elimination on the STG intermediate language. Implied by -O. 🌸
  • -fstg-lift-lams — enables late lambda lifting on the STG intermediate language. Implied by -O2. 🦋
  • -fstg-lift-lams-known — allows turning known into unknown calls while performing late lambda lifting. 👀
  • -fstg-lift-lams-non-rec-args — creates top-level non-recursive functions with at most at most <n> parameters while performing late lambda lifting. 🧚
  • -fstg-lift-lams-rec-args — creates top-level recursive functions with at most at most <n> parameters while performing late lambda lifting. 🌀
  • -fstrictness — turns on demand analysis. Implied by -O. Implies -fworker-wrapper — the way that worker/wrapper gets pulled in, iykyk. 💪
  • -fstrictness-before=⟨n⟩ — runs an additional demand analysis before simplifier phase ⟨n⟩. ⏱️
  • -funbox-small-strict-fields — flattens strict constructor fields with a pointer-sized representation. Implied by -O. 🎁
  • -funbox-strict-fields — flattens strict constructor fields. 📦
  • -funfolding-case-scaling=⟨n⟩ — default: 30. Applies a penalty of (inlining_cost * 1/n) for each level of case nesting. 🌸
  • -funfolding-case-threshold=⟨n⟩ — default: 2. Reduces inlining for cases nested deeper than n. 🌀
  • -funfolding-creation-threshold=⟨n⟩ — default: 750. Tweaks unfolding settings. 🎀
  • -funfolding-dict-discount=⟨n⟩ — default: 30. Tweaks unfolding settings. 🦋
  • -funfolding-fun-discount=⟨n⟩ — default: 60. Tweaks unfolding settings. ✨
  • -funfolding-keeness-factor=⟨n⟩ — this has been deprecated in GHC 9.0.1. 💀
  • -funfolding-use-threshold=⟨n⟩ — default: 90. Tweaks unfolding settings. 💅
  • -fworker-wrapper — enables the worker/wrapper transformation. Implied by -O and by -fstrictness. 🫶
  • -fworker-wrapper-cbv — enables w/w splits for wrappers whose sole purpose is evaluating arguments. 💪
  • -fwrite-if-compression=⟨n⟩ — default: 2. Tweaks the level of interface file compression. 🎀

🚀 Optimization levels 🚀

  • -O — enable level 1 optimisations. 🔥
  • -O0 — disable optimisations (default). 💤
  • -O2 — enable level 2 optimisations. 🔥🔥
  • -O⟨n⟩ — any -On where n > 2 is the same as -O2. periodt 💅

🎁 Package options 🎁

  • -clear-package-db — clears the package db stack. 🧹
  • -distrust ⟨pkg⟩ — exposes package ⟨pkg⟩ and sets it to be distrusted. See Safe Haskell. 🕵️
  • -distrust-all-packages — distrusts all packages by default. See Safe Haskell. 🚨
  • -fpackage-trust — enables Safe Haskell trusted package requirement for trustworthy modules. 🔐
  • -global-package-db — adds the global package db to the stack. 🌍
  • -hide-all-packages — hides all packages by default. 🙈
  • -hide-package ⟨pkg⟩ — hides package ⟨pkg⟩. 🫣
  • -ignore-package ⟨pkg⟩ — ignores package ⟨pkg⟩. 🚫
  • -no-auto-link-packages — doesn’t automatically link in the base and rts packages. 🔗
  • -no-global-package-db — removes the global package db from the stack. 🌍
  • -no-user-package-db — removes the user’s package db from the stack. 👤
  • -package ⟨pkg⟩ — exposes package ⟨pkg⟩. 📦
  • -package-db ⟨file⟩ — adds ⟨file⟩ to the package db stack. 🗂️
  • -package-env ⟨file⟩|⟨name⟩ — uses the specified package environment. 🌱
  • -package-id ⟨unit-id⟩ — exposes package by id ⟨unit-id⟩. 🆔
  • -this-unit-id ⟨unit-id⟩ — compiles to be part of unit (i.e. package) ⟨unit-id⟩. 🧩
  • -trust ⟨pkg⟩ — exposes package ⟨pkg⟩ and sets it to be trusted. See Safe Haskell. 🛡️
  • -user-package-db — adds the user’s package db to the stack. 👤

🛠️ Phases of compilation 🛠️

  • --merge-objs — merges a set of objects into a GHCi library. 🧱
  • -C — stops after generating C (.hc file). 🇨
  • -c — stops after generating object (.o) file. 🔧
  • -E — stop right after preprocessing, so you're left with a .hspp file and vibes ✨
  • -F — turn on a pre-processor, which you pick with -pgmF ⟨cmd⟩ 🎀
  • -S — stop after generating assembly, giving you a .s file 🔥
  • -x ⟨suffix⟩ — override the default behaviour for source files, iykyk

🌈 Overriding external programs 🌈

okay so this whole lil family is literally "hey GHC, use this program instead of the one you'd normally grab" — one flag per tool, no cap 💅

  • -pgma ⟨cmd⟩ — use ⟨cmd⟩ as the assembler
  • -pgmc ⟨cmd⟩ — use ⟨cmd⟩ as the C compiler
  • -pgmCmmP ⟨cmd⟩ — use ⟨cmd⟩ as the C-- C pre-processor
  • -pgmcxx ⟨cmd⟩ — use ⟨cmd⟩ as the C++ compiler
  • -pgmF ⟨cmd⟩ — use ⟨cmd⟩ as the pre-processor (with -F only!)
  • -pgmi ⟨cmd⟩ — use ⟨cmd⟩ as the external interpreter command
  • -pgminstall_name_tool ⟨cmd⟩ — use ⟨cmd⟩ as the program that injects runpath into mach-o dylibs on macOS 🍎
  • -pgmJSP ⟨cmd⟩ — use ⟨cmd⟩ as the JavaScript C pre-processor (only for javascript-backend)
  • -pgmL ⟨cmd⟩ — use ⟨cmd⟩ as the literate pre-processor
  • -pgml ⟨cmd⟩ — use ⟨cmd⟩ as the linker
  • -pgmlas ⟨cmd⟩ — use ⟨cmd⟩ as the LLVM assembler
  • -pgmlc ⟨cmd⟩ — use ⟨cmd⟩ as the LLVM compiler
  • -pgmlm ⟨cmd⟩ — use ⟨cmd⟩ as the linker when merging object files
  • -pgmlo ⟨cmd⟩ — use ⟨cmd⟩ as the LLVM optimiser
  • -pgmotool ⟨cmd⟩ — use ⟨cmd⟩ as the program to inspect mach-o dylibs on macOS 🍎
  • -pgmP ⟨cmd⟩ — use ⟨cmd⟩ as the C pre-processor (with -cpp only)
  • -pgms ⟨cmd⟩ — use ⟨cmd⟩ as the splitter
  • -pgmwindres ⟨cmd⟩ — use ⟨cmd⟩ as the program for embedding manifests on Windows 🪟
note the lowercase/uppercase chaos bestie: -pgml = linker, -pgmL = literate pre-processor. yes really. the case matters, do not come for me 😭

🦋 Phase-specific options 🦋

same energy, opposite direction: instead of naming a whole program, you pass one single option straight through to a tool 👑

  • -opta ⟨option⟩ — pass ⟨option⟩ to the assembler
  • -optc ⟨option⟩ — pass ⟨option⟩ to the C compiler
  • -optCmmP ⟨option⟩ — pass ⟨option⟩ to the C-- C pre-processor
  • -optcxx ⟨option⟩ — pass ⟨option⟩ to the C++ compiler
  • -optF ⟨option⟩ — pass ⟨option⟩ to the custom pre-processor
  • -opti ⟨option⟩ — pass ⟨option⟩ to the interpreter sub-process
  • -optJSP ⟨option⟩ — pass ⟨option⟩ to JavaScript C pre-processor (only for javascript-backend)
  • -optL ⟨option⟩ — pass ⟨option⟩ to the literate pre-processor
  • -optl ⟨option⟩ — pass ⟨option⟩ to the linker
  • -optlas ⟨option⟩ — pass ⟨option⟩ to the LLVM assembler
  • -optlc ⟨option⟩ — pass ⟨option⟩ to the LLVM compiler
  • -optlm ⟨option⟩ — pass ⟨option⟩ to the linker when merging object files
  • -optlo ⟨option⟩ — pass ⟨option⟩ to the LLVM optimiser
  • -optP ⟨option⟩ — pass ⟨option⟩ to cpp (with -cpp only)
  • -optwindres ⟨option⟩ — pass ⟨option⟩ to windres
  • -pgmc-supports-no-pie — (deprecated 👴) indicate that the linker supports -no-pie
  • -pgml-supports-no-pie — indicate that the linker supports -no-pie

🌸 Platform-specific options 🌸

SIMD era 💅 these are basically you telling GHC "bestie the CPU can do this, go off". Several of them are x86 only, and I've flagged each one fr fr.

  • -mavx — (x86 only) enable support for AVX SIMD extensions
  • -mavx2 — (x86 only) enable support for AVX2 SIMD extensions
  • -mavx512cd — (x86 only) enable support for AVX512-CD SIMD extensions
  • -mavx512er — (x86 only) enable support for AVX512-ER SIMD extensions
  • -mavx512f — (x86 only) enable support for AVX512-F SIMD extensions
  • -mavx512pf — (x86 only) enable support for AVX512-PF SIMD extensions
  • -mbmi — (x86 only) use BMI1 for bit manipulation operations
  • -mbmi2 — (x86 only) use BMI2 for bit manipulation operations
  • -mfma — use native FMA instructions for fused multiply-add floating-point operations ✨ (no x86-only note on this one, that's just how it is)
  • -msse — (x86 only) use SSE for floating-point operations
  • -msse2 — (x86 only) use SSE2 for floating-point operations
  • -msse3 — (x86 only) use SSE3 for floating-point operations
  • -msse4 — (x86 only) use SSE4 for floating-point operations
  • -msse4.2 — (x86 only) use SSE4.2 for floating-point operations

🧚 Compiler plugins 🧚

the plugin girlies are so real for this one 🫶

  • -fclear-plugins — clear the list of active plugins, poof 🪄
  • -fplugin-library=⟨file-path⟩;⟨unit-id⟩;⟨module⟩;⟨args⟩ — load a pre-compiled static plugin from an external library
  • -fplugin-opt=⟨module⟩:⟨args⟩ — give arguments to a plugin module; the module must be specified with -fplugin=⟨module⟩
  • -fplugin-trustworthy — trust the used plugins and no longer mark the compiled module as unsafe 😌
  • -fplugin=⟨module⟩ — load a plugin exported by a given module
  • -hide-all-plugin-packages — hide all packages for plugins by default
  • -plugin-package ⟨pkg⟩ — expose ⟨pkg⟩ for plugins
  • -plugin-package-id ⟨pkg-id⟩ — expose ⟨pkg-id⟩ for plugins

💜 Profiling 💜

the "why is my program slow" section, aka main character energy for performance girlies 🔥

  • -auto — (deprecated 👴) alias for -fprof-auto-exported
  • -auto-all — (deprecated 👴) alias for -fprof-auto
  • -caf-all — (deprecated 👴) alias for -fprof-cafs
  • -fno-prof-count-entries — do not collect entry counts
  • -fprof-auto — auto-add SCCs to all bindings not marked INLINE
  • -fprof-auto-calls — auto-add SCCs to all call sites
  • -fprof-auto-exported — auto-add SCCs to all exported bindings not marked INLINE
  • -fprof-auto-top — auto-add SCCs to all top-level bindings not marked INLINE
  • -fprof-cafs — auto-add SCCs to all CAFs
  • -fprof-callers=⟨name⟩ — auto-add SCCs to all call-sites of the named function
  • -fprof-late — auto-add SCCs to all top level bindings after the core pipeline has run
  • -fprof-late-inline — auto-add SCCs to all top level bindings after the optimizer has run and retain them when inlining
  • -fprof-late-overloaded — auto-add SCCs to all top level overloaded bindings after the core pipeline has run
  • -fprof-late-overloaded-calls — auto-add SCCs to all call sites that include dictionary arguments after the core pipeline has run
  • -fprof-manual — process manual SCC annotations
  • -no-auto — (deprecated 👴) alias for -fno-prof-auto
  • -no-auto-all — (deprecated 👴) alias for -fno-prof-auto
  • -no-caf-all — (deprecated 👴) alias for -fno-prof-cafs
  • -prof — turn on profiling 📈
  • -ticky — turn on ticky-ticky profiling
  • -ticky-allocd — track the number of times each closure type is allocated
  • -ticky-ap-thunk — don't use standard AP thunks on order to get more reliable entry counters (yes, "on order" — that's the manpage's own typo, I'm just the messenger 🙈)
  • -ticky-dyn-thunk — track allocations of dynamic thunks
  • -ticky-LNE — treat join point binders similar to thunks/functions
  • -ticky-tag-checks — emit dummy ticky counters to record how many tag-inference checks tag inference avoided

⭐ Program coverage ⭐

  • -fhpc — turn on Haskell program coverage instrumentation ✨
  • -hpcdir⟨dir⟩ — set the directory where GHC places .mix files (no space before ⟨dir⟩, that's exactly how it's written 💅)

🎀 Recompilation checking 🎀

the art of not rebuilding the entire world every time you sneeze 🌍

  • -exclude-module=⟨file⟩ — regard ⟨file⟩ as "stable"; i.e., exclude it from having dependencies on it
  • -fforce-recomp — turn off recompilation checking. this is implied by any -ddump-X option when compiling a single file (i.e. when using -c)
  • -fignore-hpc-changes — do not recompile modules just to match changes to HPC flags. this is especially useful for avoiding recompilation when using GHCi, and is enabled by default for GHCi 😌
  • -fignore-optim-changes — do not recompile modules just to match changes to optimisation flags. this is especially useful for avoiding recompilation when using GHCi, and is enabled by default for GHCi
  • -include-cpp-deps — include preprocessor dependencies
  • -include-pkg-deps — regard modules imported from packages as unstable

🍓 Redirecting output 🍓

you're the director now bestie, you pick where the files go 🎬

  • -dep-makefile ⟨file⟩ — use ⟨file⟩ as the makefile
  • -dep-suffix ⟨suffix⟩ — make dependencies that declare that files with suffix .⟨suf⟩⟨osuf⟩ depend on interface files with suffix .⟨suf⟩hi
  • -dumpdir ⟨dir⟩ — redirect dump files
  • -dynhisuf ⟨suffix⟩ — set the suffix to use for dynamic interface files
  • -dyno ⟨file⟩ — set dynamic output filename
  • -dynohi ⟨file⟩ — set the filename in which to put the dynamic interface
  • -dynosuf ⟨suffix⟩ — set the dynamic output file suffix
  • -hcsuf ⟨suffix⟩ — set the suffix to use for intermediate C files
  • -hidir ⟨dir⟩ — set directory for interface files
  • -hiedir ⟨dir⟩ — set directory for extended interface files
  • -hiesuf ⟨suffix⟩ — set the suffix to use for extended interface files
  • -hisuf ⟨suffix⟩ — set the suffix to use for interface files
  • -o ⟨file⟩ — set output filename
  • -odir ⟨dir⟩ — set directory for object files
  • -ohi ⟨file⟩ — set the filename in which to put the interface
  • -osuf ⟨suffix⟩ — set the output file suffix
  • -outputdir ⟨dir⟩ — set output directory
  • -stubdir ⟨dir⟩ — redirect FFI stub files

🧹 Temporary files 🧹

  • -tmpdir ⟨dir⟩ — set the directory for temporary files

💀 Verbosity options 💀

how much GHC talks to you. the diagnostics girlies live here 🙈

  • -fabstract-refinement-hole-fits — default: off. toggles whether refinements where one or more of the holes are abstract are reported
  • -fdefer-diagnostics — defer and group diagnostic messages by severity
  • -fdiagnostics-as-json — output diagnostics in Json format specified by JSON schema
  • -fdiagnostics-color=⟨always|auto|never⟩ — use colors in error messages 🌈
  • -fdiagnostics-show-caret — whether to show snippets of original source code
  • -ferror-spans — output full span in error messages
  • -fhide-source-paths — hide module source and object paths
  • -fkeep-going — continue compilation as far as possible on errors 🫡
  • -fmax-refinement-hole-fits=⟨n⟩ — default: 6. set the maximum number of refinement hole fits for typed holes to display in type error messages
  • -fmax-relevant-binds=⟨n⟩ — default: 6. set the maximum number of bindings to display in type error messages
  • -fmax-valid-hole-fits=⟨n⟩ — default: 6. set the maximum number of valid hole fits for typed holes to display in type error messages
  • -fno-show-valid-hole-fits — disables showing a list of valid hole fits for typed holes in type error messages
  • -fno-sort-valid-hole-fits — turns off the sorting of the list of valid hole fits for typed holes in type error messages 💅 like, the suggestions still show up, they're just not ranked for you anymore
  • -fprint-axiom-incomps — shows you the equation incompatibilities in closed type families ✨ messy family drama, but make it type-level
  • -fprint-equality-relations — distinguishes between equality relations when printing 🎀 so you can actually tell which equality is which (iykyk)
  • -fprint-error-index-links=⟨always|auto|never⟩ — decides whether your diagnostic codes get emitted as ANSI hyperlinks to the Haskell Error Index 🔗 like, do you want the cute clickable link or not
  • -fprint-expanded-synonyms — in type errors, also prints type-synonym-expanded types 🌸 because sometimes the synonym is hiding the real tea
  • -fprint-explicit-coercions — prints coercions in types 💅 no more mystery coercion erasure, we're showing everything
  • -fprint-explicit-foralls — prints explicit forall quantification in types ✨ see also ExplicitForAll
  • -fprint-explicit-kinds — prints explicit kind foralls and kind arguments in types 👑 see also KindSignatures
  • -fprint-explicit-runtime-reps — prints RuntimeRep and Levity variables in types which are runtime-representation polymorphic 🌀 the full lore, no cap
  • -fprint-potential-instances — displays all available instances in type error messages 🫶 it's giving "here are literally all your options, bestie"
  • -fprint-redundant-promotion-ticks — prints redundant DataKinds promotion ticks 🎀 the ticks that didn't need to be there, exposed
  • -fprint-typechecker-elaboration — prints extra information from typechecker 🔍 the behind-the-scenes commentary track
  • -fprint-unicode-syntax — uses unicode syntax when printing expressions, types and kinds 🌈 see also UnicodeSyntax
  • -frefinement-level-hole-fits=⟨n⟩ — default: off. Sets the level of refinement of the refinement hole fits, where level n means that hole fits of up to n holes will be considered 🦋 so dial in how adventurous the suggestions get
  • -freverse-errors — outputs errors in reverse order 🙈 chronological order is cancelled, apparently
  • -fshow-docs-of-hole-fits — toggles whether to show the documentation of the valid hole fits in the output 📚 educational slay
  • -fshow-error-context — whether to show textual information about error context 🧐 the where and why, not just the what
  • -fshow-hole-constraints — shows constraints when reporting typed holes ✨ the fine print, included
  • -fshow-hole-matches-of-hole-fits — toggles whether to show the type of the additional holes in refinement hole fits 💅 more info about the extra holes
  • -fshow-provenance-of-hole-fits — toggles whether to show the provenance of the valid hole fits in the output 🔎 where each suggestion came from
  • -fshow-type-app-of-hole-fits — toggles whether to show the type application of the valid hole fits in the output 🎀
  • -fshow-type-app-vars-of-hole-fits — toggles whether to show what type each quantified variable takes in a valid hole fit 🦋
  • -fshow-type-of-hole-fits — toggles whether to show the type of the valid hole fits in the output 👑
  • -fsort-by-size-hole-fits — sorts valid hole fits by size 📏 lil suggestions first, big chonky ones later
  • -fsort-by-subsumption-hole-fits — sorts valid hole fits by subsumption 🌀
  • -funclutter-valid-hole-fits — unclutters the list of valid hole fits by not showing provenance nor type applications of suggestions ✨ minimal aesthetic, less noise
  • -Rghc-timing — summarises timing stats for GHC (same as +RTS -tstderr) ⏱️ receipts on where the time went
  • -v — verbose mode (equivalent to -v3) 💬
  • -v⟨n⟩ — sets verbosity level 🔊 pick your level of yapping

✨ Warnings ✨

  • -fenable-th-splice-warnings — generates warnings for Template Haskell splices 🔮 TH but it warns you now
  • -fhelpful-errors — makes suggestions for mis-spelled names 💖 it's giving "did you mean…?" and honestly, we love her
  • -fmax-pmcheck-models=⟨n⟩ — soft limit on the number of parallel models the pattern match checker should check a pattern match clause against 🧠 a soft limit, so don't stress
  • -fshow-warning-groups — shows which group an emitted warning belongs to 🏷️
  • -fvia-C — uses the C code generator 💀 old-school route
  • -W — enables normal warnings ✅
  • -w — disables all warnings 🤫 silence, but at what cost
  • -Wall — enables almost all warnings (details in Warnings and sanity-checking) 🌈 the "I want to know everything" button
  • -Wall-missed-specialisations — warns when specialisation of any overloaded function fails 😭
  • -Wall-missed-specializations — alias for -Wall-missed-specialisations 🪞 same thing, different spelling
  • -Wambiguous-fields — warns about ambiguous field selectors or updates 🌀
  • -Wauto-orphans — (deprecated) Does nothing 💀 literally nothing, she's retired
  • -Wbadly-staged-types — warns when a type binding is used at the wrong TH stage 🎭 wrong stage, wrong vibe
  • -Wcompat — enables future compatibility warnings (details in Warnings and sanity-checking) 🔮 future-proofing, bestie
  • -Wcompat-unqualified-imports — (deprecated) reports unqualified imports of core libraries which are expected to cause compatibility problems in future releases ⚠️
  • -Wcpp-undef — warns on uses of the #if directive on undefined identifiers 🧵
  • -Wdata-kinds-tc — warns when an illegal use of a type or kind without DataKinds is caught by the typechecker 🚨
  • -Wdefault — enables default flags 🎀
  • -Wdefaulted-exception-context — warns when a Control.Exception.Context.ExceptionContext implicit parameter is defaulted to Control.Exception.Context.emptyExceptionContext 🫠 it got defaulted, and we're telling you
  • -Wdeferred-out-of-scope-variables — reports warnings when variable out-of-scope errors are deferred until runtime 😬 see -fdefer-out-of-scope-variables
  • -Wdeferred-type-errors — reports warnings when deferred type errors are enabled. This option is enabled by default. See -fdefer-type-errors ✨
  • -Wdeprecated-flags — warns about uses of commandline flags that are deprecated 👵
  • -Wdeprecated-type-abstractions — warns when type abstractions in constructor patterns are used without enabling TypeApplications 💅
  • -Wdeprecations — warns about uses of functions & types that have DEPRECATED pragmas, or WARNING pragmas with the deprecated category ⚠️
  • -Wderiving-defaults — warns about default deriving when using both DeriveAnyClass and GeneralizedNewtypeDeriving 😵‍💫 yes the conflict is real
  • -Wderiving-typeable — warns when Typeable is derived 🌀
  • -Wdodgy-exports — warns about dodgy exports 🚩
  • -Wdodgy-foreign-imports — warns about dodgy foreign imports 🚩
  • -Wdodgy-imports — warns about dodgy imports 🚩
  • -Wduplicate-constraints — warns when a constraint appears duplicated in a type signature 👯
  • -Wduplicate-exports — warns when an entity is exported multiple times 🔁
  • -Wempty-enumerations — warns about enumerations that are empty 🫙
  • -Werror — makes warnings fatal 💀🔪 no cap, your warnings now stop the build
  • -Weverything — enables all warnings supported by GHC 🌈👑 the maximalist option
  • -Wextended-warnings — warns about uses of functions & types that have WARNING or DEPRECATED pragmas, across all categories 📢
  • -Wextra — alias for -W 🪞
  • -Wforall-identifier — (deprecated) Does nothing 💀 retired icon
  • -Wgadt-mono-local-binds — warns when pattern matching on a GADT without MonoLocalBinds 🧩
  • -Whi-shadowing — (deprecated) warns when a .hi file in the current directory shadows a library 👻
  • -Widentities — warns about uses of Prelude numeric conversions that are probably the identity (and hence could be omitted) 🪞✨
  • -Wimplicit-kind-vars — (deprecated) warns when kind variables are implicitly quantified over 🌀
  • -Wimplicit-lift — warns about implicit lift in Template Haskell quotes 🔮
  • -Wimplicit-prelude — warns when the Prelude is implicitly imported 📦
  • -Wimplicit-rhs-quantification — warns when type variables on the RHS of a type synonym are implicitly quantified 🤫
  • -Winaccessible-code — warns about inaccessible code 🚪
  • -Wincomplete-export-warnings — warns when some but not all of exports for a name are warned about 🧮
  • -Wincomplete-patterns — warns when a pattern match could fail 😬 the classic
  • -Wincomplete-record-selectors — warns when a record selector application could fail 🎯
  • -Wincomplete-record-updates — warns when a record update could fail 🎯
  • -Wincomplete-uni-patterns — warns when a pattern match in a lambda expression, pattern binding or a lazy pattern could fail 🌪️
  • -Winconsistent-flags — warns when command line options are inconsistent in some way 🚩 bestie, pick a lane
  • -Winferred-safe-imports — warns when an explicitly Safe Haskell module imports a Safe-Inferred one 🛡️
  • -Winline-rule-shadowing — warns if a rewrite RULE might fail to fire because the function might be inlined before the rule has a chance to fire 🔥 see How rules interact with INLINE/NOINLINE pragmas
  • -Winvalid-haddock — warns when a Haddock comment occurs in an invalid position 📝
  • -Wloopy-superclass-solve — (deprecated) warns when creating potentially-loopy superclass constraint evidence 🌀
  • -Wmisplaced-pragmas — warns about uses of file header pragmas in the module body 🏷️
  • -Wmissed-extra-shared-lib — warns when GHCi can't load a shared lib 😭
  • -Wmissed-specialisations — warns when specialisation of an imported, overloaded function fails 💔
  • -Wmissed-specializations — alias for -Wmissed-specialisations 🪞
  • -Wmissing-deriving-strategies — warns when deriving without mentioning a deriving strategy 🎀
  • -Wmissing-export-lists — warns when a module declaration does not explicitly list all exports 📋
  • -Wmissing-exported-pattern-synonym-signatures — warns about pattern synonyms without signatures, only if they are exported 📤
  • -Wmissing-exported-signatures — warns about top-level functions without signatures, only if they are exported 📤
  • -Wmissing-exported-sigs — (deprecated) warns about top-level functions without signatures, only if they are exported. takes precedence over -Wmissing-signatures 👑
  • -Wmissing-fields — warns when fields of a record are uninitialised 🕳️
  • -Wmissing-home-modules — warns when encountering a home module imported, but not listed on the command line. Useful for cabal to ensure GHC won't pick up modules, not listed neither in exposed-modules, nor in other-modules 📦
  • -Wmissing-import-lists — warns when an import declaration does not explicitly list all the names brought into scope 📋
  • -Wmissing-kind-signatures — warns when type declarations don't have kind signatures nor CUSKs 🧬
  • -Wmissing-local-signatures — warns about polymorphic local bindings without signatures 🪧
  • -Wmissing-local-sigs — (deprecated) warns about polymorphic local bindings without signatures 🪧
  • -Wmissing-methods — warns when class methods are undefined 🫥
  • -Wmissing-monadfail-instances — (deprecated) warns when a failable pattern is used in a do-block that does not have a MonadFail instance 💀
  • -Wmissing-pattern-synonym-signatures — warns when pattern synonyms do not have type signatures ✍️
  • -Wmissing-poly-kind-signatures — warns when an inferred polykinded type or class declaration doesn't have kind signatures nor CUSKs. give those kinds a home bestie 😭
  • -Wmissing-role-annotations — warns when type declarations don't have role annotations. roles matter, we love a well-defined role 💅
  • -Wmissing-safe-haskell-mode — warns when the Safe Haskell mode is not explicitly specified. say it with your chest ✨
  • -Wmissing-signatures — warns about top-level functions without signatures. like what even are you, girl 🫶
  • -Wmissing-space-after-bang — (deprecated) literally does nothing. a ghost. a vibe with no substance 👻
  • -Wmonomorphism-restriction — warns when the Monomorphism Restriction is applied.
  • -Wname-shadowing — warns when names are shadowed. not the shadowing 😭
  • -Wnoncanonical-monad-instances — warns when Applicative or Monad instances have noncanonical definitions of return, pure, (>>), or (*>). See flag description in Warnings and sanity-checking for more details. 🔥
  • -Wnoncanonical-monadfail-instances — (deprecated) warns when Monad or MonadFail instances have noncanonical definitions of fail.
  • -Wnoncanonical-monoid-instances — warns when Semigroup or Monoid instances have noncanonical definitions of (<>) or mappend. See flag description in Warnings and sanity-checking for more details. 🎀
  • -Wnot — (deprecated) Alias for -w. that's it, that's the whole thing 💀
  • -Woperator-whitespace — warns on prefix, suffix, and tight infix uses of infix operators. spacing is a love language fr fr
  • -Woperator-whitespace-ext-conflict — warns on uses of infix operators that would be parsed differently were a particular GHC extension enabled. sneaky parse-flip energy, we're watching 👀
  • -Worphans — warns when the module contains orphan instance declarations or rewrite rules. no parents? we're judging (lovingly) 🧚
  • -Woverflowed-literals — warns about literals that will overflow their type. too much for that type to hold, honestly relatable 😭
  • -Woverlapping-patterns — warns about overlapping patterns.
  • -Wpartial-fields — warns when defining a partial record field.
  • -Wpartial-type-signatures — warns about holes in partial type signatures when PartialTypeSignatures is enabled. Not applicable when PartialTypeSignatures is not enabled, in which case errors are generated for such holes. so like — either a warning or a full-on error, pick your fighter 💅
  • -Wprepositive-qualified-module — Report imports with a leading/prepositive "qualified".
  • -Wredundant-bang-patterns — Warns about redundant bang patterns. ! but make it unnecessary 🫠
  • -Wredundant-constraints — Have the compiler warn about redundant constraints in type signatures.
  • -Wredundant-record-wildcards — Warns about record wildcard matches when the wildcard binds no patterns. wildcard that does nothing? embarrassing for it 🎀
  • -Wredundant-strictness-flags — Warns about redundant strictness flags.
  • -Wsafe — warn if the module being compiled is regarded to be safe. goody-two-shoes module alert 🫶
  • -Wsemigroup — (deprecated) Warns when a Monoid is not Semigroup, and on non-Semigroup definitions of (<>)" — iykyk, it's giving legacy flag energy
  • -Wsimplifiable-class-constraints — Warns about class constraints in a type signature that can be simplified using a top-level instance declaration. bestie that constraint is whole extra, pls simplify ✨
  • -Wstar-binder — warns about binding the (*) type operator despite StarIsType. tricky tricky ⭐
  • -Wstar-is-type — warns when * is used to mean Data.Kind.Type. stars in their type era 🌟
  • -Wtabs — warn if there are tabs in the source file. tabs vs spaces discourse, but make it a compiler warning 💀
  • -Wterm-variable-capture — warns when an implicitly quantified type variable captures a term's name. the way it just takes the name 😭
  • -Wtrustworthy-safe — warn if the module being compiled is marked as Trustworthy but it could instead be marked as Safe, a more informative bound. glow-up suggestion 🦋
  • -Wtype-defaults — warns when defaulting happens.
  • -Wtype-equality-out-of-scope — warns when type equality a ~ b is used despite being out of scope.
  • -Wtype-equality-requires-operators — warns when type equality a ~ b is used despite being out of scope. yes it's the same sentence as the one above, no we're not editing the manpage, we simply report 🫡
  • -Wtyped-holes — Report warnings when typed hole errors are deferred until runtime. See -fdefer-typed-holes. holes at runtime, living dangerously 🙈
  • -Wunbanged-strict-patterns — warns on pattern bind of unlifted variable that is neither bare nor banged. neither bare nor banged, the worst of both worlds 😔
  • -Wunicode-bidirectional-format-characters — warns about the usage of unicode bidirectional layout override characters. sneaky text-invisible characters, we see u 👀
  • -Wunrecognised-pragmas — warns about uses of pragmas that GHC doesn't recognise. {-# ??? #-} bestie no 😭
  • -Wunrecognised-warning-flags — throws a warning when an unrecognised -W... flag is encountered on the command line. yes, it warns you about your warnings. iconic recursive behaviour tbh 👑
  • -Wunsafe — warn if the module being compiled is regarded to be unsafe. See Safe Haskell. bad-boy module detected 💀
  • -Wunsupported-calling-conventions — warns about use of an unsupported calling convention.
  • -Wunsupported-llvm-version — Warns when using -fllvm with an unsupported version of LLVM.
  • -Wunticked-promoted-constructors — warns if promoted constructors are not ticked. give that constructor its lil ' tick ✨
  • -Wunused-binds — warns about bindings that are unused. Alias for -Wunused-top-binds, -Wunused-local-binds and -Wunused-pattern-binds. a three-for-one, we love efficiency 🎀
  • -Wunused-do-bind — warns about do bindings that appear to throw away values of types other than (). girl you dropped that value 😭
  • -Wunused-foralls — warns about type variables in user-written foralls that are unused. all those quantifiers and for what 🙈
  • -Wunused-imports — warns about unnecessary imports. clean it up bestie 🧹
  • -Wunused-local-binds — warns about local bindings that are unused.
  • -Wunused-matches — warns about variables in patterns that aren't used.
  • -Wunused-packages — warns when package is requested on command line, but not needed. you asked for it and didn't even use it 💀
  • -Wunused-pattern-binds — warns about pattern match bindings that are unused.
  • -Wunused-record-wildcards — Warns about record wildcard matches when none of the bound variables are used.
  • -Wunused-top-binds — warns about top-level bindings that are unused.
  • -Wunused-type-patterns — warns about unused type variables which arise from patterns in in type family and data family instances. (that double "in in" is theirs, not ours, we keep the receipts 🧾)
  • -Wview-pattern-signatures — warns when a view pattern is used with type signature without explicit parens. parens are load-bearing, wrap it up 🎁
  • -Wwarn — make warnings non-fatal. they're just little guys, let 'em live 🫶
  • -Wwarnings-deprecations — warns about uses of functions & types that have DEPRECATED pragmas, or WARNING pragmas with the deprecated category. Alias for -Wdeprecations.
  • -Wwrong-do-bind — warns about do bindings that appear to throw away monadic values that you should have bound instead. bestie you were supposed to keep that 😭
  • -Wx-⟨category⟩ — warns about uses of functions & types that have WARNING pragmas with the given category. custom categories, custom chaos 💅

Copyright 2015. The University Court of the University of Glasgow. All rights reserved.

🌈 SEE ALSO 🌈

💖 AUTHOR 💖

The GHC Team

2026, GHC Team


and that's the whole page, bestie — no cap, you read all of it 💅✨ this manual is version 9.12.4, dated Mar 28, 2026, straight from the GHC Team, and honestly? she ate. go compile something iconic now 🔥🦋🍓

📦 where this page comes from