owned this note
owned this note
Published
Linked with GitHub
# `-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 `statement`s (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)
- nnethercote: Should really be called `-Z ast-hir-stats`
- `-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)~~
- nnethercote: removed in https://github.com/rust-lang/rust/pull/117773
- `-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
- wesleywiser: https://github.com/rust-lang/rust/pull/115293 is removing this along with `-Zfuel`
- `-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)
- Added in [#112400](https://github.com/rust-lang/rust/pull/112400)
- `-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)
- May be renamed by https://github.com/rust-lang/compiler-team/issues/706
## 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
- davidtwco: there's a PR open to remove this: https://github.com/rust-lang/rust/pull/115293
- `-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`)~~
- nnethercote: was removed by https://github.com/rust-lang/rust/pull/117734
## 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-only=val` -- parse only; do not 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 debug-info-for-profiling=val` -- emit discriminators and other data necessary for AutoFDO
- `-Z no-profiler-runtime=val` -- prevent automatic injection of the profiler_builtins crate
- `-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)
- `-Z profile-sample-use=val` -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)
- `-Z profiler-runtime=val` -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)
## 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](https://github.com/rust-lang/rust/pull/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](https://github.com/rust-lang/rust/pull/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](https://github.com/rust-lang/rust/pull/52568).
- nnethercote: Removed in [#119567](https://github.com/rust-lang/rust/pull/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](https://github.com/rust-lang/rust/pull/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 `val`th 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)
- `-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)~~
- nnethercote: was removed in https://github.com/rust-lang/rust/pull/117737
- `-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-llvm=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