diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 16b4d26b37b4b..804b86cd864cb 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -77,6 +77,15 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { modifier `-bundle` with library kind `static`", ) .emit(); + if !self.tcx.features().static_nobundle { + feature_err( + &self.tcx.sess.parse_sess, + sym::static_nobundle, + item.span(), + "kind=\"static-nobundle\" is unstable", + ) + .emit(); + } NativeLibKind::Static { bundle: Some(false), whole_archive: None } } "dylib" => NativeLibKind::Dylib { as_needed: None }, @@ -252,17 +261,6 @@ impl Collector<'tcx> { ) .emit(); } - if matches!(lib.kind, NativeLibKind::Static { bundle: Some(false), .. }) - && !self.tcx.features().static_nobundle - { - feature_err( - &self.tcx.sess.parse_sess, - sym::static_nobundle, - span.unwrap_or(rustc_span::DUMMY_SP), - "kind=\"static-nobundle\" is unstable", - ) - .emit(); - } // this just unwraps lib.name; we already established that it isn't empty above. if let (NativeLibKind::RawDylib, Some(lib_name)) = (lib.kind, lib.name) { let span = match span { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index ebf4b2b01c568..96d896cb9e1da 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1609,8 +1609,20 @@ fn select_debuginfo( } } -fn parse_native_lib_kind(kind: &str, error_format: ErrorOutputType) -> NativeLibKind { - match kind { +fn parse_native_lib_kind( + matches: &getopts::Matches, + kind: &str, + error_format: ErrorOutputType, +) -> (NativeLibKind, Option) { + let is_nightly = nightly_options::match_is_nightly_build(matches); + let enable_unstable = nightly_options::is_unstable_enabled(matches); + + let (kind, modifiers) = match kind.split_once(':') { + None => (kind, None), + Some((kind, modifiers)) => (kind, Some(modifiers)), + }; + + let kind = match kind { "dylib" => NativeLibKind::Dylib { as_needed: None }, "framework" => NativeLibKind::Framework { as_needed: None }, "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, @@ -1620,17 +1632,49 @@ fn parse_native_lib_kind(kind: &str, error_format: ErrorOutputType) -> NativeLib "library kind `static-nobundle` has been superseded by specifying \ `-bundle` on library kind `static`. Try `static:-bundle`", ); + if modifiers.is_some() { + early_error( + error_format, + "linking modifier can't be used with library kind `static-nobundle`", + ) + } + if !is_nightly { + early_error( + error_format, + "library kind `static-nobundle` are currently unstable and only accepted on \ + the nightly compiler", + ); + } NativeLibKind::Static { bundle: Some(false), whole_archive: None } } s => early_error( error_format, &format!("unknown library kind `{}`, expected one of dylib, framework, or static", s), ), + }; + match modifiers { + None => (kind, None), + Some(modifiers) => { + if !is_nightly { + early_error( + error_format, + "linking modifiers are currently unstable and only accepted on \ + the nightly compiler", + ); + } + if !enable_unstable { + early_error( + error_format, + "linking modifiers are currently unstable, \ + the `-Z unstable-options` flag must also be passed to use it", + ) + } + parse_native_lib_modifiers(kind, modifiers, error_format) + } } } fn parse_native_lib_modifiers( - is_nightly: bool, mut kind: NativeLibKind, modifiers: &str, error_format: ErrorOutputType, @@ -1646,14 +1690,6 @@ fn parse_native_lib_modifiers( ), }; - if !is_nightly { - early_error( - error_format, - "linking modifiers are currently unstable and only accepted on \ - the nightly compiler", - ); - } - match (modifier, &mut kind) { ("bundle", NativeLibKind::Static { bundle, .. }) => { *bundle = Some(value); @@ -1700,7 +1736,6 @@ fn parse_native_lib_modifiers( } fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec { - let is_nightly = nightly_options::match_is_nightly_build(matches); matches .opt_strs("l") .into_iter() @@ -1714,13 +1749,7 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec< let (name, kind, verbatim) = match s.split_once('=') { None => (s, NativeLibKind::Unspecified, None), Some((kind, name)) => { - let (kind, verbatim) = match kind.split_once(':') { - None => (parse_native_lib_kind(kind, error_format), None), - Some((kind, modifiers)) => { - let kind = parse_native_lib_kind(kind, error_format); - parse_native_lib_modifiers(is_nightly, kind, modifiers, error_format) - } - }; + let (kind, verbatim) = parse_native_lib_kind(matches, kind, error_format); (name.to_string(), kind, verbatim) } }; diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs new file mode 100644 index 0000000000000..1b5fa78ee5521 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-2.rs @@ -0,0 +1,10 @@ +// Test native_link_modifiers_bundle don't need static-nobundle +// check-pass + +#![feature(native_link_modifiers)] +#![feature(native_link_modifiers_bundle)] + +#[link(name = "foo", kind = "static", modifiers = "-bundle")] +extern "C" {} + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.rs new file mode 100644 index 0000000000000..3da943ee4a963 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.rs @@ -0,0 +1,3 @@ +// compile-flags: -l static:-bundle=nonexistent + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr new file mode 100644 index 0000000000000..86ccb4e860b69 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_bundle-3.stderr @@ -0,0 +1,2 @@ +error: linking modifiers are currently unstable, the `-Z unstable-options` flag must also be passed to use it + diff --git a/src/test/ui/feature-gates/feature-gate-static-nobundle-2.rs b/src/test/ui/feature-gates/feature-gate-static-nobundle-2.rs index b6c8648a7d03d..ad0662b6892d2 100644 --- a/src/test/ui/feature-gates/feature-gate-static-nobundle-2.rs +++ b/src/test/ui/feature-gates/feature-gate-static-nobundle-2.rs @@ -1,6 +1,4 @@ -//~ ERROR kind="static-nobundle" is unstable -// Test the behavior of rustc when non-existent library is statically linked - +// check-pass // compile-flags: -l static-nobundle=nonexistent fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-static-nobundle-2.stderr b/src/test/ui/feature-gates/feature-gate-static-nobundle-2.stderr index 301a1e1341eed..76c317f741012 100644 --- a/src/test/ui/feature-gates/feature-gate-static-nobundle-2.stderr +++ b/src/test/ui/feature-gates/feature-gate-static-nobundle-2.stderr @@ -1,10 +1,2 @@ warning: library kind `static-nobundle` has been superseded by specifying `-bundle` on library kind `static`. Try `static:-bundle` -error[E0658]: kind="static-nobundle" is unstable - | - = note: see issue #37403 for more information - = help: add `#![feature(static_nobundle)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr b/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr index 9695618207cc9..eaf2e0db51110 100644 --- a/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr +++ b/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr @@ -5,10 +5,10 @@ LL | #[link(name = "foo", kind = "static-nobundle")] | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0658]: kind="static-nobundle" is unstable - --> $DIR/feature-gate-static-nobundle.rs:1:1 + --> $DIR/feature-gate-static-nobundle.rs:1:22 | LL | #[link(name = "foo", kind = "static-nobundle")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #37403 for more information = help: add `#![feature(static_nobundle)]` to the crate attributes to enable