diff options
Diffstat (limited to 'compiler/rustc_session/src')
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 99 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config/cfg.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_session/src/parse.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_session/src/session.rs | 9 |
5 files changed, 128 insertions, 26 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7f2f5f1c5a4..d6215e1de04 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -370,12 +370,34 @@ impl LinkSelfContained { } /// To help checking CLI usage while some of the values are unstable: returns whether one of the - /// components was set individually. This would also require the `-Zunstable-options` flag, to - /// be allowed. - fn are_unstable_variants_set(&self) -> bool { - let any_component_set = - !self.enabled_components.is_empty() || !self.disabled_components.is_empty(); - self.explicitly_set.is_none() && any_component_set + /// unstable components was set individually, for the given `TargetTuple`. This would also + /// require the `-Zunstable-options` flag, to be allowed. + fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> { + if self.explicitly_set.is_some() { + return Ok(()); + } + + // `-C link-self-contained=-linker` is only stable on x64 linux. + let has_minus_linker = self.disabled_components.is_linker_enabled(); + if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + return Err(format!( + "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \ + target. The `-Z unstable-options` flag must also be passed to use it on this target", + )); + } + + // Any `+linker` or other component used is unstable, and that's an error. + let unstable_enabled = self.enabled_components; + let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER; + if !unstable_enabled.union(unstable_disabled).is_empty() { + return Err(String::from( + "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \ + are stable, the `-Z unstable-options` flag must also be passed to use \ + the unstable values", + )); + } + + Ok(()) } /// Returns whether the self-contained linker component was enabled on the CLI, using the @@ -402,7 +424,7 @@ impl LinkSelfContained { } } -/// The different values that `-Z linker-features` can take on the CLI: a list of individually +/// The different values that `-C linker-features` can take on the CLI: a list of individually /// enabled or disabled features used during linking. /// /// 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 { _ => None, } } + + /// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are + /// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used. + /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()` + /// returns false. + pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> { + // `-C linker-features=-lld` is only stable on x64 linux. + let has_minus_lld = self.disabled.is_lld_enabled(); + if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + return Err(format!( + "`-C linker-features=-lld` is unstable on the `{target_tuple}` \ + target. The `-Z unstable-options` flag must also be passed to use it on this target", + )); + } + + // Any `+lld` or non-lld feature used is unstable, and that's an error. + let unstable_enabled = self.enabled; + let unstable_disabled = self.disabled - LinkerFeatures::LLD; + if !unstable_enabled.union(unstable_disabled).is_empty() { + let unstable_features: Vec<_> = unstable_enabled + .iter() + .map(|f| format!("+{}", f.as_str().unwrap())) + .chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap()))) + .collect(); + return Err(format!( + "`-C linker-features={}` is unstable, and also requires the \ + `-Z unstable-options` flag to be used", + unstable_features.join(","), + )); + } + + Ok(()) + } } /// Used with `-Z assert-incr-state`. @@ -2643,26 +2698,21 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M } } - if !nightly_options::is_unstable_enabled(matches) - && cg.force_frame_pointers == FramePointer::NonLeaf - { + let unstable_options_enabled = nightly_options::is_unstable_enabled(matches); + if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf { early_dcx.early_fatal( "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \ and a nightly compiler", ) } - // For testing purposes, until we have more feedback about these options: ensure `-Z - // unstable-options` is required when using the unstable `-C link-self-contained` and `-C - // linker-flavor` options. - if !nightly_options::is_unstable_enabled(matches) { - let uses_unstable_self_contained_option = - cg.link_self_contained.are_unstable_variants_set(); - if uses_unstable_self_contained_option { - early_dcx.early_fatal( - "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \ - the `-Z unstable-options` flag must also be passed to use the unstable values", - ); + let target_triple = parse_target_triple(early_dcx, matches); + + // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and + // `-C linker-flavor` options. + if !unstable_options_enabled { + if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) { + early_dcx.early_fatal(error); } if let Some(flavor) = cg.linker_flavor { @@ -2702,7 +2752,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let cg = cg; - let target_triple = parse_target_triple(early_dcx, matches); let opt_level = parse_opt_level(early_dcx, matches, &cg); // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`) @@ -2711,6 +2760,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let debuginfo = select_debuginfo(matches, &cg); let debuginfo_compression = unstable_opts.debuginfo_compression; + if !unstable_options_enabled { + if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) { + early_dcx.early_fatal(error); + } + } + let crate_name = matches.opt_str("crate-name"); let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); // Parse any `-l` flags, which link to native libraries. diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index cbfe9e0da6a..62891eb4f26 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -278,7 +278,7 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { }; insert_atomic(sym::integer(i), align); if sess.target.pointer_width as u64 == i { - insert_atomic(sym::ptr, layout.pointer_align.abi); + insert_atomic(sym::ptr, layout.pointer_align().abi); } } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index ecd82c0cc01..626262c8442 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2015,6 +2015,8 @@ options! { on a C toolchain or linker installed in the system"), linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED], "system linker to link outputs with"), + linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED], + "a comma-separated list of linker features to enable (+) or disable (-): `lld`"), linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED], "linker flavor"), linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, @@ -2307,8 +2309,6 @@ options! { "link native libraries in the linker invocation (default: yes)"), link_only: bool = (false, parse_bool, [TRACKED], "link the `.rlink` file generated by `-Z no-link` (default: no)"), - linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED], - "a comma-separated list of linker features to enable (+) or disable (-): `lld`"), lint_llvm_ir: bool = (false, parse_bool, [TRACKED], "lint LLVM IR (default: no)"), lint_mir: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 0118cdb1fc2..9097b27b86c 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -205,6 +205,46 @@ pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>( } } +/// This is only used by unstable_feature_bound as it does not have issue number information for now. +/// This is basically the same as `feature_err_issue` +/// but without the feature issue note. If we can do a lookup for issue number from feature name, +/// then we should directly use `feature_err_issue` for ambiguity error of +/// `#[unstable_feature_bound]`. +#[track_caller] +pub fn feature_err_unstable_feature_bound( + sess: &Session, + feature: Symbol, + span: impl Into<MultiSpan>, + explain: impl Into<DiagMessage>, +) -> Diag<'_> { + let span = span.into(); + + // Cancel an earlier warning for this same error, if it exists. + if let Some(span) = span.primary_span() { + if let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning) { + err.cancel() + } + } + + let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() }); + + // #23973: do not suggest `#![feature(...)]` if we are in beta/stable + if sess.psess.unstable_features.is_nightly_build() { + err.subdiagnostic(FeatureDiagnosticHelp { feature }); + + if feature == sym::rustc_attrs { + // We're unlikely to stabilize something out of `rustc_attrs` + // without at least renaming it, so pointing out how old + // the compiler is will do little good. + } else if sess.opts.unstable_opts.ui_testing { + err.subdiagnostic(SuggestUpgradeCompiler::ui_testing()); + } else if let Some(suggestion) = SuggestUpgradeCompiler::new() { + err.subdiagnostic(suggestion); + } + } + err +} + /// Info about a parsing session. pub struct ParseSess { dcx: DiagCtxt, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 8386fe8dab0..85bd8340c3c 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -776,8 +776,15 @@ impl Session { pub fn must_emit_unwind_tables(&self) -> bool { // This is used to control the emission of the `uwtable` attribute on - // LLVM functions. + // LLVM functions. The `uwtable` attribute according to LLVM is: // + // This attribute indicates that the ABI being targeted requires that an + // unwind table entry be produced for this function even if we can show + // that no exceptions passes by it. This is normally the case for the + // ELF x86-64 abi, but it can be disabled for some compilation units. + // + // Typically when we're compiling with `-C panic=abort` we don't need + // `uwtable` because we can't generate any exceptions! // Unwind tables are needed when compiling with `-C panic=unwind`, but // LLVM won't omit unwind tables unless the function is also marked as // `nounwind`, so users are allowed to disable `uwtable` emission. |
