@@ -370,12 +370,34 @@ impl LinkSelfContained {
370370    } 
371371
372372    /// To help checking CLI usage while some of the values are unstable: returns whether one of the 
373-      /// components was set individually. This would also require the `-Zunstable-options` flag, to 
374-      /// be allowed. 
375-      fn  are_unstable_variants_set ( & self )  -> bool  { 
376-         let  any_component_set =
377-             !self . enabled_components . is_empty ( )  || !self . disabled_components . is_empty ( ) ; 
378-         self . explicitly_set . is_none ( )  && any_component_set
373+      /// unstable components was set individually, for the given `TargetTuple`. This would also 
374+      /// require the `-Zunstable-options` flag, to be allowed. 
375+      fn  check_unstable_variants ( & self ,  target_tuple :  & TargetTuple )  -> Result < ( ) ,  String >  { 
376+         if  self . explicitly_set . is_some ( )  { 
377+             return  Ok ( ( ) ) ; 
378+         } 
379+ 
380+         // `-C link-self-contained=-linker` is only stable on x64 linux. 
381+         let  has_minus_linker = self . disabled_components . is_linker_enabled ( ) ; 
382+         if  has_minus_linker && target_tuple. tuple ( )  != "x86_64-unknown-linux-gnu"  { 
383+             return  Err ( format ! ( 
384+                 "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \  
385+                      target. The `-Z unstable-options` flag must also be passed to use it on this target", 
386+             ) ) ; 
387+         } 
388+ 
389+         // Any `+linker` or other component used is unstable, and that's an error. 
390+         let  unstable_enabled = self . enabled_components ; 
391+         let  unstable_disabled = self . disabled_components  - LinkSelfContainedComponents :: LINKER ; 
392+         if  !unstable_enabled. union ( unstable_disabled) . is_empty ( )  { 
393+             return  Err ( String :: from ( 
394+                 "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \  
395+                  are stable, the `-Z unstable-options` flag must also be passed to use \ 
396+                  the unstable values", 
397+             ) ) ; 
398+         } 
399+ 
400+         Ok ( ( ) ) 
379401    } 
380402
381403    /// Returns whether the self-contained linker component was enabled on the CLI, using the 
@@ -402,7 +424,7 @@ impl LinkSelfContained {
402424    } 
403425} 
404426
405- /// The different values that `-Z  linker-features` can take on the CLI: a list of individually 
427+ /// The different values that `-C  linker-features` can take on the CLI: a list of individually 
406428/// enabled or disabled features used during linking. 
407429/// 
408430/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be 
@@ -442,6 +464,39 @@ impl LinkerFeaturesCli {
442464            _ => None , 
443465        } 
444466    } 
467+ 
468+     /// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are 
469+      /// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used. 
470+      /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()` 
471+      /// returns false. 
472+      pub ( crate )  fn  check_unstable_variants ( & self ,  target_tuple :  & TargetTuple )  -> Result < ( ) ,  String >  { 
473+         // `-C linker-features=-lld` is only stable on x64 linux. 
474+         let  has_minus_lld = self . disabled . is_lld_enabled ( ) ; 
475+         if  has_minus_lld && target_tuple. tuple ( )  != "x86_64-unknown-linux-gnu"  { 
476+             return  Err ( format ! ( 
477+                 "`-C linker-features=-lld` is unstable on the `{target_tuple}` \  
478+                      target. The `-Z unstable-options` flag must also be passed to use it on this target", 
479+             ) ) ; 
480+         } 
481+ 
482+         // Any `+lld` or non-lld feature used is unstable, and that's an error. 
483+         let  unstable_enabled = self . enabled ; 
484+         let  unstable_disabled = self . disabled  - LinkerFeatures :: LLD ; 
485+         if  !unstable_enabled. union ( unstable_disabled) . is_empty ( )  { 
486+             let  unstable_features:  Vec < _ >  = unstable_enabled
487+                 . iter ( ) 
488+                 . map ( |f| format ! ( "+{}" ,  f. as_str( ) . unwrap( ) ) ) 
489+                 . chain ( unstable_disabled. iter ( ) . map ( |f| format ! ( "-{}" ,  f. as_str( ) . unwrap( ) ) ) ) 
490+                 . collect ( ) ; 
491+             return  Err ( format ! ( 
492+                 "`-C linker-features={}` is unstable, and also requires the \  
493+                  `-Z unstable-options` flag to be used", 
494+                 unstable_features. join( "," ) , 
495+             ) ) ; 
496+         } 
497+ 
498+         Ok ( ( ) ) 
499+     } 
445500} 
446501
447502/// Used with `-Z assert-incr-state`. 
@@ -2638,26 +2693,21 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
26382693        } 
26392694    } 
26402695
2641-     if  !nightly_options:: is_unstable_enabled ( matches) 
2642-         && cg. force_frame_pointers  == FramePointer :: NonLeaf 
2643-     { 
2696+     let  unstable_options_enabled = nightly_options:: is_unstable_enabled ( matches) ; 
2697+     if  !unstable_options_enabled && cg. force_frame_pointers  == FramePointer :: NonLeaf  { 
26442698        early_dcx. early_fatal ( 
26452699            "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \  
26462700                 and a nightly compiler", 
26472701        ) 
26482702    } 
26492703
2650-     // For testing purposes, until we have more feedback about these options: ensure `-Z 
2651-     // unstable-options` is required when using the unstable `-C link-self-contained` and `-C 
2652-     // linker-flavor` options. 
2653-     if  !nightly_options:: is_unstable_enabled ( matches)  { 
2654-         let  uses_unstable_self_contained_option =
2655-             cg. link_self_contained . are_unstable_variants_set ( ) ; 
2656-         if  uses_unstable_self_contained_option { 
2657-             early_dcx. early_fatal ( 
2658-                 "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \  
2659-                  the `-Z unstable-options` flag must also be passed to use the unstable values", 
2660-             ) ; 
2704+     let  target_triple = parse_target_triple ( early_dcx,  matches) ; 
2705+ 
2706+     // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and 
2707+     // `-C linker-flavor` options. 
2708+     if  !unstable_options_enabled { 
2709+         if  let  Err ( error)  = cg. link_self_contained . check_unstable_variants ( & target_triple)  { 
2710+             early_dcx. early_fatal ( error) ; 
26612711        } 
26622712
26632713        if  let  Some ( flavor)  = cg. linker_flavor  { 
@@ -2697,7 +2747,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
26972747
26982748    let  cg = cg; 
26992749
2700-     let  target_triple = parse_target_triple ( early_dcx,  matches) ; 
27012750    let  opt_level = parse_opt_level ( early_dcx,  matches,  & cg) ; 
27022751    // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able 
27032752    // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`) 
@@ -2706,6 +2755,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
27062755    let  debuginfo = select_debuginfo ( matches,  & cg) ; 
27072756    let  debuginfo_compression = unstable_opts. debuginfo_compression ; 
27082757
2758+     if  !unstable_options_enabled { 
2759+         if  let  Err ( error)  = cg. linker_features . check_unstable_variants ( & target_triple)  { 
2760+             early_dcx. early_fatal ( error) ; 
2761+         } 
2762+     } 
2763+ 
27092764    let  crate_name = matches. opt_str ( "crate-name" ) ; 
27102765    let  unstable_features = UnstableFeatures :: from_environment ( crate_name. as_deref ( ) ) ; 
27112766    // Parse any `-l` flags, which link to native libraries. 
0 commit comments