-Z option triage

As of 2023-11-08, we have 185 unstable (-Z) options. Are they all necessary? Should some be stabilized? Let's crowdsource that question.

Please mark them as follows:

  • "removable?": ones you think could be removed.
  • "stabilize?": ones you think could be stabilized. E.g. ones used for Rust-in-Linux
  • And annotate ones you think should be kept.
  • Include your name/handle at the start of each comment.

Note: The categories below are rough, and many options could go in more than one category. The exact category for each option doesn't really matter, it's just a way of structuring this document.

printing/dumping internal stuff

  • -Z dump-dep-graph=val dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no)
  • -Z dump-mir=val dump MIR state to file.
    val is used to select which passes and functions to dump. For example:
    all matches all passes and functions,
    foo matches all passes for functions whose name contains 'foo',
    foo & ConstProp only the 'ConstProp' pass for function names containing 'foo',
    foo | bar all passes for function names containing 'foo' or 'bar'.
  • -Z dump-mir-dataflow=val in addition to .mir files, create graphviz .dot files with dataflow results (default: no)
  • -Z dump-mir-dir=val the directory the MIR is dumped into (default: mir_dump)
  • -Z dump-mir-exclude-pass-number=val exclude the pass number when dumping MIR (used in tests) (default: no)
  • -Z dump-mir-graphviz=val in addition to .mir files, create graphviz .dot files (default: no)
  • -Z dump-mir-spanview=val in addition to .mir files, create .html files to view spans for all statements (including terminators), only terminator spans, or computed block spans (one span encompassing a block's terminator and all statements).
    • Zalathar: This was added by the original author of coverage instrumentation, as a debugging aid. I haven't used it much myself, but I want to keep it around for now in case it's useful in the future. (But if it ends up not being useful for people working on coverage, then it would become a good candidate for deletion.)
    • Zalathar: (removable?) After trying it out, I've decided that this flag is too limited/buggy to be worth preserving. PR filed as https://github.com/rust-lang/rust/pull/119566.
  • -Z dump-mono-stats=val output statistics about monomorphization collection
  • -Z dump-mono-stats-format=val the format to use for -Z dump-mono-stats (markdown (default) or json)
  • -Z dump-solver-proof-tree=val dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it
    then it defaults to always. If the flag is not specified at all it defaults to on-request.
  • -Z graphviz-dark-mode=val use dark-themed colors in graphviz output (default: no)
  • -Z graphviz-font=val use the given fontname in graphviz output; can be overridden by setting environment variable RUSTC_GRAPHVIZ_FONT (default: Courier, monospace)
  • -Z hir-stats=val print some statistics about AST and HIR (default: no)
  • -Z incremental-info=val print high-level information about incremental reuse (or the lack thereof) (default: no)
  • -Z input-stats=val gather statistics about the input (default: no)
    • nnethercote: removable? could be merged into -Z hir-stats
  • -Z llvm-time-trace=val generate JSON tracing data file from LLVM data (default: no)
  • -Z meta-stats=val gather metadata statistics (default: no)
  • -Z mir-include-spans=val use line numbers relative to the function in mir pretty printing
  • -Z nll-facts=val dump facts from NLL analysis into side files (default: no)
  • -Z nll-facts-dir=val the directory the NLL facts are dumped into (default: nll-facts)
  • -Z perf-stats=val print some performance-related statistics (default: no)
  • -Z print-codegen-stats=val print codegen statistics (default: no)
  • -Z print-fuel=val make rustc print the total optimization fuel used by a crate
  • -Z print-llvm-passes=val print the LLVM optimization passes being run (default: no)
  • -Z print-mono-items=val print the result of the monomorphization collection pass
  • -Z print-type-sizes=val print layout information for each type encountered (default: no)
  • -Z print-vtable-sizes=val print size comparison between old and new vtable layouts (default: no)
  • -Z profile-closures=val profile size of closures
  • -Z show-span=val show spans for compiler debugging (expr|pat|ty)
  • -Z span-free-formats=val exclude spans when debug-printing compiler state (default: no)
  • -Z unpretty=val present the input source, unstable (and less-pretty) variants;
    normal, identified,
    expanded, expanded,identified,
    expanded,hygiene (with internal representations),
    ast-tree (raw AST before expansion),
    ast-tree,expanded (raw AST after expansion),
    hir (the HIR), hir,identified,
    hir,typed (HIR with types for each node),
    hir-tree (dump the raw HIR),
    thir-tree, thir-flat,
    mir (the MIR), or mir-cfg (graphviz formatted MIR)
  • -Z verbose=val in general, enable more debug printouts (default: no)

extra internal checking

  • -Z assert-incr-state=val assert that the incremental cache is in given state: either loaded or not-loaded.
  • -Z incremental-verify-ich=val verify incr. comp. hashes of green query instances (default: no)
  • -Z validate-mir=val validate MIR after each transformation
  • -Z verify-llvm-ir=val verify LLVM IR (default: no)

optimization

  • -Z cross-crate-inline-threshold=val threshold to allow cross crate inlining of functions
  • -Z fuel=val set the optimization fuel quota for a crate
  • -Z inline-llvm=val enable LLVM inlining (default: yes)
  • -Z inline-mir=val enable MIR inlining (default: no)
  • -Z inline-mir-hint-threshold=val inlining threshold for functions with inline hint (default: 100)
  • -Z inline-mir-threshold=val a default MIR inlining threshold (default: 50)
  • -Z llvm-plugins=val a list LLVM plugins to enable (space separated)
  • -Z merge-functions=val control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
  • -Z mir-enable-passes=val use like -Zmir-enable-passes=+DestinationPropagation,-InstSimplify. Forces the specified passes to be enabled, overriding all other checks. In particular, this will enable unsound (known-buggy and hence usually disabled) passes without further warning! Passes that are not specified are enabled or disabled by other flags as usual.
  • -Z mir-opt-level=val MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
  • -Z polymorphize=val perform polymorphization analysis
  • -Z remark-dir=val directory into which to write optimization remarks (if not specified, they will be written to standard error output)
  • -Z unsound-mir-opts=val enable unsound and buggy MIR optimizations (default: no)
  • -Z virtual-function-elimination=val enables dead virtual function elimination optimization. Requires -Clto[=[fat,yes]]
  • -Z unleash-the-miri-inside-of-you=val take the brakes off const evaluation. NOTE: this is unsound (default: no)

codegen

  • -Z asm-comments=val generate comments into the assembly (may change behavior) (default: no)
  • -Z box-noalias=val emit noalias metadata for box (default: yes)
  • -Z branch-protection=val set options for branch target identification and pointer authentication on AArch64
  • -Z cf-protection=val instrument control-flow architecture protection
  • -Z codegen-backend=val the backend to use
  • -Z combine-cgu=val combine CGUs into a single one
  • -Z emit-stack-sizes=val emit a section containing stack size metadata (default: no)
  • -Z export-executable-symbols=val export symbols from executables, as if they were dynamic libraries
  • -Z extra-const-ub-checks=val turns on more checks to detect const UB, which can be slow (default: no)
  • -Z function-sections=val whether each function should go in its own section
  • -Z human-readable-cgu-names=val generate human-readable, predictable names for codegen units (default: no)
  • -Z inline-in-all-cgus=val control whether #[inline] functions are in all CGUs
  • -Z instrument-mcount=val insert function instrument code for mcount-based tracing (default: no)
  • -Z instrument-xray=val insert function instrument code for XRay-based tracing (default: no)
    Optional extra settings:
    =always
    =never
    =ignore-loops
    =instruction-threshold=N
    =skip-entry
    =skip-exit
    Multiple options can be combined with commas.
  • -Z mutable-noalias=val emit noalias metadata for mutable references (default: yes)
  • -Z no-jump-tables=val disable the jump tables and lookup tables that can be generated from a switch case lowering
  • -Z no-trait-vptr=val disable generation of trait vptr in vtable for upcasting
  • -Z no-unique-section-names=val do not use unique names for text and data sections when -Z function-sections is used
  • -Z packed-bundled-libs=val change rlib format to store native libraries as archives
  • -Z plt=val whether to use the PLT when calling into shared libraries;
    only has effect for PIC code on systems with ELF binaries
    (default: PLT is disabled if full relro is enabled on x86_64)
  • -Z precise-enum-drop-elaboration=val use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551.
  • -Z relax-elf-relocations=val whether ELF relocations can be relaxed
  • -Z relro-level=val choose which RELRO level to use
  • -Z saturating-float-casts=val make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes)
  • -Z share-generics=val make the current crate share its generic instantiations
  • -Z stack-protector=val control stack smash protection strategy (rustc --print stack-protector-strategies for details)
  • -Z trap-unreachable=val generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)
  • -Z tune-cpu=val select processor to schedule for (rustc --print target-cpus for details)
  • -Z use-ctors-section=val use legacy .ctors section for initializers rather than .init_array

linking

  • -Z link-directives=val honor #[link] directives in the compiled crate (default: yes)
  • -Z link-native-libraries=val link native libraries in the linker invocation (default: yes)
  • -Z link-only=val link the .rlink file generated by -Z no-link (default: no)
  • -Z osx-rpath-install-name=val pass -install_name @rpath/... to the macOS linker (default: no)
  • -Z pre-link-arg=val a single extra argument to prepend the linker invocation (can be used several times)
    • nnethercote: removable? surely don't need both -Z pre-link-arg and -Z pre-link-args
  • -Z pre-link-args=val extra arguments to prepend to the linker invocation (space separated)
  • -Z staticlib-prefer-dynamic=val prefer dynamic linking to static linking for staticlibs (default: no)
  • -Z strip=val tell the linker which information to strip (none (default), debuginfo or symbols)

early exit

  • -Z no-analysis=val parse and expand the source, but run no analysis
  • -Z no-codegen=val run all passes except codegen; no output
  • -Z no-link=val compile without linking
  • -Z parse-crate-root-only=val parse the crate root file only; do not parse other files, compile, assemble, or link (default: no)

sanitizers

  • -Z sanitizer=val use a sanitizer
  • -Z sanitizer-cfi-canonical-jump-tables=val enable canonical jump tables (default: yes)
  • -Z sanitizer-cfi-generalize-pointers=val enable generalizing pointer types (default: no)
  • -Z sanitizer-cfi-normalize-integers=val enable normalizing integer types (default: no)
  • -Z sanitizer-memory-track-origins=val enable origins tracking in MemorySanitizer
  • -Z sanitizer-recover=val enable recovery for selected sanitizers

testing

  • -Z future-incompat-test=val forces all lints to be future incompatible, used for internal testing (default: no)
  • -Z incremental-ignore-spans=val ignore spans during ICH computation used for testing (default: no)
  • -Z simulate-remapped-rust-src-base=val simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes
  • -Z translate-additional-ftl=val additional fluent translation to preferentially use (for testing translation)
  • -Z ui-testing=val emit compiler diagnostics in a form suitable for UI testing (default: no)
  • -Z no-leak-check=val disable the 'leak check' for subtyping; unsound, but useful for tests
  • -Z query-dep-graph=val enable queries of the dependency graph for regression testing (default: no)
  • -Z tiny-const-eval-limit=val sets a tiny, non-configurable limit for const eval; useful for compiler tests

debug info

  • -Z debug-macros=val emit line numbers debug info inside macros (default: no)
  • -Z debuginfo-compression=val compress debug info sections (none, zlib, zstd, default: none)
  • -Z dwarf-version=val version of DWARF debug information to emit (default: 2 or 4, depending on platform)
  • -Z no-generate-arange-section=val omit DWARF address ranges that give faster lookups
  • -Z split-dwarf-inlining=val provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
    • davidtwco: both of these split dwarf options expose a choice we get from LLVM, but they probably aren't used - there's likely zero ongoing maintainance cost to either of them though
  • -Z split-dwarf-kind=val split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
    (default: split)
    split: sections which do not require relocation are written into a DWARF object (.dwo)
    file which is ignored by the linker
    single: sections which do not require relocation are written into object file but ignored
    by the linker
  • -Z src-hash-algorithm=val hash algorithm of source files in debug info (md5, sha1, or sha256)

metadata and depinfo

  • -Z always-encode-mir=val encode MIR of all functions into the crate metadata (default: no)
  • -Z binary-dep-depinfo=val include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
  • -Z dep-info-omit-d-target=val in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no)
  • -Z ls=val decode and print various parts of the crate metadata for a library crate (space separated)

profiling

  • -Z no-profiler-runtime=val prevent automatic injection of the profiler_builtins crate
    • Zalathar: Very useful for in-tree testing; keep as perma-unstable
  • -Z profile=val insert profiling code (default: no)
  • -Z profile-emit=val file path to emit profiling data at runtime when using 'profile' (default based on relative source path)
    • Being removed in #131829
  • -Z profiler-runtime=val name of the profiler runtime crate to automatically inject (default: profiler_builtins)

AutoFDO

AutoFDO is a form of profile-guided optimization, separate from the compiler's main PGO features. Untested in-tree.

  • -Z debug-info-for-profiling=val emit discriminators and other data necessary for AutoFDO
  • -Z profile-sample-use=val use the given .prof file for sampled profile-guided optimization (also known as AutoFDO)

self-profiling

  • -Z location-detail=val what location details should be tracked when using caller_location, either none, or a comma separated list of location details, for which valid options are file, line, and column (default: file,line,column)
  • -Z self-profile=val run the self profiler and output the raw event data
    • nnethercote: critical for rustc-perf
  • -Z self-profile-counter=val counter used by the self profiler (default: wall-time), one of:
    wall-time (monotonic clock, i.e. std::time::Instant)
    instructions:u (retired instructions, userspace-only)
    instructions-minus-irqs:u (subtracting hardware interrupt counts for extra accuracy)
    • nnethercote: not used by rustc-perf
  • -Z self-profile-events=val specify the events recorded by the self profiler;
    for example: -Z self-profile-events=default,query-keys
    all options: none, all, default, generic-activity, query-provider, query-cache-hit
    query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes
    • nnethercote: critical for rustc-perf
  • -Z time-llvm-passes=val measure time of each LLVM pass (default: no)
  • -Z time-passes=val measure time of each rustc pass (default: no)
    • nnethercote: useful for casual diagnosis of compile-time slowness, even though indenting of sub-passes has long been broken
  • -Z time-passes-format=val the format to use for -Z time-passes (text (default) or json)

diagnostics

  • -Z deduplicate-diagnostics=val deduplicate identical diagnostics (default: yes)
  • -Z dont-buffer-diagnostics=val emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no)
    • nnethercote: removable? what is this for?
    • davidtwco: this option is only used in one place and doesn't seem to do much to actually prevent buffering (which I think we still do and need?) - probably removable
    • Removed in #119723.
  • -Z eagerly-emit-delayed-bugs emit delayed bugs eagerly as errors instead of stashing them and emitting them only if an error has not been emitted"
    • nnethercote: Added in #119872 as a replacement for -Z report-delayed-bugs, because it's a little simpler and more convenient to use
    • nnethercote: useful for debugging, and used in a couple of tests
  • -Z ignore-directory-in-diagnostics-source-blocks=val do not display the source code block in diagnostics for files in the directory
    • nnethercote: Used in src/tools/compiletest to avoid differences when $CARGO_HOME is remapped.
  • -Z report-delayed-bugs=val immediately print bugs registered with delay_span_bug (default: no)
    • nnethercote: Was added in #52568.
    • nnethercote: Removed in #119567.
  • -Z teach=val show extended diagnostic help (default: no)
  • -Z terminal-urls=val use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output
    • Added in #107838.
    • davidtwco: unless there's some intent to stabilize this or have some detection to know when it is appropriate to emit these, I imagine this option just doesn't get used
  • -Z track-diagnostics=val tracks where in rustc a diagnostic was emitted
    • nnethercote: for compiler developers, useful when debugging diagnostics
  • -Z translate-directionality-markers=val emit directionality isolation markers in translated diagnostics
  • -Z translate-lang=val language identifier for diagnostic output
  • -Z treat-err-as-bug=val treat the valth error that occurs as bug (default if not specified: 0 - don't treat errors as bugs. default if specified without a value: 1 - treat the first error as bug)
  • -Z trim-diagnostic-paths=val in diagnostics, use heuristics to shorten paths referring to items
    • nnethercote: defaults to true. Set to false in a few tests, presumably to ensure the full path is correct
  • -Z write-long-types-to-disk=val whether long type names should be written to files instead of being printed in errors

macros

  • -Z dual-proc-macros=val load proc macros for both target and host, but only link to the target (default: no)
  • -Z macro-backtrace=val show macro backtraces (default: no)
  • -Z proc-macro-backtrace=val show backtraces for panics during proc-macro execution (default: no)
  • -Z proc-macro-execution-strategy=val how to run proc-macro code (default: same-thread)
  • -Z span-debug=val forward proc_macro::Span's Debug impl to Span
  • -Z trace-macros=val for every macro invocation, print its name and arguments (default: no)

LTO

  • -Z split-lto-unit=val enable LTO unit splitting (default: no) Stabilize: Required to build Chromium, users shouldn't need a nightly compiler for that.
  • -Z thinlto=val enable ThinLTO when possible
  • -Z dylib-lto=val enables LTO for dylib crate type
  • -Z emit-thin-lto=val emit the bc module with thin LTO info (default: yes)

uncategorized

  • -Z allow-features=val only allow the listed language features to be enabled in code (comma separated)
  • -Z assume-incomplete-release=val make cfg(version) treat the current version as incomplete (default: no)
  • -Z crate-attr=val inject the given attribute in the crate
  • -Z fewer-names=val reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
  • -Z flatten-format-args=val flatten nested format_args!() and literals into a simplified format_args!() call (default: yes)
  • -Z force-unstable-if-unmarked=val force all crates to be rustc_private unstable (default: no)
  • -Z identify-regions=val display unnamed regions as '<id>, using a non-ident unique id (default: no)
  • -Z keep-hygiene-data=val keep hygiene data after analysis (default: no)
  • -Z layout-seed=val seed layout randomization
  • -Z maximal-hir-to-mir-coverage=val save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)
  • -Z mir-emit-retag=val emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
  • -Z mir-keep-place-mention=val keep place mention MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
  • -Z move-size-limit=val the size at which the large_assignments lint starts to be emitted
  • -Z no-parallel-backend=val run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
    • nnethercote: sometimes critically useful for debugging LLVM bugs
  • -Z normalize-docs=val normalize associated items in rustdoc when generating documentation
  • -Z oom=val panic strategy for out-of-memory handling
  • -Z panic-abort-tests=val support compiling tests with panic=abort (default: no)
  • -Z panic-in-drop=val panic strategy for panics in drops
  • -Z polonius=val enable polonius-based borrow-checker (default: no)
  • -Z randomize-layout=val randomize the layout of types (default: no)
  • -Z remap-cwd-prefix=val remap paths under the current working directory to this path prefix
  • -Z remap-path-scope=val remap path scope (default: all)
  • -Z staticlib-allow-rdylib-deps=val allow staticlibs to have rust dylib dependencies
  • -Z strict-init-checks=val control if mem::uninitialized and mem::zeroed panic on more UB
  • -Z temps-dir=val the directory the intermediate files are written to
  • -Z thir-unsafeck=val use the THIR unsafety checker (default: no)
  • -Z threads=val use a thread pool with N threads
    • nnethercote: this name is inaccurate, because it only controls the front-end threads limit. The back-end uses one thread per codegen unit.
  • -Z tls-model=val choose the TLS model to use (rustc --print tls-models for details)
  • -Z trait-solver=val specify the trait solver mode used by rustc (default: classic)
  • -Z translate-remapped-path-to-local-path=val translate remapped paths into local paths when possible (default: yes)
  • -Z uninit-const-chunk-threshold=val allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16)
  • -Z unstable-options=val adds unstable command line options to rustc interface (default: no)
  • -Z wasi-exec-model=val whether to build a wasi command or reactor
Select a repo