@@ -429,6 +429,35 @@ impl LinkerFeaturesCli {
429429 _ => None ,
430430 }
431431 }
432+
433+ /// Checks usage of unstable variants for linker features for the given `target_tuple`.
434+ /// Returns `Ok` if no unstable variants are used.
435+ pub ( crate ) fn check_unstable_variants ( & self , target_tuple : & TargetTuple ) -> Result < ( ) , String > {
436+ let mentioned_features = self . enabled . union ( self . disabled ) ;
437+ let has_lld = mentioned_features. is_lld_enabled ( ) ;
438+
439+ // Check that -Clinker-features=[-+]lld is not used anywhere else than on x64
440+ // without -Zunstable-options.
441+ if has_lld && target_tuple. tuple ( ) != "x86_64-unknown-linux-gnu" {
442+ return Err ( format ! (
443+ "`-C linker-features` with lld are unstable for the `{target_tuple} target, ` \
444+ the `-Z unstable-options` flag must also be passed to use it on this target",
445+ ) ) ;
446+ }
447+
448+ for feature in LinkerFeatures :: all ( ) {
449+ // Check that no other features were enabled without -Zunstable-options
450+ // Note that this should currently be unreachable, because the `-Clinker-features` parser
451+ // currently only accepts lld.
452+ if feature != LinkerFeatures :: LLD && mentioned_features. contains ( feature) {
453+ return Err ( "`-C linker-features` is stable only for the lld feature, \
454+ the`-Z unstable-options` flag must also be passed to use it with other features"
455+ . to_string ( ) ) ;
456+ }
457+ }
458+
459+ Ok ( ( ) )
460+ }
432461}
433462
434463/// Used with `-Z assert-incr-state`.
@@ -2472,9 +2501,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
24722501 }
24732502 }
24742503
2475- if !nightly_options:: is_unstable_enabled ( matches)
2476- && cg. force_frame_pointers == FramePointer :: NonLeaf
2477- {
2504+ let unstable_options_enabled = nightly_options:: is_unstable_enabled ( matches) ;
2505+ if !unstable_options_enabled && cg. force_frame_pointers == FramePointer :: NonLeaf {
24782506 early_dcx. early_fatal (
24792507 "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
24802508 and a nightly compiler",
@@ -2484,7 +2512,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
24842512 // For testing purposes, until we have more feedback about these options: ensure `-Z
24852513 // unstable-options` is required when using the unstable `-C link-self-contained` and `-C
24862514 // linker-flavor` options.
2487- if !nightly_options :: is_unstable_enabled ( matches ) {
2515+ if !unstable_options_enabled {
24882516 let uses_unstable_self_contained_option =
24892517 cg. link_self_contained . are_unstable_variants_set ( ) ;
24902518 if uses_unstable_self_contained_option {
@@ -2532,6 +2560,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
25322560 let debuginfo = select_debuginfo ( matches, & cg) ;
25332561 let debuginfo_compression = unstable_opts. debuginfo_compression ;
25342562
2563+ if !unstable_options_enabled {
2564+ if let Err ( error) = cg. linker_features . check_unstable_variants ( & target_triple) {
2565+ early_dcx. early_fatal ( error) ;
2566+ }
2567+ }
2568+
25352569 let crate_name = matches. opt_str ( "crate-name" ) ;
25362570 let unstable_features = UnstableFeatures :: from_environment ( crate_name. as_deref ( ) ) ;
25372571 // Parse any `-l` flags, which link to native libraries.
0 commit comments