Skip to content

sess: target modifiers under -T - #160167

Draft
davidtwco wants to merge 27 commits into
rust-lang:mainfrom
davidtwco:target-modifier-group
Draft

sess: target modifiers under -T#160167
davidtwco wants to merge 27 commits into
rust-lang:mainfrom
davidtwco:target-modifier-group

Conversation

@davidtwco

Copy link
Copy Markdown
Member

cc rust-lang/compiler-team#980 (#t-compiler/major changes > group target modifier options under `-T` compiler-team#980)

This patch re-implements target modifiers so that they are grouped under -T instead of being regular flags.

The current implementation is quite complex, using lots of macro_rules!s to filter out the target modifier options from the rest of the codegen options, and then storing the original string values of the target modifiers in cross-crate metadata before re-parsing them again in the downstream crate. Some of this complexity is desirable - we don't want to store every option value in the cross-crate metadata because that would hurt compile times. This patch removes the current approach entirely and starts again, leveraging simplifications made possible by the -T design.

  • The first commit (f283869) removes the existing target modifier infrastructure
  • The second commit (1f5aba5) is a small renaming
  • The next set of commits (3b95e08..208adfc) implements group target modifier options under -T compiler-team#980
    • A new TargetOptions struct is introduced that is parsed from -T and target modifier options are moved to it
    • TargetOptions is serialised in its entirety into cross-crate metadata, which is a lot simpler and isn't storing any more information than necessary
    • Local crate-only tracking of whether an option was actually set by the user is introduced, which is necessary to reproduce the previous diagnostics
    • Options can be set as TRACKED_UNSTABLE to require that -Zunstable-options be provided if they are used - all current target modifiers are unstable so this is used for all of them
    • Sanitizers are in both -T and -Z, with only address and leak being in -Z and everything else being in -T w/ -Zunstable-options
    • -Ttarget-cpu is required for targets with TargetOptions::requires_consistent_cpu, otherwise -Ctarget-cpu remains usable
    • -T itself is insta-stable, but all the options under are unstable, so it's effectively unstable
  • The final set of commits (090db9c..c87f767) implements @Darksonn's suggestion from #t-compiler > Using -T for target modifiers and forwards compatibility @ 💬
    • tl;dr all -C options can also be used as -T options
      • We can remove these commits if we decide that we don't actually want to go this route, but I figured I'd try implement it
    • TargetOptions is removed again and target modifier options are now moved into CodegenOptions (they're still unstable thanks to the aforementioned TRACKED_UNSTABLE)
    • CodegenOptions is parsed from both -C and -T
      • -T takes precedence
    • Options can optionally be marked as TargetModifierFilter::Only (only -T, no -C) or TargetModifierFilter::Never (only -C, no -T)
    • -T option values are stored into a FxHashMap, these are stored into cross-crate metadata so we know which options were set as target modifiers in dependencies and we only store those that were set with -T
      • This hashmap is keyed by an CodegenOptionsKey enum that has a variant for each option
      • This hashmap's values are a TargetModifierValue type that contains variants for each distinct value type of the options we support as being target modifiers
        • Any option value types that TargetModifierValue doesn't support should be marked as never-target-modifiers, I haven't done that yet and rustc will ICE if you use them with -T
        • TargetModifierValue was introduced as an attempt to try and keep cross-crate metadata size down - avoiding Box<dyn Any> or storing strings for every option
    • -T is insta-stable for any of the currently stable -C options

To-do:

  • -Zsanitizers-cfi-normalize-integers was previously only a target modifier for -Zsanitizers=kcfi, not -Zsanitizers=cfi, but it is now a target modifier for both
  • Which version of the patch do we want?
  • (for the interchangeable -C/-T version) Which options should never be usable as target modifiers? Options related to linking or file paths?

Opening this as a draft as there are clearly some questions to resolve above.

davidtwco added 27 commits July 29, 2026 14:59
The existing implementation of target modifiers is quite complicated and
hard to work with because it relies so heavily on macros. To some extent,
this is unavoidable because only a subset of the `UnstableOptions` or
`CodegenOptions` flags are target modifiers and so it needs to filter
for those. A simpler implementation will be possible given the additional
constraint that all target modifier options are in the same group.
A small refactoring just to give each of these meta-variables better
names.
Reporting good target modifier mismatch errors will require at least
knowing whether a option was set by the user explicitly rather than just
having its default value. This small addition to the infrastructure
enables that to be tracked. It is not persisted into the cross-crate
metadata, it will only be required in the local crate.
Introduces a new implementation of target modifiers under the `-T`
prefix, leveraging that all of the options are in the one struct so that
the whole type can just be encoded or decoded to keep track of the
values set in downstream crates.

The term "target modifiers" is leaked, not just "target flags" because
`--target` is already used (unsurprisingly!).
Introduce a generic mechanism for requiring `-Zunstable-options` on
flags so this doesn't need to be checked per-flag manually.
Introduces a new trait to control printing of the values of target
modifier options in the target modifier diagnostics.
This additional argument will be used in a future commit to allow some
flags to accept arguments on when used as target modifiers (once flags
can be both `-T` and `-C`).
Another big refactoring making all codegen flags both `-T` target
modifiers and `-C` regular codegen flags, and enforcing that values match
only when a flag is given as `-T`.

Flags can be required to be target modifiers, optionally be target
modifiers, or never be target modifiers.

This commit no longer stores the entire `TargetOpts` struct, which no
longer exists in metadata. Instead, produce a map from a new key enum
(with one variant for each option) to the value set with `-T` and store
that map. Values are converted to a `TargetModifierValue` type that
stores only the types that target-modifier-compatible options - this is
hypothetically better than `Box<dyn Any>` that is not encodable and is
large, or storing all of the option values.
Re-using the key enum that was introduced in the previous commit to track
options being set using a `HashSet` rather than a new struct with boolean
fields.
@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-run-make Area: port run-make Makefiles to rmake.rs PG-exploit-mitigations Project group: Exploit mitigations labels Jul 29, 2026
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jul 29, 2026
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
    Checking rustc_codegen_gcc v0.1.0 (/checkout/compiler/rustc_codegen_gcc)
error[E0609]: no field `regparm` on type `UnstableOptions`
   --> compiler/rustc_codegen_gcc/src/context.rs:535:55
    |
535 |             regparm: self.tcx.sess.opts.unstable_opts.regparm,
    |                                                       ^^^^^^^ unknown field
    |
    = note: available fields are: `allow_features`, `allow_partial_mitigations`, `always_encode_mir`, `annotate_moves`, `assert_incr_state` ... and 95 others

error[E0609]: no field `reg_struct_return` on type `UnstableOptions`
   --> compiler/rustc_codegen_gcc/src/context.rs:536:65
    |
536 |             reg_struct_return: self.tcx.sess.opts.unstable_opts.reg_struct_return,
    |                                                                 ^^^^^^^^^^^^^^^^^ unknown field
    |
    = note: available fields are: `allow_features`, `allow_partial_mitigations`, `always_encode_mir`, `annotate_moves`, `assert_incr_state` ... and 95 others

For more information about this error, try `rustc --explain E0609`.
[RUSTC-TIMING] rustc_codegen_gcc test:false 1.204
error: could not compile `rustc_codegen_gcc` (lib) due to 2 previous errors
Bootstrap failed while executing `check`

@rust-bors

rust-bors Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #160190) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-run-make Area: port run-make Makefiles to rmake.rs PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants