GHC(1)
🌈 GHC(1) — the Glasgow Haskell Compiler 🌈
🎀 NAME 🎀
ghc — the Glasgow Haskell Compiler. This is the manual page for GHC(1), bestie.
💫 SYNOPSIS 💫
ghc [option|filename]
ghci [option|filename]
✨ DESCRIPTION ✨
Okay so this manual page gives you the quick tea on the ghc and ghci commands. Important heads-up: ghci is not yet available on all architectures. There is extensive documentation in various other formats, including PDF at <https://downloads.haskell.org/ghc/latest/docs/users_guide.pdf> and HTML at <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.
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-linkedp— built with profiling
.⟨way⟩_hi— interface files for "way" ⟨way⟩; common ways are:
💅 OPTIONS 💅
Okay bestie, the original page now starts dumping the option groups. It does not give a one-liner for each flag in these groups, so I am not inventing behavior — just listing every flag in the exact order and grouping from the page. Duplicates stay duplicated, periodt.
💻 Code generation 💻
-dynamic-too-fasm-fllvm-fbyte-code-fexpose-internal-symbols-fexternal-dynamic-refs-fllvm-fasm-fno-code-fobject-code-fPIC-fPIE-fwrite-interface-split-objs
🐛 Debugging the compiler 🐛
-dasm-lint-dcmm-lint-dcore-lint-ddump-asm-ddump-asm-expanded-ddump-asm-liveness-ddump-asm-native-ddump-asm-regalloc-ddump-asm-regalloc-stages-ddump-asm-stats-ddump-bcos-ddump-c-backend-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-verbose-ddump-cmm-verbose-by-proc-ddump-core-stats-ddump-cpr-signatures-ddump-cpranal-ddump-cse-ddump-deriv-ddump-ds-ddump-ds-preopt-ddump-ec-trace-ddump-faststrings-ddump-file-prefix=⟨str⟩-ddump-foreign-ddump-hie-ddump-hpc-ddump-if-trace-ddump-inlinings-ddump-json-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-spec-ddump-splices-ddump-stg-ddump-stg-final-ddump-stg-from-core-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-worker-wrapper-dfaststring-stats-dhex-word-literals-dinitial-unique=⟨s⟩-dinline-check=⟨str⟩-dlinear-core-lint-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-coercions-dsuppress-idinfo-dsuppress-module-prefixes-dsuppress-stg-free-vars-dsuppress-ticks-dsuppress-timestamps-dsuppress-type-applications-dsuppress-type-signatures-dsuppress-unfoldings-dsuppress-uniques-dsuppress-var-kinds-dth-dec-file-dunique-increment=⟨i⟩-dverbose-core2core-dverbose-stg2stg-falignment-sanitisation-fcatch-bottoms-fcheck-prim-bounds-fdistinct-constructor-tables-finfo-table-map-fllvm-fill-undef-with-garbage-fproc-alignment-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-fghci-hist-size=⟨n⟩-fghci-leak-check-fno-ghci-leak-check-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 🗣️
-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-XFieldSelectors-XFlexibleContexts-XFlexibleInstances-XForeignFunctionInterface-XFunctionalDependencies-XGADTs-XGADTSyntax-XGeneralisedNewtypeDeriving-XGeneralizedNewtypeDeriving-XGHC2021-XGHCForeignImportPrim-XHaskell2010-XHaskell98-XHexFloatLiterals-XImplicitParams-XImportQualifiedPost-XImpredicativeTypes-XIncoherentInstances-XInstanceSigs-XInterruptibleFFI-XKindSignatures-XLambdaCase-XLexicalNegation-XLiberalTypeSynonyms-XLinearTypes-XMagicHash-XMonadComprehensions-XMonoLocalBinds-XMultiParamTypeClasses-XMultiWayIf-XNamedFieldPuns-XNamedWildCards-XNegativeLiterals-XNoImplicitPrelude-XNoMonomorphismRestriction-XNondecreasingIndentation-XNoPatternGuards-XNoTraditionalRecordSyntax-XNPlusKPatterns-XNullaryTypeClasses-XNumDecimals-XNumericUnderscores-XOverlappingInstances-XOverloadedLabels-XOverloadedLists-XOverloadedRecordDot-XOverloadedRecordUpdate-XOverloadedStrings-XPackageImports-XParallelListComp-XPartialTypeSignatures-XPatternSynonyms-XPolyKinds-XPostfixOperators-XQualifiedDo-XQuantifiedConstraints-XQuasiQuotes-XRank2Types-XRankNTypes-XRebindableSyntax-XRecordWildCards-XRecursiveDo-XRoleAnnotations-XSafe-XScopedTypeVariables-XStandaloneDeriving-XStandaloneKindSignatures-XStarIsType-XStaticPointers-XStrict-XStrictData-XTemplateHaskell-XTemplateHaskellQuotes-XTransformListComp-XTrustworthy-XTupleSections-XTypeApplications-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⟩-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-split-sections-static-staticlib-threaded-with-rtsopts=⟨opts⟩
🎲 Miscellaneous options 🎲
-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⟩-j[⟨n⟩]
🚀 Modes of operation 🚀
--frontend ⟨module⟩--help-?--info--interactive--make--mk-dll--numeric-version--print-booter-version--print-build-platform--print-c-compiler-flags--print-c-compiler-link-flags--print-debug-on--print-global-package-db--print-have-interpreter--print-have-native-code-generator--print-host-platform--print-ld-flags--print-leading-underscore--print-libdir--print-object-splitting-supported--print-project-git-commit-id--print-project-version--print-rts-ways--print-stage--print-support-smp--print-tables-next-to-code--print-target-platform--print-unregisterised--run ⟨file⟩--show-iface ⟨file⟩--show-options--supported-extensions--supported-languages--version-V-e ⟨expr⟩-M
✨ Individual optimizations ✨
okay bestie, breathe. this is the big one. this is the "my entire personality is compiler flags" list. every single one is here, in order, no skips, no shortcuts (ironic given the first flag). some of them come as a matched set with their -fno- buddy, some are lone wolves, and all of them are exactly as written. 💅
-fasm-shortcutting,-fno-asm-shortcutting-fbinary-blob-threshold=⟨n⟩-fblock-layout-cfg,-fno-block-layout-cfg-fblock-layout-weightless,-fno-block-layout-weightless-fblock-layout-weights-fcall-arity,-fno-call-arity-fcase-folding,-fno-case-folding-fcase-merge,-fno-case-merge-fcmm-elim-common-blocks,-fno-cmm-elim-common-blocks-fcmm-sink,-fno-cmm-sink-fcmm-static-pred,-fno-cmm-static-pred-fcpr-anal,-fno-cpr-anal-fcross-module-specialise,-fno-cross-module-specialise-fcse,-fno-cse-fdicts-cheap,-fno-dicts-cheap-fdicts-strict,-fno-dicts-strict-fdmd-tx-dict-sel,-fno-dmd-tx-dict-sel-fdo-eta-reduction,-fno-do-eta-reduction-fdo-lambda-eta-expansion,-fno-do-lambda-eta-expansion-feager-blackholing-fenable-rewrite-rules,-fno-enable-rewrite-rules-fexcess-precision,-fno-excess-precision-fexitification,-fno-exitification-fexpose-all-unfoldings,-fno-expose-all-unfoldings-ffloat-in,-fno-float-in-ffull-laziness,-fno-full-laziness-ffun-to-thunk,-fno-fun-to-thunk-fignore-asserts,-fno-ignore-asserts-fignore-interface-pragmas,-fno-ignore-interface-pragmas-finline-generics,-fno-inline-generics-finline-generics-aggressively,-fno-inline-generics-aggressively-flate-dmd-anal,-fno-late-dmd-anal-flate-specialise,-fno-late-specialise-fliberate-case,-fno-liberate-case-fliberate-case-threshold=⟨n⟩,-fno-liberate-case-threshold-fllvm-pass-vectors-in-regs-floopification,-fno-loopification-fmax-inline-alloc-size=⟨n⟩-fmax-inline-memcpy-insns=⟨n⟩-fmax-inline-memset-insns=⟨n⟩-fmax-simplifier-iterations=⟨n⟩-fmax-uncovered-patterns=⟨n⟩-fmax-worker-args=⟨n⟩-fno-opt-coercion-fno-pre-inlining-fno-state-hack-fomit-interface-pragmas,-fno-omit-interface-pragmas-fomit-yields,-fno-omit-yields-foptimal-applicative-do,-fno-optimal-applicative-do-fpedantic-bottoms,-fno-pedantic-bottoms-fregs-graph,-fno-regs-graph-fregs-iterative,-fno-regs-iterative-fsimpl-tick-factor=⟨n⟩-fsimplifier-phases=⟨n⟩-fsolve-constant-dicts,-fno-solve-constant-dicts-fspec-constr,-fno-spec-constr-fspec-constr-count=⟨n⟩,-fno-spec-constr-count-fspec-constr-keen,-fno-spec-constr-keen-fspec-constr-threshold=⟨n⟩,-fno-spec-constr-threshold-fspecialise,-fno-specialise-fspecialise-aggressively,-fno-specialise-aggressively-fstatic-argument-transformation,-fno-static-argument-transformation-fstg-cse,-fno-stg-cse-fstg-lift-lams,-fno-stg-lift-lams-fstg-lift-lams-known,-fno-stg-lift-lams-known-fstg-lift-lams-non-rec-args-fstg-lift-lams-non-rec-args-any-fstg-lift-lams-rec-args-fstg-lift-lams-rec-args-any-fstrictness,-fno-strictness-fstrictness-before=⟨n⟩-funbox-small-strict-fields,-fno-unbox-small-strict-fields-funbox-strict-fields,-fno-unbox-strict-fields-funfolding-case-scaling=⟨n⟩-funfolding-case-threshold=⟨n⟩-funfolding-creation-threshold=⟨n⟩-funfolding-dict-discount=⟨n⟩-funfolding-fun-discount=⟨n⟩-funfolding-keeness-factor=⟨n⟩-funfolding-use-threshold=⟨n⟩-fworker-wrapper
no cap, -funfolding-keeness-factor really is spelled like that in the flag. it's giving "the typo is load-bearing". don't @ me, just copy it exactly. 🫶
🌈 Optimization levels 🌈
the vibes-based knobs, literally just these, exactly in this order, duplicates and all:
-O, -O1, -O0, -O0, -O2, -O0, -O⟨n⟩, -O0
🎀 Package options 🎀
package management era. every flag, untouched:
-clear-package-db-distrust ⟨pkg⟩-distrust-all-packages-fpackage-trust-global-package-db-hide-all-packages-hide-package ⟨pkg⟩-ignore-package ⟨pkg⟩-no-auto-link-packages-no-global-package-db-no-user-package-db-package ⟨pkg⟩-package-db ⟨file⟩-package-env ⟨file⟩|⟨name⟩-package-id ⟨unit-id⟩-this-unit-id ⟨unit-id⟩-trust ⟨pkg⟩-user-package-db
🦋 Phases of compilation 🦋
the whole pipeline in six little flags, bestie:
-C-c-E-F-S-x ⟨suffix⟩
🔥 Overriding external programs 🔥
you get to swap out the external programs. every -pgm one, in order:
-pgma ⟨cmd⟩-pgmc ⟨cmd⟩-pgmdll ⟨cmd⟩-pgmF ⟨cmd⟩-pgmi ⟨cmd⟩-pgminstall_name_tool ⟨cmd⟩-pgmL ⟨cmd⟩-pgml ⟨cmd⟩-pgmlc ⟨cmd⟩-pgmlibtool ⟨cmd⟩-pgmlm ⟨cmd⟩-pgmlo ⟨cmd⟩-pgmotool ⟨cmd⟩-pgmP ⟨cmd⟩-pgms ⟨cmd⟩-pgmwindres ⟨cmd⟩
heads up:-pgmLand-pgmlare not the same flag. case matters, bestie.-pgmlc,-pgmlm,-pgmlo— all lowercase after them. look twice, type once. 💀
💜 Phase-specific options 💜
passing stuff straight through to a phase, iconically:
-opta ⟨option⟩-optc ⟨option⟩-optcxx ⟨option⟩-optdll ⟨option⟩-optF ⟨option⟩-opti ⟨option⟩-optL ⟨option⟩-optl ⟨option⟩-optlc ⟨option⟩-optlm ⟨option⟩-optlo ⟨option⟩-optP ⟨option⟩-optwindres ⟨option⟩-pgmc-supports-no-pie
🌸 Platform-specific options 🌸
the CPU-feature girlies. all of them, verbatim:
-mavx-mavx2-mavx512cd-mavx512er-mavx512f-mavx512pf-mbmi-mbmi2-msse-msse2-msse3-msse4-msse4.2
yes, -msse4.2 has a literal dot in it. keep the dot. the dot is iconic. ✨
🧚 Compiler plugins 🧚
plug-in era, we love to see it:
-fclear-plugins-fplugin-opt=⟨module⟩:⟨args⟩-fplugin-trustworthy-fplugin=⟨module⟩-hide-all-plugin-packages-plugin-package ⟨pkg⟩-plugin-package-id ⟨pkg-id⟩
🍓 Profiling 🍓
time to find out where your program is spending its whole life. full list, no edits:
-auto-auto-all-caf-all-fno-prof-count-entries-fprof-count-entries-fprof-auto-fno-prof-auto-fprof-auto-calls-fno-prof-auto-fprof-auto-exported-fno-prof-auto-fprof-auto-top-fno-prof-auto-fprof-cafs-fno-prof-cafs-fprof-callers=⟨name⟩-no-auto-no-auto-all-no-caf-all-prof-ticky-ticky-allocd-ticky-dyn-thunk
real talk: -fno-prof-auto shows up four separate times in this list and that's genuinely how it's written. don't "clean it up", don't dedupe, that's not our job. 🙈
⭐ Program coverage ⭐
one flag. one icon. -fhpc. that's the whole section, and honestly? she ate. 💅
🎀 Recompilation checking 🎀
so you can stop recompiling things that didn't change:
-fforce-recomp,-fno-force-recomp-fignore-hpc-changes,-fno-ignore-hpc-changes-fignore-optim-changes,-fno-ignore-optim-changes
💖 Redirecting output 💖
where does everything go? you decide. whole list, in order:
--exclude-module=⟨file⟩-ddump-mod-cycles-dep-makefile ⟨file⟩-dep-suffix ⟨suffix⟩-dumpdir ⟨dir⟩-dynhisuf ⟨suffix⟩-dyno ⟨file⟩-dynohi ⟨file⟩-dynosuf ⟨suffix⟩-hcsuf ⟨suffix⟩-hidir ⟨dir⟩-hiedir ⟨dir⟩-hiesuf ⟨suffix⟩-hisuf ⟨suffix⟩-include-cpp-deps-include-pkg-deps-o ⟨file⟩-odir ⟨dir⟩-ohi ⟨file⟩-osuf ⟨suffix⟩-outputdir ⟨dir⟩-stubdir ⟨dir⟩
lowkey obsessed with how-o,-ohi,-odir,-hidir,-hiedir,-hcsuf,-hiesuf,-hisuf,-dyno,-dynohi,-dynosufall just exist next to each other. that's a whole keyboard smash and it's valid. 😭
🫶 Temporary files 🫶
just the one, bestie:
-tmpdir ⟨dir⟩
👑 Verbosity options 👑
the "tell me everything, i want the whole tea" section. biggest list in the whole page, and yes, every single flag made it in:
-fabstract-refinement-hole-fits,-fno-abstract-refinement-hole-fits-fdefer-diagnostics-fdiagnostics-color=⟨always|auto|never⟩-fdiagnostics-show-caret,-fno-diagnostics-show-caret-ferror-spans-fhide-source-paths-fkeep-going-fmax-refinement-hole-fits=⟨n⟩,-fno-max-refinement-hole-fits-fmax-relevant-binds=⟨n⟩,-fno-max-relevant-binds-fmax-valid-hole-fits=⟨n⟩,-fno-max-valid-hole-fits-fno-show-valid-hole-fits-fno-sort-valid-hole-fits,-fsort-valid-hole-fits-fprint-axiom-incomps,-fno-print-axiom-incomps-fprint-equality-relations,-fno-print-equality-relations-fprint-expanded-synonyms,-fno-print-expanded-synonyms-fprint-explicit-coercions,-fno-print-explicit-coercions-fprint-explicit-foralls,-fno-print-explicit-foralls-fprint-explicit-kinds,-fno-print-explicit-kinds-fprint-explicit-runtime-reps,-fno-print-explicit-runtime-reps-fprint-potential-instances,-fno-print-potential-instances-fprint-typechecker-elaboration,-fno-print-typechecker-elaboration-fprint-unicode-syntax,-fno-print-unicode-syntax-frefinement-level-hole-fits=⟨n⟩,-fno-refinement-level-hole-fits-freverse-errors,-fno-reverse-errors-fshow-docs-of-hole-fits,-fno-show-docs-of-hole-fits-fshow-hole-constraints-fshow-hole-matches-of-hole-fits,-fno-show-hole-matches-of-hole-fits-fshow-provenance-of-hole-fits,-fno-show-provenance-of-hole-fits-fshow-type-app-of-hole-fits,-fno-show-type-app-of-hole-fits-fshow-type-app-vars-of-hole-fits,-fno-show-type-app-vars-of-hole-fits-fshow-type-of-hole-fits,-fno-show-type-of-hole-fits-fsort-by-size-hole-fits,-fno-sort-by-size-hole-fits-fsort-by-subsumption-hole-fits,-fno-sort-by-subsumption-hole-fits-funclutter-valid-hole-fits-Rghc-timing-v-v⟨n⟩
quick vibe check:-vand-v⟨n⟩are two separate entries at the end there. and-fno-show-valid-hole-fits/-fno-sort-valid-hole-fits/-fsort-valid-hole-fitsare ordered exactly like that — negations first, then the positive. copy it as-is, no reordering. 💅
okay we're not done yet — the page keeps going, so stay with me bestie, next part's right there. 🌈
Warnings ✨
okay bestie, deep breath — this is the big one. Every warning flag GHC knows, in order, nothing skipped, nothing merged. Some show up as a pair, some show up alone, and a couple show up more than once because the source list says so and we don't edit the source list. 💅
-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-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,-w,-w-Wall,-w,-Wall-missed-specialisations-Wno-all-missed-specialisations,-Wall-missed-specializations-Wno-all-missed-specializations-Wambiguous-fields-Wauto-orphans-Wcompat/-Wno-compat-Wcompat-unqualified-imports/-Wno-compat-unqualified-imports-Wcpp-undef-Wdefault-Wdeferred-out-of-scope-variables/-Wno-deferred-out-of-scope-variables-Wdeferred-type-errors/-Wno-deferred-type-errors-Wdeprecated-flags/-Wno-deprecated-flags-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-Wextra-w-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-Winaccessible-code/-Wno-inaccessible-code-Wincomplete-patterns/-Wno-incomplete-patterns-Wincomplete-record-updates/-Wno-incomplete-record-updates-Wincomplete-uni-patterns/-Wno-incomplete-uni-patterns-Winferred-safe-imports/-Wno-inferred-safe-imports-Winline-rule-shadowing/-Wno-inline-rule-shadowing-Winvalid-haddock/-Wno-invalid-haddock-Wmissed-extra-shared-lib/-Wno-missed-extra-shared-lib-Wmissed-specialisations/-Wno-missed-specialisations-Wmissed-specializations/-Wno-missed-specializations
yes bestie, both the-isationsand the-izationsspellings are real, that's not a typo, the manpage lists both 💀
-Wmissing-deriving-strategies/-Wno-missing-deriving-strategies-Wmissing-export-lists/-Wno-missing-export-lists-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-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-Wno-compat/-Wcompat-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-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-Wtrustworthy-safe/-Wno-safe-Wtype-defaults/-Wno-type-defaults-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-monomorphism-restriction-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-Wwarn/-Werror-Wwarnings-deprecations/-Wno-warnings-deprecations-Wwrong-do-bind/-Wno-wrong-do-bind
phew. that's the whole warning alphabet, bestie, and you survived it. 🫶
Code generation 🌈
these are the switches that decide what shape of output the compiler actually makes. pick your fighter:
-dynamic-too— builds dynamic object files as well as static object files while it's compiling. both. at once. multitasking icon 💅-fasm— use the native code generator-fbyte-code— generate byte-code-fexpose-internal-symbols— produce symbols for all functions, including internal functions.-fexternal-dynamic-refs— generate code for linking against dynamic libraries-fllvm— compile using the LLVM code generator-fno-code— omit code generation entirely, bestie, no code for you-fobject-code— generate object code-fPIC— generate position-independent code (where available)-fPIE— generate code for a position-independent executable (where available)-fwrite-interface— always write interface files-split-objs— split generated object files into smaller files
note the "where available" on-fPICand-fPIE— it's not a universal promise, it's a where available situation 🦋
Debugging the compiler 🔥
okay so this whole section is -d-prefixed and it's basically GHC showing you its diary. every stage of the pipeline can dump its little thoughts. also there's a genuinely unhinged number of C-- related dumps and honestly? iconic.
-dasm-lint— ASM pass sanity checking-dcmm-lint—C--pass sanity checking-dcore-lint— turn on internal sanity checking-ddump-asm— dump final assembly-ddump-asm-expanded— dump the result of the synthetic instruction expansion pass.-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-graphregister allocator.-ddump-asm-stats— dump statistics from the register allocator.-ddump-bcos— dump interpreter byte code-ddump-c-backend— dump C code produced by the C (unregisterised) backend.-ddump-cfg-weights— dump the assumed weights of the CFG.-ddump-cmm— dump the finalC--output-ddump-cmm-caf— dump the results of theC--CAF analysis pass.-ddump-cmm-cbe— dump the results of common block elimination-ddump-cmm-cfg— dump the results of theC--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 theC--info table augmentation pass.-ddump-cmm-opt— dump the results ofC--toC--optimising passes-ddump-cmm-proc— dump the results of proc-point analysis-ddump-cmm-procmap— dump the results of theC--proc-point map pass.-ddump-cmm-raw— dump rawC---ddump-cmm-sink— dump the results of theC--sinking pass.-ddump-cmm-sp— dump the results of theC--stack layout pass.-ddump-cmm-split— dump the results of theC--proc-point splitting pass.-ddump-cmm-switch— dump the results of switch lowering passes-ddump-cmm-verbose— write output from mainC--pipeline passes to files-ddump-cmm-verbose-by-proc— show output from mainC--pipeline passes (grouped by proc)-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-cse— dump CSE output-ddump-deriv— dump deriving output-ddump-ds— dump desugarer output.-ddump-ec-trace— trace exhaustiveness checker-ddump-faststrings— dump the whole FastString table when finished-ddump-file-prefix=⟨str⟩— set the prefix of the filenames used for debugging output.-ddump-foreign— dump foreign export stubs-ddump-hie— dump the hie file syntax tree-ddump-hpc— an alias for-ddump-ticked.-ddump-if-trace— trace interface files-ddump-inlinings— dump inlining info-ddump-json— dump error messages as JSON documents-ddump-llvm— dump LLVM intermediate code.-ddump-mod-map— dump the state of the module mapping database.-ddump-occur-anal— dump occurrence analysis output-ddump-opt-cmm— dump the results ofC--toC--optimising passes-ddump-parsed— dump parse tree-ddump-parsed-ast— dump parser output as a syntax tree-ddump-prep— dump prepared core-ddump-rn— dump renamer output-ddump-rn-ast— dump renamer output as a syntax tree-ddump-rn-stats— renamer stats-ddump-rn-trace— trace renamer-ddump-rtti— trace runtime type inference-ddump-rule-firings— dump rule firing info-ddump-rule-rewrites— dump detailed rule firing info-ddump-rules— dump rewrite rules-ddump-simpl— dump final simplifier output-ddump-simpl-iterations— dump output from each simplifier iteration-ddump-simpl-stats— dump simplifier stats-ddump-spec— dump specialiser output-ddump-splices— dump TH spliced expressions, and what they evaluate to
and that's exactly where this chunk of the list runs out, bestie — do not close the tab, there's more coming 👀
-ddump-stg— (deprecated 💀) it's just an alias for-ddump-stg-from-core, bestie. Use the real one.-ddump-stg-final— shows the output of the last STG pass. the grand finale ✨-ddump-stg-from-core— shows you theCoreToStgoutput.-ddump-stg-unarised— shows the unarised STG. yes that's a real word, no I will not be explaining it further 🫶-ddump-str-signatures— dumps top-level demand signatures.-ddump-stranal— dumps the demand analysis output.-ddump-tc— dumps typechecker output.-ddump-tc-ast— dumps typechecker output, but as a syntax tree 🌳-ddump-tc-trace— traces the typechecker. very spy-core 🔍-ddump-ticked— dumps the code instrumented by HPC (Observing Code Coverage).-ddump-timings— dumps per-pass timing and allocation statistics. numbers girlies rise 🎀-ddump-to-file— dumps to files instead of stdout. saving the receipts fr fr.-ddump-types— dumps type signatures.-ddump-worker-wrapper— dumps worker-wrapper output.-dfaststring-stats— shows statistics for fast string usage when finished.-dhex-word-literals— prints values of typeWord#in hexadecimal.-dinitial-unique=⟨s⟩— startUniqSupplyallocation from⟨s⟩.-dinline-check=⟨str⟩— dumps information about inlining decisions.-dlinear-core-lint— turns on internal sanity checking. mentally checking in on itself 💅-dno-debug-output— suppresses unsolicited debugging output. no ✨unwanted✨ notifications.-dno-typeable-binds— don't generate bindings forTypeablemethods.-dppr-case-as-let— prints single-alternative case expressions as strict lets.-dppr-cols=⟨n⟩— sets the width of debugging output. like, for example-dppr-cols200.-dppr-debug— turns on debug printing (more verbose). she's chatty 💬-dppr-user-length— sets the depth for printing expressions in error messages.-drule-check=⟨str⟩— dumps information about potential rule application.-dshow-passes— prints out each pass name as it happens. live commentary 🌈-dstg-lint— STG pass sanity checking.-dsuppress-all— in dumps, suppresses everything (except for uniques) that is suppressible. minimalist queen 🎀-dsuppress-coercions— suppresses the printing of coercions in Core dumps so they're shorter.-dsuppress-idinfo— suppresses extended information about identifiers where they're bound.-dsuppress-module-prefixes— suppresses the printing of module qualification prefixes.-dsuppress-stg-free-vars— suppresses the printing of closure free variable lists in STG output.-dsuppress-ticks— suppresses "ticks" in the pretty-printer output.-dsuppress-timestamps— suppresses timestamps in dumps.-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 usediff). ngl this one's a lifesaver 😭-dsuppress-var-kinds— suppresses the printing of variable kinds.-dth-dec-file— dumps evaluated TH declarations into*.th.hsfiles.-dunique-increment=⟨i⟩— sets the increment for the generatedUnique's to⟨i⟩.-dverbose-core2core— shows output from each core-to-core pass.-dverbose-stg2stg— shows output from each STG-to-STG pass.-falignment-sanitisation— compiles with alignment checks for all info table dereferences.-fcatch-bottoms— adds a default error alternative to case expressions that don't have a default alternative. catching strays, literally 💀-fcheck-prim-bounds— instruments array primops with bounds checks.-fdistinct-constructor-tables— generates a fresh info table for each usage of a data constructor.-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. it's giving find my friends but for closures 🫶-fllvm-fill-undef-with-garbage— instructs LLVM to fill dead STG registers with garbage. (yes, "intructs" — we stan a typo in the source material. reproduce it and move on ✨)-fproc-alignment— aligns functions at the given boundary.-g— produces DWARF debug information in compiled object files.⟨n⟩can be0,1, or2, with higher numbers producing richer output. If⟨n⟩is omitted, level2is assumed. go off, level 2 default 👑
C pre-processor 🧚
-cpp— runs the C pre-processor on Haskell source files.-D⟨symbol⟩[=⟨value⟩]— defines a symbol in the C pre-processor.-I⟨dir⟩— adds⟨dir⟩to the directory search list for#includefiles.-U⟨symbol⟩— undefines a symbol in the C pre-processor.
Finding imports 🌸
-i— empties the import directory list. poof, gone 🪄-i⟨dir⟩[:⟨dir⟩]*— adds⟨dir⟩,⟨dir2⟩, etc. to the import path.
Interactive mode 💬
-fbreak-on-error— breaks on uncaught exceptions and errors.-fbreak-on-exception— breaks on any exception thrown.-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.-flocal-ghci-history— uses the current directory for the GHCi command history file.ghci-history.-fno-it— no longer sets the special variableit. ripit😭-fprint-bind-result— turns on printing of binding results in GHCi.-fprint-evld-with-show— instructs:printto useShowinstances where possible.-fshow-loaded-modules— shows the names of modules GHCi loaded after a:loadcommand.-ghci-script— reads additional.ghcifiles.-ignore-dot-ghci— disables reading of.ghcifiles.-interactive-print ⟨name⟩— selects the function to use for printing evaluated expressions in GHCi.
Interface files 🎀
--show-iface ⟨file⟩— see Modes of operation.-ddump-hi— dumps the new interface to stdout.-ddump-hi-diffs— shows the differences vs. the old interface.-ddump-minimal-imports— dumps a minimal set of imports.
Keeping intermediate files 🍓
-keep-hc-file— retains intermediate.hcfiles.-keep-hi-files— retains intermediate.hifiles (this is the default, bestie).-keep-hscpp-file— retains intermediate.hscppfiles.-keep-llvm-file— retains intermediate LLVM.llfiles. implies-fllvm.-keep-o-files— retains intermediate.ofiles (the default).-keep-s-file— retains intermediate.sfiles.-keep-tmp-files— retains all intermediate temporary files. a hoarder's dream 🙈
Language options ✨
-XAllowAmbiguousTypes— lets you write ambiguous types, and lets the type inference engine infer them.-XApplicativeDo— enablesApplicativedo-notation desugaring.-XArrows— enables the arrow notation extension.-XBangPatterns— enables bang patterns.-XBinaryLiterals— enables support for binary literals.-XBlockArguments— allowsdoblocks and other constructs as function arguments.-XCApiFFI— enables theCAPIcalling convention.-XConstrainedClassMethods— enables constrained class methods.-XConstraintKinds— enables a kind of constraints.-XCPP— enables the C preprocessor.-XCUSKs— enables detection of complete user-supplied kind signatures. cusks. say it out loud. cusks 💀-XDataKinds— enables datatype promotion.-XDatatypeContexts— allows contexts on data types.-XDeepSubsumption— enables deep subsumption.-XDefaultSignatures— enables default signatures.-XDeriveAnyClass— enables deriving for any class.-XDeriveDataTypeable— enables deriving for theDataclass. implied by (deprecated 💀)AutoDeriveTypeable.-XDeriveFoldable— enables deriving for theFoldableclass. implied byDeriveTraversable.-XDeriveFunctor— enables deriving for theFunctorclass. implied byDeriveTraversable.-XDeriveGeneric— enables deriving for theGenericclass.-XDeriveLift— enables deriving for theLiftclass.-XDeriveTraversable— enables deriving for theTraversableclass. impliesDeriveFunctorandDeriveFoldable.-XDerivingStrategies— enables deriving strategies.-XDerivingVia— enables deriving instances via types of the same runtime representation. impliesDerivingStrategies.-XDisambiguateRecordFields— enables record field disambiguation. implied byRecordWildCards.-XDuplicateRecordFields— allows definition of record types with identically-named fields.-XEmptyCase— allows empty case alternatives.-XEmptyDataDecls— allows definition of empty data types.-XEmptyDataDeriving— allows deriving instances of standard type classes for empty data types.-XExistentialQuantification— enables liberalised type synonyms.-XExplicitForAll— enables explicit universal quantification. implied byScopedTypeVariables,LiberalTypeSynonyms,RankNTypesandExistentialQuantification.-XExplicitNamespaces— enables using the keywordtypeto specify the namespace of entries in imports and exports (Explicit namespaces in import/export). implied byTypeOperatorsandTypeFamilies.-XExtendedDefaultRules— uses GHCi's extended default rules in a normal module.-XFieldSelectors— controls visibility of field selector functions.-XFlexibleContexts— removes some restrictions on class contexts.-XFlexibleInstances— enables flexible instances. impliesTypeSynonymInstances.-XForeignFunctionInterface— enables the foreign function interface.-XFunctionalDependencies— enables functional dependencies. impliesMultiParamTypeClasses.-XGADTs— enables generalised algebraic data types. impliesGADTSyntaxandMonoLocalBinds.-XGADTSyntax— enables generalised algebraic data type syntax.-XGeneralisedNewtypeDeriving— enables newtype deriving.-XGeneralizedNewtypeDeriving— enables newtype deriving. (yes, both spellings. the 'z' version and the 's' version are both iconic and both valid 💅)-XGHC2021— uses GHC's set of default language extensions from 2021.-XGHCForeignImportPrim— enables theprimcalling convention. intended for internal use only 🚨-XHaskell2010— uses the Haskell 2010 language variant.-XHaskell98— uses the Haskell 98 language variant.-XHexFloatLiterals— enables support for hexadecimal floating point literals.-XImplicitParams— enables Implicit Parameters.-XImportQualifiedPost— lets you write the import likeimport M qualified(postfix qualified, cute and modern 💅)-XImpredicativeTypes— turns on impredicative types. ImpliesRankNTypes. 🌀-XIncoherentInstances— turns on incoherent instances. ImpliesOverlappingInstances. Chaos, but make it typechecked 💀-XInstanceSigs— turns on instance signatures ✍️-XInterruptibleFFI— turns on interruptible FFI ⚡-XKindSignatures— turns on kind signatures. Implied byTypeFamiliesandPolyKinds. 🎀-XLambdaCase— turns on lambda-case expressions 🌙-XLexicalNegation— uses whitespace to figure out whether the minus sign means negation or subtraction, iykyk ➖-XLiberalTypeSynonyms— turns on liberalised type synonyms 🕊️-XLinearTypes— turns on linear types 📏-XMagicHash— allows#as a postfix modifier on identifiers ✨ (yes it's literally called magic, no we're not joking)-XMonadComprehensions— turns on monad comprehensions 🧚-XMonoLocalBinds— turns on "do not generalise local bindings". Implied byTypeFamiliesandGADTs. 🔒-XMultiParamTypeClasses— turns on multi parameter type classes. Implied byFunctionalDependencies. 👯-XMultiWayIf— turns on multi-way if-expressions 🔀-XNamedFieldPuns— turns on record puns 🎤-XNamedWildCards— turns on named wildcards 🃏-XNegativeLiterals— turns on support for negative literals ➖-XNoImplicitPrelude— don't implicitly importPrelude. Implied byRebindableSyntax. 🙈-XNoMonomorphismRestriction— disables the monomorphism restriction 🚫-XNondecreasingIndentation— allows nested contexts to sit at the same indentation level as their enclosing context 📐-XNoPatternGuards— disables pattern guards. Implied byHaskell98. 🚫-XNoTraditionalRecordSyntax— disables support for traditional record syntax (the kind Haskell 98 supports), likeC {f = x}🚫-XNPlusKPatterns— turns on support for n+k patterns. Implied byHaskell98. ➕-XNullaryTypeClasses— deprecated, does literally nothing. Nullary (no parameter) type classes are now enabled usingMultiParamTypeClasses. 👻-XNumDecimals— turns on support for 'fractional' integer literals 🍰-XNumericUnderscores— turns on support for numeric underscores1_000_000🔢-XOverlappingInstances— turns on overlapping instances 🥞-XOverloadedLabels— turns on overloaded labels 🏷️-XOverloadedLists— turns on overloaded lists 📋-XOverloadedRecordDot— record'.'syntax 👑-XOverloadedRecordUpdate— record'.'syntax record updates 👑-XOverloadedStrings— turns on overloaded string literals 🧵-XPackageImports— turns on package-qualified imports 📦-XParallelListComp— turns on parallel list comprehensions ⚡-XPartialTypeSignatures— turns on partial type signatures 🩹-XPatternSynonyms— turns on pattern synonyms 🧩-XPolyKinds— turns on kind polymorphism. ImpliesKindSignatures. 🌈-XPostfixOperators— turns on postfix operators 🔚-XQualifiedDo— turns on qualified do-notation desugaring 🎀-XQuantifiedConstraints— allowsforallquantifiers in constraints ∀-XQuasiQuotes— turns on quasiquotation ❝❞-XRank2Types— turns on rank-2 types. Synonym forRankNTypes. 🥈-XRankNTypes— turns on rank-N types. Implied byImpredicativeTypes. 🥇-XRebindableSyntax— employs rebindable syntax. ImpliesNoImplicitPrelude. 🔁-XRecordWildCards— turns on record wildcards. ImpliesDisambiguateRecordFields. 🃏-XRecursiveDo— turns on recursive do (mdo) notation 🔄-XRoleAnnotations— turns on role annotations 🎭-XSafe— enables the Safe Haskell Safe mode 🛡️-XScopedTypeVariables— turns on lexically-scoped type variables 🔭-XStandaloneDeriving— turns on standalone deriving 🧍-XStandaloneKindSignatures— allows the use of standalone kind signatures 🧍-XStarIsType— treats*asData.Kind.Type⭐-XStaticPointers— turns on static pointers 📌-XStrict— makes bindings in the current module strict by default 😤-XStrictData— turns on default strict datatype fields 😤-XTemplateHaskell— turns on Template Haskell 🧙-XTemplateHaskellQuotes— turns on the quotation subset of Template Haskell ✂️-XTransformListComp— turns on generalised list comprehensions 🔀-XTrustworthy— enables the Safe Haskell Trustworthy mode 🤝-XTupleSections— turns on tuple sections 🍡-XTypeApplications— turns on type application syntax in terms, patterns and types 🎯-XTypeFamilies— turns on type families. ImpliesExplicitNamespaces,KindSignatures, andMonoLocalBinds. 👨👩👧-XTypeFamilyDependencies— turns on injective type families. ImpliesTypeFamilies. 💉-XTypeInType— deprecated. Enables kind polymorphism and datatype promotion. 👻-XTypeOperators— turns on type operators. ImpliesExplicitNamespaces. ➕-XTypeSynonymInstances— turns on type synonyms in instance heads. Implied byFlexibleInstances. 🧬-XUnboxedSums— turns on unboxed sums 📦-XUnboxedTuples— turns on the use of unboxed tuple syntax 📦-XUndecidableInstances— turns on undecidable instances 🤷-XUndecidableSuperClasses— allows all superclass constraints, including the ones that may make the typechecker not terminate 😭 (yes, for real, the typechecker might just spin forever)-XUnicodeSyntax— turns on unicode syntax ✨-XUnliftedDatatypes— turns on unlifted data types 🪂-XUnliftedFFITypes— turns on unlifted FFI types 🪂-XUnliftedNewtypes— turns on unlifted newtypes 🪂-XUnsafe— enables Safe Haskell Unsafe mode 😈-XViewPatterns— turns on view patterns 👀
🔗 Linking options 🔗
okay this is where the linker stuff lives, bestie. linker flags are giving backstage-pass energy 🎟️
-c— stop after generating the object (.o) file-debug— use the debugging runtime 🐛-dylib-install-name⟨path⟩ — set the install name (via-install_namepassed to Apple's linker), specifying 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— selects one of a number of modes for finding shared libraries at runtime-eventlog— enable runtime event tracing 📊-fcompact-unwind— instruct the linker to produce a__compact_unwindsection-fkeep-cafs— do not garbage-collect CAFs (top-level expressions) at runtime 🗑️-flink-rts— link the runtime when generating a shared or static library-fno-embed-manifest— do not embed the manifest in the executable (Windows only) 🪟-fno-gen-manifest— do not generate a manifest file (Windows only) 🪟-fno-shared-implib— don't generate an import library for a DLL (Windows only) 🪟-framework⟨name⟩ — on Darwin/OS X/iOS only, link in the framework ⟨name⟩. This option corresponds to the-frameworkoption for Apple's Linker. 🍎-framework-path⟨dir⟩ — on Darwin/OS X/iOS only, add ⟨dir⟩ to the list of directories searched for frameworks. This option corresponds to the-Foption for Apple's Linker. 🍎-fuse-rpaths— set the rpath based on-Lflags-fwhole-archive-hs-libs— when linking a binary executable, this inserts the flag-Wl,--whole-archivebefore any-lflags for Haskell libraries, and-Wl,--no-whole-archiveafterwards 📚-L⟨dir⟩ — add ⟨dir⟩ to the list of directories searched for libraries-l⟨lib⟩ — link in library ⟨lib⟩-main-is⟨thing⟩ — set main module and function 🎯-no-hs-main— don't assume this program containsmain🙅-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— this instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. Currently Linux and Windows/MinGW32 only. This is equivalent to using-optl -rdynamicon Linux, and-optl -export-all-symbolson Windows. 🐧🪟-rtsopts[=⟨none|some|all|ignore|ignoreAll⟩]— control whether the RTS behaviour can be tweaked via command-line flags and theGHCRTSenvironment variable. Usingnonemeans no RTS flags can be given;somemeans only a minimum of safe options can be given (the default);all(or no argument at all) means that all RTS flags are permitted;ignoremeans RTS flags can be given, but are treated as regular arguments and passed to the Haskell program as arguments;ignoreAllis the same asignore, butGHCRTSis also ignored.-rtsoptsdoes not affect-with-rtsoptsbehavior; flags passed via-with-rtsoptsare used regardless of-rtsopts. ⚙️-shared— generate a shared library (as opposed to an executable)-split-sections— split sections for link-time dead-code stripping ✂️-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 in a single static library that can be linked against. 📚-threaded— use the threaded runtime 🧵-with-rtsopts=⟨opts⟩ — set the default RTS options to ⟨opts⟩ ⚙️
🧃 Miscellaneous options 🧃
the grab-bag section, the everything-drawer of flags 🗄️
-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 extensions for exactly which ones. 👴-fno-safe-haskell— disable Safe Haskell 🙅-ghcversion-file⟨path to ghcversion.h⟩ — (GHC as a C compiler only) use thisghcversion.hfile 🗂️-H⟨size⟩ — set the minimum size of the heap to ⟨size⟩ 📈-j[⟨n⟩]— when compiling with--make, compile ⟨n⟩ modules in parallel ⚡
🎛️ Modes of operation 🎛️
--frontend⟨module⟩ — run GHC with the given frontend plugin; see Frontend plugins for details 🔌--help— display help 🙋--info— spills all the info about this compiler build, like a whole vibe check of what GHC is made of 👑--interactive— interactive mode, bestie! This is the one you're in when you literally just runghci; see Using GHCi for the deets ✨--make— builds a whole multi-module Haskell program and figures out the dependencies all by itself. Lowkey way easier and faster than fighting withmake; see Using ghc --make for the full tea 🫶--mk-dll— DLL-creation mode (Windows only, so if you're not on Windows this is not your moment 💀)--numeric-version— display GHC version, numeric only (just the digits, no extra chatter)--print-booter-version— display the bootstrap compiler version--print-build-platform— display the platform on which GHC was built--print-c-compiler-flags— the C compiler flags used to build GHC--print-c-compiler-link-flags— the C linker flags used to build GHC--print-debug-on— prints 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 the target platform has NCG support--print-host-platform— display the host platform of GHC--print-ld-flags— display the linker flags used to compile GHC--print-leading-underscore— display use of leading underscores on symbol names--print-libdir— display the GHC library directory--print-object-splitting-supported— display whether GHC supports object splitting--print-project-git-commit-id— display the Git commit id GHC is built from--print-project-version— display GHC version--print-rts-ways— display which way the RTS was built--print-stage— display the 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 the target platform of GHC--print-unregisterised— display whether this GHC was built in unregisterised mode (iconic spelling, we keep it 🎀)--run⟨file⟩ — run a Haskell program. That's it, that's the whole job 💅--show-iface⟨file⟩ — display the contents of an interface file--show-options— display the supported command line options (yes, the list of the list, very meta of it)--supported-extensions— display the supported language extensions--version— display GHC version-e⟨expr⟩ — evaluate expr; see Expression evaluation mode for the details ✨-M— generate dependency information suitable for use in aMakefile; see Dependency generation for details
🔥 Individual optimizations 🔥
Okay bestie, this next chunk is the deep magic — the knobs the optimizer turns. Ngl, most of these you'll never touch, but the flags are all here and they're all real, so let's go 🧚
-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.-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-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.-fcpr-anal— turn on CPR analysis in the demand analyser. Implied by-O.-fcross-module-specialise— turn on specialisation of overloaded functions imported from other modules.-fcse— enable common sub-expression elimination. Implied by-O.-fdicts-cheap— make dictionary-valued expressions seem cheap to the optimiser.-fdicts-strict— make dictionaries strict.-fdmd-tx-dict-sel— (deprecated) use a special demand transformer for dictionary selectors. Deprecated, so, like, it's giving "we don't do that anymore" 💀-fdo-eta-reduction— enable eta-reduction. Implied by-O.-fdo-lambda-eta-expansion— enable lambda eta-expansion. Always enabled by default.-feager-blackholing— turn on eager blackholing.-fenable-rewrite-rules— switch on all rewrite rules (including rules generated by automatic specialisation of overloaded functions). Implied by-O.-fexcess-precision— enable excess intermediate precision.-fexitification— enables exitification optimisation. Implied by-O.-fexpose-all-unfoldings— expose all unfoldings, even for very large or recursive functions.-ffloat-in— turn on the float-in transformation. Implied by-O.-ffull-laziness— turn on full laziness (floating bindings outwards). Implied by-O.-ffun-to-thunk— allow worker-wrapper to convert a function closure into a thunk if the function does not use any of its arguments. Off by default.-fignore-asserts— ignore assertions in the source. Implied by-O.-fignore-interface-pragmas— ignore pragmas in interface files. Implied by-O0only.-finline-generics— annotate methods of derivedGenericandGeneric1instances withINLINE[1]pragmas based on heuristics. Implied by-O.-finline-generics-aggressively— annotate methods of all derivedGenericandGeneric1instances withINLINE[1]pragmas.-flate-dmd-anal— run demand analysis again, at the end of the simplification pipeline.-flate-specialise— run a late specialisation pass.-fliberate-case— turn on the liberate-case transformation. Implied by-O2.-fliberate-case-threshold=⟨n⟩ — default:2000. Set the size threshold for the liberate-case transformation to ⟨n⟩.-fllvm-pass-vectors-in-regs— (deprecated) does nothing. Literally nothing, it's just vibes 🙈-floopification— turn saturated self-recursive tail-calls into local jumps in the generated assembly. Implied by-O.-fmax-inline-alloc-size=⟨n⟩ — default:128. Set the maximum size of inline array allocations to ⟨n⟩ bytes (default: 128).-fmax-inline-memcpy-insns=⟨n⟩ — default:32. Inlinememcpycalls if they would generate no more than ⟨n⟩ pseudo instructions.-fmax-inline-memset-insns=⟨n⟩ — default:32. Inlinememsetcalls if they would generate no more than ⟨n⟩ pseudo instructions.-fmax-simplifier-iterations=⟨n⟩ — default:4. Set the max iterations for the simplifier.-fmax-uncovered-patterns=⟨n⟩ — default:4. Set 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— turn off the coercion optimiser.-fno-pre-inlining— turn off pre-inlining.-fno-state-hack— turn off the state hack, whereby 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.-fomit-interface-pragmas— don't generate interface pragmas. Implied by-O0only.-fomit-yields— omit heap checks when no allocation is being performed.-foptimal-applicative-do— use a slower but better algorithm forApplicativeDo.-fpedantic-bottoms— make GHC be more precise about its treatment of bottom (but see also-fno-state-hack). In particular, GHC will not eta-expand through a case expression.-fregs-graph— use the graph colouring register allocator for register allocation in the native code generator.-fregs-iterative— use the iterative coalescing graph colouring register allocator in the native code generator.-fsimpl-tick-factor=⟨n⟩ — default:100. Set the percentage factor for simplifier ticks.-fsimplifier-phases=⟨n⟩ — default:2. Set the number of phases for the simplifier. Ignored with-O0.-fsolve-constant-dicts— when solving constraints, try to eagerly solve super classes using available dictionaries.-fspec-constr— turn on the SpecConstr transformation. Implied by-O2.-fspec-constr-count=⟨n⟩ — default:3.*Set to ⟨n⟩ the maximum number of specialisations that will be created for any one function by the SpecConstr transformation.-fspec-constr-keen— specialize 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. Set the size threshold for the SpecConstr transformation to ⟨n⟩.-fspecialise— turn on specialisation of overloaded functions. Implied by-O.-fspecialise-aggressively— turn on specialisation of overloaded functions regardless of size, if unfolding is available.-fstatic-argument-transformation— turn on the static argument transformation.-fstg-cse— enable common sub-expression elimination on the STG intermediate language.-fstg-lift-lams— enable late lambda lifting on the STG intermediate language. Implied by-O2.-fstg-lift-lams-known— allow turning known into unknown calls while performing late lambda lifting.-fstg-lift-lams-non-rec-args— create top-level non-recursive functions with at most<n>parameters while performing late lambda lifting.-fstg-lift-lams-rec-args— create top-level recursive functions with at most<n>parameters while performing late lambda lifting.-fstrictness— turn on demand analysis. Implied by-O. Implies-fworker-wrapper.-fstrictness-before=⟨n⟩ — run an additional demand analysis before simplifier phase ⟨n⟩.-funbox-small-strict-fields— flatten strict constructor fields with a pointer-sized representation. Implied by-O.-funbox-strict-fields— flatten strict constructor fields.-funfolding-case-scaling=⟨n⟩ — default:30. Apply a penalty of (inlining_cost * 1/n) for each level of case nesting.-funfolding-case-threshold=⟨n⟩ — default:2. Reduce inlining for cases nested deeper than n.-funfolding-creation-threshold=⟨n⟩ — default:750. Tweak unfolding settings.-funfolding-dict-discount=⟨n⟩ — default:30. Tweak unfolding settings.-funfolding-fun-discount=⟨n⟩— default:60. Tiny knob for tweaking your unfolding settings ✨-funfolding-keeness-factor=⟨n⟩— heads up bestie, this one's been deprecated in GHC 9.0.1 💀 (yes, that's how it's spelled, keeness with two e's, don't come for me)-funfolding-use-threshold=⟨n⟩— default:80. Another lil unfolding settings tweaker 🎀-fworker-wrapper— turns on the worker/wrapper transformation 👷
🚀 Optimization levels 🚀
-O— level 1 optimisations, on 🔥-O0— no optimisations at all, and that's the default babe 🙈-O2— level 2 optimisations, we're going off 💅-O⟨n⟩— literally any-Onwhere n > 2 is just the same as-O2. The more you know 🌈
📦 Package options 📦
-clear-package-db— wipes the package db stack clean 🧹-distrust ⟨pkg⟩— exposes package ⟨pkg⟩ and marks it distrusted. See Safe Haskell 🔒-distrust-all-packages— distrusts every package by default, no exceptions. See Safe Haskell 🔒-fpackage-trust— enables the 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⟩, like it doesn't even exist 💀-no-auto-link-packages— don't automatically link in thebaseandrtspackages-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 package environment you point at 🎀-package-id ⟨unit-id⟩— exposes a package by its id ⟨unit-id⟩-this-unit-id ⟨unit-id⟩— compile so you're part of unit (i.e. package) ⟨unit-id⟩-trust ⟨pkg⟩— exposes package ⟨pkg⟩ and marks it trusted. See Safe Haskell 🔒-user-package-db— adds the user's package db to the stack
🛠️ Phases of compilation 🛠️
-C— stop after generating the C file (.hc)-c— stop after generating the object file (.o)-E— stop after preprocessing (.hspp)-F— enable using a pre-processor (set it with-pgmF ⟨cmd⟩)-S— stop after generating assembly (.s)-x ⟨suffix⟩— override the default behaviour for source files
🔌 Overriding external programs 🔌
-pgma ⟨cmd⟩— use ⟨cmd⟩ as the assembler-pgmc ⟨cmd⟩— use ⟨cmd⟩ as the C compiler-pgmdll ⟨cmd⟩— use ⟨cmd⟩ as the DLL generator-pgmF ⟨cmd⟩— use ⟨cmd⟩ as the pre-processor (only with-F)-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 🍎-pgmL ⟨cmd⟩— use ⟨cmd⟩ as the literate pre-processor-pgml ⟨cmd⟩— use ⟨cmd⟩ as the linker-pgmlc ⟨cmd⟩— use ⟨cmd⟩ as the LLVM compiler-pgmlibtool ⟨cmd⟩— use ⟨cmd⟩ as the command for libtool (only with-staticlib)-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 (only with-cpp)-pgms ⟨cmd⟩— use ⟨cmd⟩ as the splitter-pgmwindres ⟨cmd⟩— use ⟨cmd⟩ as the program for embedding manifests on Windows 🪟
🎯 Phase-specific options 🎯
-opta ⟨option⟩— passes ⟨option⟩ to the assembler-optc ⟨option⟩— passes ⟨option⟩ to the C compiler-optcxx ⟨option⟩— passes ⟨option⟩ to the C++ compiler-optdll ⟨option⟩— passes ⟨option⟩ to the DLL generator-optF ⟨option⟩— passes ⟨option⟩ to the custom pre-processor-opti ⟨option⟩— passes ⟨option⟩ to the interpreter sub-process-optL ⟨option⟩— passes ⟨option⟩ to the literate pre-processor-optl ⟨option⟩— passes ⟨option⟩ to the linker-optlc ⟨option⟩— passes ⟨option⟩ to the LLVM compiler-optlm ⟨option⟩— passes ⟨option⟩ to the linker when merging object files-optlo ⟨option⟩— passes ⟨option⟩ to the LLVM optimiser-optP ⟨option⟩— passes ⟨option⟩ to cpp (only with-cpp)-optwindres ⟨option⟩— passes ⟨option⟩ to windres-pgmc-supports-no-pie— indicates that the C compiler supports-no-pie
ngl the-optL(capital L, literate) vs-optl(lowercase l, linker) thing is so sneaky — read twice bestie 👀
💻 Platform-specific options 💻
-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-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
every single one of these is x86 only, so if you're on ARM just scroll past, this isn't your era 💀
🧩 Compiler plugins 🧩
-fclear-plugins— clears the list of active plugins 🧹-fplugin-opt=⟨module⟩:⟨args⟩— gives arguments to a plugin module; the module has to be specified with-fplugin=⟨module⟩-fplugin-trustworthy— trusts the plugins in use and stops marking the compiled module as unsafe 🫶-fplugin=⟨module⟩— loads a plugin exported by a given module-hide-all-plugin-packages— hides all packages for plugins by default 🙈-plugin-package ⟨pkg⟩— exposes ⟨pkg⟩ for plugins-plugin-package-id ⟨pkg-id⟩— exposes ⟨pkg-id⟩ for plugins
📊 Profiling 📊
-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— don't collect entry counts-fprof-auto— auto-addsSCCs to all bindings not markedINLINE-fprof-auto-calls— auto-addsSCCs to all call sites-fprof-auto-exported— auto-addsSCCs to all exported bindings not markedINLINE-fprof-auto-top— auto-addsSCCs to all top-level bindings not markedINLINE-fprof-cafs— auto-addsSCCs to all CAFs-fprof-callers=⟨name⟩— auto-addsSCCs to all call-sites of the named function-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— turns on profiling-ticky— turns on ticky-ticky profiling-ticky-allocd— tracks the number of times each closure type gets allocated-ticky-dyn-thunk— tracks allocations of dynamic thunks
🎯 Program coverage 🎯
-fhpc— turns on Haskell program coverage instrumentation ⭐
🔁 Recompilation checking 🔁
-fforce-recomp— turns off recompilation checking. Fun fact: it's implied by any-ddump-Xoption when you're compiling a single file (i.e. when you're using-c) 🫠-fignore-hpc-changes— doesn't recompile modules just to match changes to HPC flags. Super useful for avoiding recompiles when you're in GHCi, and it's enabled by default for GHCi ✨-fignore-optim-changes— doesn't recompile modules just to match changes to optimisation flags. Also super useful for dodging recompiles in GHCi, and also enabled by default for GHCi ✨
📤 Redirecting output 📤
--exclude-module=⟨file⟩— treats ⟨file⟩ as "stable"; i.e. excludes it from having dependencies on it-ddump-mod-cycles— dumps module cycles 🌀-dep-makefile ⟨file⟩— uses ⟨file⟩ as the makefile-dep-suffix ⟨suffix⟩— makes dependencies that declare that files with suffix.⟨suf⟩⟨osuf⟩depend on interface files with suffix.⟨suf⟩hi-dumpdir ⟨dir⟩— redirects dump files-dynhisuf ⟨suffix⟩— sets the suffix to use for dynamic interface files-dyno ⟨file⟩— sets the dynamic output filename-dynohi ⟨file⟩— sets the filename to put the dynamic interface in-dynosuf ⟨suffix⟩— sets the dynamic output file suffix-hcsuf ⟨suffix⟩— sets the suffix to use for intermediate C files-hidir ⟨dir⟩— sets the directory for interface files-hiedir ⟨dir⟩— sets the directory for extended interface files-hiesuf ⟨suffix⟩— sets the suffix to use for extended interface files-hisuf ⟨suffix⟩— sets the suffix to use for interface files-include-cpp-deps— includes preprocessor dependencies-include-pkg-deps— treats modules imported from packages as unstable-o ⟨file⟩— sets the output filename-odir ⟨dir⟩— sets the directory for object files-ohi ⟨file⟩— sets the filename to put the interface in-osuf ⟨suffix⟩— sets the output file suffix-outputdir ⟨dir⟩— sets the output directory-stubdir ⟨dir⟩— redirects FFI stub files
🗂️ Temporary files 🗂️
-tmpdir ⟨dir⟩— sets the directory for temporary files
🗣️ Verbosity options 🗣️
-fabstract-refinement-hole-fits— default: off. Toggles whether refinements where one or more of the holes are abstract get reported-fdefer-diagnostics— defers and groups diagnostic messages by severity-fdiagnostics-color=⟨always|auto|never⟩— uses colors in error messages 🌈-fdiagnostics-show-caret— whether to show snippets of the original source code-ferror-spans— outputs the full span in error messages-fhide-source-paths— hides module source and object paths-fkeep-going— keeps compiling as far as possible even when there are errors 💪-fmax-refinement-hole-fits=⟨n⟩— default:6. Sets the maximum number of refinement hole fits for typed holes to display in type error messages-fmax-relevant-binds=⟨n⟩— default:6. Sets the maximum number of bindings to display in type error messages
okay so bestie, we're deep in typed-hole territory now — hold my hand, we're going in 💅
-fmax-valid-hole-fits=⟨n⟩— default:6. this is the cap on how many valid hole fits GHC is allowed to show you in type error messages. like a little stack of suggestions, and you're choosing how tall the stack gets 🌸-fno-show-valid-hole-fits— disables showing that whole list of valid hole fits for typed holes in type error messages. bye bye suggestions 😭-fno-sort-valid-hole-fits— disables the sorting of the valid hole fits list in type error messages. no ranking, no order, just vibes 💀-fprint-axiom-incomps— display equation incompatibilities in closed type families 🦋-fprint-equality-relations— distinguish between equality relations when printing 👑-fprint-expanded-synonyms— in type errors, also print type-synonym-expanded types. so you can actually see what's underneath 🎀-fprint-explicit-coercions— print coercions in types 💅-fprint-explicit-foralls— print explicitforallquantification in types. see alsoExplicitForAll✨-fprint-explicit-kinds— print explicit kind foralls and kind arguments in types. see alsoKindSignatures🌈-fprint-explicit-runtime-reps— printRuntimeRepvariables in types which are runtime-representation polymorphic. iykyk 🔥-fprint-potential-instances— display all available instances in type error messages. every single one, no gatekeeping 🫶-fprint-typechecker-elaboration— print extra information from the typechecker. the tea ☕-fprint-unicode-syntax— use unicode syntax when printing expressions, types and kinds. see alsoUnicodeSyntax— pretty math symbols, we love to see it 🧚-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 🦋-freverse-errors— output errors in reverse order 🙈-fshow-docs-of-hole-fits— toggles whether to show the documentation of the valid hole fits in the output 🎀-fshow-hole-constraints— show constraints when reporting typed holes 💜-fshow-hole-matches-of-hole-fits— toggles whether to show the type of the additional holes in refinement hole fits ✨-fshow-provenance-of-hole-fits— toggles whether to show the provenance of the valid hole fits in the output 👑-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— sort valid hole fits by size 🍓-fsort-by-subsumption-hole-fits— sort valid hole fits by subsumption 🦋-funclutter-valid-hole-fits— unclutter the list of valid hole fits by not showing provenance nor type applications of suggestions. minimalism era 💅-Rghc-timing— summarise timing stats for GHC (same as+RTS -tstderr) ⏱️-v— verbose mode (equivalent to-v3) 👀-v⟨n⟩— set verbosity level 🎚️
⚠️ Warnings ⚠️
okay these are the flags that tell GHC to tell you things. your compiler being a little nosy bestie who's looking out for you 🫶
-fdefer-out-of-scope-variables— convert variable out of scope variables errors into warnings. implied by-fdefer-type-errors. see also-Wdeferred-out-of-scope-variables🙈-fdefer-type-errors— turn type errors into warnings, deferring the error until runtime. implies-fdefer-typed-holesand-fdefer-out-of-scope-variables. see also-Wdeferred-type-errors😭-fdefer-typed-holes— convert typed hole errors into warnings, deferring the error until runtime. implied by-fdefer-type-errors. see also-Wtyped-holes🕳️-fenable-th-splice-warnings— generate warnings for Template Haskell splices ✨-fhelpful-errors— make suggestions for mis-spelled names. literally the compiler going "did you mean…?" 🥺-fmax-pmcheck-models=⟨n⟩— soft limit on the number of parallel models the pattern match checker should check a pattern match clause against 🔍-fshow-warning-groups— show which group an emitted warning belongs to 👑-fvia-C— use the C code generator 🏗️-W— enable normal warnings ✅-w— disable all warnings. silence. peace. 🔇-Wall— enable almost all warnings (details in Warnings and sanity-checking) 🌈-Wall-missed-specialisations— warn when specialisation of any overloaded function fails 💀-Wall-missed-specializations— alias for-Wall-missed-specialisations🫶-Wambiguous-fields— warn about ambiguous field selectors or updates 🌸-Wauto-orphans— (deprecated) does nothing. iconic of it honestly 💅-Wcompat— enable future compatibility warnings (details in Warnings and sanity-checking) 🔮-Wcompat-unqualified-imports— report unqualified imports of core libraries which are expected to cause compatibility problems in future releases ⏳-Wcpp-undef— warn on uses of the#ifdirective on undefined identifiers 🎀-Wdefault— enable default flags ⭐-Wdeferred-out-of-scope-variables— report warnings when variable out-of-scope errors are deferred until runtime. see-fdefer-out-of-scope-variables🦋-Wdeferred-type-errors— report warnings when deferred type errors are enabled. this option is enabled by default. see-fdefer-type-errors🔥-Wdeprecated-flags— warn about uses of commandline flags that are deprecated 🕰️-Wdeprecations— warn about uses of functions & types that have warnings or deprecated pragmas. alias for-Wwarnings-deprecations😭-Wderiving-defaults— warn about default deriving when using bothDeriveAnyClassandGeneralizedNewtypeDeriving💀-Wderiving-typeable— warn whenTypeableis derived 🦋-Wdodgy-exports— warn about dodgy exports 👀-Wdodgy-foreign-imports— warn about dodgy foreign imports 🌍-Wdodgy-imports— warn about dodgy imports 🚩-Wduplicate-constraints— warn when a constraint appears duplicated in a type signature 🎀-Wduplicate-exports— warn when an entity is exported multiple times ✌️-Wempty-enumerations— warn about enumerations that are empty 🫙-Werror— make warnings fatal. no more nice girl 💀-Weverything— enable all warnings supported by GHC. all of them. every last one 👑-Wextra— alias for-W🌟-Whi-shadowing— (deprecated) warn when a.hifile in the current directory shadows a library 🙈-Widentities— warn about uses of Prelude numeric conversions that are probably the identity (and hence could be omitted) 💅-Wimplicit-kind-vars— warn when kind variables are implicitly quantified over 🦋-Wimplicit-lift— warn about implicit lift in Template Haskell quotes ⬆️-Wimplicit-prelude— warn when the Prelude is implicitly imported 🌸-Winaccessible-code— warn about inaccessible code 🚪-Wincomplete-patterns— warn when a pattern match could fail 😬-Wincomplete-record-updates— warn when a record update could fail 🫠-Wincomplete-uni-patterns— warn when a pattern match in a lambda expression, pattern binding or a lazy pattern could fail 🍓-Winferred-safe-imports— warn when an explicitly Safe Haskell module imports a Safe-Inferred one 🛡️-Winline-rule-shadowing— warn 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— warn when a Haddock comment occurs in an invalid position 📝-Wmissed-extra-shared-lib— warn when GHCi can't load a shared lib 😭-Wmissed-specialisations— warn when specialisation of an imported, overloaded function fails 💀-Wmissed-specializations— alias for-Wmissed-specialisations🫶-Wmissing-deriving-strategies— warn when aderivingclause is missing a deriving strategy 🎀-Wmissing-export-lists— warn when a module declaration does not explicitly list all exports 📋-Wmissing-exported-signatures— warn about top-level functions without signatures, only if they are exported ✨-Wmissing-exported-sigs— (deprecated) warn about top-level functions without signatures, only if they are exported. takes precedence over-Wmissing-signatures👑-Wmissing-fields— warn when fields of a record are uninitialised 🕳️-Wmissing-home-modules— warn 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 inexposed-modules, nor inother-modules📦-Wmissing-import-lists— warn when an import declaration does not explicitly list all the names brought into scope 📜-Wmissing-kind-signatures— warn when type declarations don't have kind signatures nor CUSKs 🦋-Wmissing-local-signatures— warn about polymorphic local bindings without signatures 🏷️-Wmissing-local-sigs— (deprecated) warn about polymorphic local bindings without signatures 💅-Wmissing-methods— warn when class methods are undefined 😱-Wmissing-monadfail-instances— warn when a failable pattern is used in a do-block that does not have aMonadFailinstance 💀-Wmissing-pattern-synonym-signatures— warn when pattern synonyms do not have type signatures 🎀-Wmissing-safe-haskell-mode— warn when the Safe Haskell mode is not explicitly specified 🛡️-Wmissing-signatures— warn about top-level functions without signatures ✍️-Wmissing-space-after-bang— (deprecated) does nothing. truly doing the least 🫠-Wmonomorphism-restriction— warn when the Monomorphism Restriction is applied 🌀-Wname-shadowing— warn when names are shadowed 👥-Wno-compat— disables all warnings enabled by-Wcompat❌-Wnoncanonical-monad-instances— warn whenApplicativeorMonadinstances have noncanonical definitions ofreturn,pure,(>>), or(*>). see flag description in Warnings and sanity-checking for more details 📚-Wnoncanonical-monadfail-instances— (deprecated) warn whenMonadorMonadFailinstances have noncanonical definitions offail🕰️-Wnoncanonical-monoid-instances— warn whenSemigrouporMonoidinstances have noncanonical definitions of(<>)ormappend. see flag description in Warnings and sanity-checking for more details 🌸-Wnot— (deprecated) alias for-w🚫-Woperator-whitespace— warn on prefix, suffix, and tight infix uses of infix operators ✂️
okay bestie, we're in the home stretch of the warning flags — the -W era of the list. deep breath, hydrate, let's go 💖
-Woperator-whitespace-ext-conflict— yells at you about infix operators that would get parsed differently if some particular GHC extension were turned on. it's giving "this syntax is a landmine depending on your vibe check" 💀-Worphans— warns when your module is out here with orphan instance declarations or rewrite rules. no family, no home module, iconic but chaotic 🫶-Woverflowed-literals— warns about literals that are gonna overflow their type. bestie, that number does NOT fit, stop trying to shove it in 🙈-Woverlapping-patterns— warns about overlapping patterns. your pattern match is doing the absolute most and stepping on its own toes ✨-Wpartial-fields— warns when you're defining a partial record field. it's giving "not every constructor has this field" energy, lowkey dangerous 💅-Wpartial-type-signatures— warns about holes in partial type signatures whenPartialTypeSignaturesis enabled. heads up though: this one is not applicable whenPartialTypeSignaturesis not enabled — in that case, those holes become actual errors instead 😭-Wprepositive-qualified-module— reports imports that have a leading/prepositive"qualified". the qualifier is standing in the front like it's the main character 👑-Wredundant-bang-patterns— warns about redundant bang patterns. all those!s and for what, bestie 🔥-Wredundant-constraints— makes the compiler warn about redundant constraints in type signatures. if the constraint isn't doing anything, it's just extra luggage 🎀-Wredundant-record-wildcards— warns about record wildcard matches when the wildcard binds no patterns whatsoever. literally binding nothing, why are you here 💀-Wsafe— warn if the module being compiled is regarded to be safe. safe and proud 🫶-Wsemigroup— warns when aMonoidis not aSemigroup, and on non-Semigroupdefinitions of(<>)? yes bestie the question mark stays, we're skeptical in this house 🌸-Wsimplifiable-class-constraints— warns about class constraints in a type signature that could be simplified using a top-level instance declaration. the answer was already sitting right there in your top-level, babe ✨-Wstar-binder— warns about binding the(*)type operator despiteStarIsType. the star, but as a binder? conflicting vibes ngl ⭐-Wstar-is-type— warns when*is used to meanData.Kind.Type. stars are types now, iykyk 🌈-Wtabs— warn if there are tabs in the source file. tabs in source, in this economy?? no ma'am 💅-Wtrustworthy-safe— warn if the module you're compiling is marked asTrustworthybut it could actually be marked asSafeinstead — which is a more informative bound. glow up available and you're not taking it, bestie 👑-Wtype-defaults— warn when defaulting happens. the compiler is out here making choices for you, and now it's gonna tell you about it 🙈-Wtyped-holes— report warnings when typed hole errors get deferred until runtime. see-fdefer-typed-holesfor the whole story 🕳️-Wunbanged-strict-patterns— warns on a pattern bind of an unlifted variable that is neither bare nor banged. neither bare NOR banged, it's giving undecided 😭-Wunicode-bidirectional-format-characters— warns about the usage of unicode bidirectional layout override characters. those sneaky invisible text-flippers, fr fr be careful 🚩-Wunrecognised-pragmas— warns about uses of pragmas that GHC doesn't recognise.{-# ... #-}, who are you again?? 💀-Wunrecognised-warning-flags— throws a warning when an unrecognised-W...flag shows up on the command line. the flag police are on the case 🚨-Wunsafe— warn if the module being compiled is regarded to be unsafe. see Safe Haskell for the lore 💜-Wunsupported-calling-conventions— warns about use of an unsupported calling convention. calling who? not supported, that's who 😭-Wunsupported-llvm-version— warns when using-fllvmwith an unsupported version of LLVM. version check bestie, mismatch alert ⚠️-Wunticked-promoted-constructors— warns if promoted constructors are not ticked. slap that tick on there, it's fashion and function ✨-Wunused-binds— warns about bindings that are unused. it's an alias for-Wunused-top-binds,-Wunused-local-bindsand-Wunused-pattern-binds— three flags in a trench coat 🧚-Wunused-do-bind— warns about do bindings that appear to throw away values of types other than(). if it's not()and you dropped it, we're talking 🙈-Wunused-foralls— warns about type variables in user-writtenforalls that are unused. you quantified it and then ghosted it, rude 💀-Wunused-imports— warns about unnecessary imports. import nothing you don't need, declutter your life 🎀-Wunused-local-binds— warns about local bindings that are unused. locals count too!! 🦋-Wunused-matches— warns about variables in patterns that aren't used. matching but not using? confusing aura 🌸-Wunused-packages— warns when a package is requested on the command line, but was never loaded. you asked for it and then never opened it, we see you 👀-Wunused-pattern-binds— warns about pattern match bindings that are unused. pattern, matched, ignored. the full arc 😭-Wunused-record-wildcards— warns about record wildcard matches when none of the bound variables are used. zero uses. zero. why are we even here 💀-Wunused-top-binds— warns about top-level bindings that are unused. top-level but not top-of-mind, apparently ✨-Wunused-type-patterns— warns about unused type variables which arise from patterns in type family and data family instances. families! patterns! unused variables! drama 🫶-Wwarn— makes warnings non-fatal. let them be little, let them be warnings and not errors 💖-Wwarnings-deprecations— warns about uses of functions & types that have warnings or deprecated pragmas. deprecated means do not, but at least it's just a warning 😅-Wwrong-do-bind— warns about do bindings that appear to throw away monadic values that you should have bound instead. bestie. you had ONE job. bind it. BIND IT 🔥
💜 COPYRIGHT 💜
Copyright 2015. The University Court of the University of Glasgow. All rights reserved. yes, that's the real legal text, no she did not change it 🎀
🦋 SEE ALSO 🦋
https://www.haskell.org/ghc — the GHC homepage. go click it, it's the mothership 💅
✨ AUTHOR ✨
The GHC Team. legends, all of them 👑
🌈 COPYRIGHT 🌈
2025, GHC Team. slay, they renewed it 💖
and that's the whole page bestie — source GHC(1), version 9.2.8, dated Jan 21, 2025, all wrapped up with a little bow 🎀 you read the entire thing, i'm so proud of you, go compile something iconic 🦋💜
📦 where this page comes from
- epel 10: ghc9.2-compiler 9.2.8-28.el10_0 · BSD-3-Clause
- 💖 girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms