}
}
- // Check for unstable modifiers on `#[link(..)]` attribute
- if attr.has_name(sym::link) {
- for nested_meta in attr.meta_item_list().unwrap_or_default() {
- if nested_meta.has_name(sym::modifiers) {
- if let Some(modifiers) = nested_meta.value_str() {
- for modifier in modifiers.as_str().split(',') {
- if let Some(modifier) = modifier.strip_prefix(&['+', '-']) {
- macro_rules! gate_modifier { ($($name:literal => $feature:ident)*) => {
- $(if modifier == $name {
- let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable");
- gate_feature_post!(
- self,
- $feature,
- nested_meta.name_value_literal_span().unwrap(),
- msg
- );
- })*
- }}
-
- gate_modifier!(
- "bundle" => native_link_modifiers_bundle
- "verbatim" => native_link_modifiers_verbatim
- "as-needed" => native_link_modifiers_as_needed
- );
- }
- }
- }
- }
- }
- }
-
// Emit errors for non-staged-api crates.
if !self.features.staged_api {
if attr.has_name(sym::rustc_deprecated)
+Some linking kinds are target-specific and not supported on all platforms.
+
Linking with `kind=framework` is only supported when targeting macOS,
as frameworks are specific to that operating system.
+Similarly, `kind=raw-dylib` is only supported when targeting Windows-like
+platforms.
+
Erroneous code example:
```ignore (should-compile_fail-but-cannot-doctest-conditionally-without-macos)
* static
* dylib
* framework
+* raw-dylib
/// Returns true if we increased the number of elements present.
pub fn insert_range(&mut self, range: impl RangeBounds<I> + Clone) -> bool {
let start = inclusive_start(range.clone());
- let Some(mut end) = inclusive_end(self.domain, range) else {
+ let Some(end) = inclusive_end(self.domain, range) else {
// empty range
return false;
};
return false;
}
- loop {
- // This condition looks a bit weird, but actually makes sense.
- //
- // if r.0 == end + 1, then we're actually adjacent, so we want to
- // continue to the next range. We're looking here for the first
- // range which starts *non-adjacently* to our end.
- let next = self.map.partition_point(|r| r.0 <= end + 1);
- if let Some(last) = next.checked_sub(1) {
- let (prev_start, prev_end) = &mut self.map[last];
- if *prev_end + 1 >= start {
- // If the start for the inserted range is adjacent to the
- // end of the previous, we can extend the previous range.
- if start < *prev_start {
- // Our range starts before the one we found. We'll need
- // to *remove* it, and then try again.
- //
- // FIXME: This is not so efficient; we may need to
- // recurse a bunch of times here. Instead, it's probably
- // better to do something like drain_filter(...) on the
- // map to be able to delete or modify all the ranges in
- // start..=end and then potentially re-insert a new
- // range.
- end = std::cmp::max(end, *prev_end);
- self.map.remove(last);
- } else {
- // We overlap with the previous range, increase it to
- // include us.
- //
- // Make sure we're actually going to *increase* it though --
- // it may be that end is just inside the previously existing
- // set.
- return if end > *prev_end {
- *prev_end = end;
- true
- } else {
- false
- };
+ // This condition looks a bit weird, but actually makes sense.
+ //
+ // if r.0 == end + 1, then we're actually adjacent, so we want to
+ // continue to the next range. We're looking here for the first
+ // range which starts *non-adjacently* to our end.
+ let next = self.map.partition_point(|r| r.0 <= end + 1);
+ if let Some(right) = next.checked_sub(1) {
+ let (prev_start, prev_end) = self.map[right];
+ if prev_end + 1 >= start {
+ // If the start for the inserted range is adjacent to the
+ // end of the previous, we can extend the previous range.
+ if start < prev_start {
+ // The first range which ends *non-adjacently* to our start.
+ // And we can ensure that left <= right.
+ let left = self.map.partition_point(|l| l.1 + 1 < start);
+ let min = std::cmp::min(self.map[left].0, start);
+ let max = std::cmp::max(prev_end, end);
+ self.map[right] = (min, max);
+ if left != right {
+ self.map.drain(left..right);
}
- } else {
- // Otherwise, we don't overlap, so just insert
- self.map.insert(last + 1, (start, end));
return true;
- }
- } else {
- if self.map.is_empty() {
- // Quite common in practice, and expensive to call memcpy
- // with length zero.
- self.map.push((start, end));
} else {
- self.map.insert(next, (start, end));
+ // We overlap with the previous range, increase it to
+ // include us.
+ //
+ // Make sure we're actually going to *increase* it though --
+ // it may be that end is just inside the previously existing
+ // set.
+ return if end > prev_end {
+ self.map[right].1 = end;
+ true
+ } else {
+ false
+ };
}
+ } else {
+ // Otherwise, we don't overlap, so just insert
+ self.map.insert(right + 1, (start, end));
return true;
}
+ } else {
+ if self.map.is_empty() {
+ // Quite common in practice, and expensive to call memcpy
+ // with length zero.
+ self.map.push((start, end));
+ } else {
+ self.map.insert(next, (start, end));
+ }
+ return true;
}
}
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(crate_visibility_modifier)]
+#![feature(decl_macro)]
#![feature(drain_filter)]
#![feature(generators)]
+#![feature(let_chains)]
#![feature(let_else)]
#![feature(nll)]
#![feature(once_cell)]
-use rustc_ast::CRATE_NODE_ID;
+use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_session::parse::feature_err;
use rustc_session::utils::NativeLibKind;
use rustc_session::Session;
-use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::symbol::{sym, Symbol};
use rustc_target::spec::abi::Abi;
crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
// Process all of the #[link(..)]-style arguments
let sess = &self.tcx.sess;
+ let features = self.tcx.features();
for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) {
let Some(items) = m.meta_item_list() else {
continue;
};
- let mut lib = NativeLib {
- name: None,
- kind: NativeLibKind::Unspecified,
- cfg: None,
- foreign_module: Some(it.def_id.to_def_id()),
- wasm_import_module: None,
- verbatim: None,
- dll_imports: Vec::new(),
- };
- let mut kind_specified = false;
+ let mut name = None;
+ let mut kind = None;
+ let mut modifiers = None;
+ let mut cfg = None;
+ let mut wasm_import_module = None;
for item in items.iter() {
- if item.has_name(sym::kind) {
- kind_specified = true;
- let Some(kind) = item.value_str() else {
- continue; // skip like historical compilers
- };
- lib.kind = match kind.as_str() {
- "static" => NativeLibKind::Static { bundle: None, whole_archive: None },
- "static-nobundle" => {
- sess.struct_span_warn(
- item.span(),
- "library kind `static-nobundle` has been superseded by specifying \
- 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 }
+ match item.name_or_empty() {
+ sym::name => {
+ if name.is_some() {
+ let msg = "multiple `name` arguments in a single `#[link]` attribute";
+ sess.span_err(item.span(), msg);
+ continue;
}
- "dylib" => NativeLibKind::Dylib { as_needed: None },
- "framework" => NativeLibKind::Framework { as_needed: None },
- "raw-dylib" => NativeLibKind::RawDylib,
- k => {
- struct_span_err!(sess, item.span(), E0458, "unknown kind: `{}`", k)
- .span_label(item.span(), "unknown kind")
- .span_label(m.span, "")
+ let Some(link_name) = item.value_str() else {
+ let msg = "link name must be of the form `name = \"string\"`";
+ sess.span_err(item.span(), msg);
+ continue;
+ };
+ let span = item.name_value_literal_span().unwrap();
+ if link_name.is_empty() {
+ struct_span_err!(sess, span, E0454, "link name must not be empty")
+ .span_label(span, "empty link name")
.emit();
- NativeLibKind::Unspecified
}
- };
- } else if item.has_name(sym::name) {
- lib.name = item.value_str();
- } else if item.has_name(sym::cfg) {
- let Some(cfg) = item.meta_item_list() else {
- continue; // skip like historical compilers
- };
- if cfg.is_empty() {
- sess.span_err(item.span(), "`cfg()` must have an argument");
- } else if let cfg @ Some(..) = cfg[0].meta_item() {
- lib.cfg = cfg.cloned();
- } else {
- sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`");
+ name = Some((link_name, span));
}
- } else if item.has_name(sym::wasm_import_module) {
- match item.value_str() {
- Some(s) => lib.wasm_import_module = Some(s),
- None => {
- let msg = "must be of the form `#[link(wasm_import_module = \"...\")]`";
+ sym::kind => {
+ if kind.is_some() {
+ let msg = "multiple `kind` arguments in a single `#[link]` attribute";
sess.span_err(item.span(), msg);
+ continue;
}
- }
- } else {
- // currently, like past compilers, ignore unknown
- // directives here.
- }
- }
-
- // Do this outside the above loop so we don't depend on modifiers coming
- // after kinds
- let mut modifiers_count = 0;
- for item in items.iter().filter(|item| item.has_name(sym::modifiers)) {
- if let Some(modifiers) = item.value_str() {
- modifiers_count += 1;
- let span = item.name_value_literal_span().unwrap();
- let mut has_duplicate_modifiers = false;
- for modifier in modifiers.as_str().split(',') {
- let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
- Some(m) => (m, modifier.starts_with('+')),
- None => {
- // Note: this error also excludes the case with empty modifier
- // string, like `modifiers = ""`.
- sess.span_err(
- span,
- "invalid linking modifier syntax, expected '+' or '-' prefix \
- before one of: bundle, verbatim, whole-archive, as-needed",
- );
- continue;
- }
+ let Some(link_kind) = item.value_str() else {
+ let msg = "link kind must be of the form `kind = \"string\"`";
+ sess.span_err(item.span(), msg);
+ continue;
};
- match (modifier, &mut lib.kind) {
- ("bundle", NativeLibKind::Static { bundle, .. }) => {
- if bundle.is_some() {
- has_duplicate_modifiers = true;
- }
- *bundle = Some(value);
- }
- ("bundle", _) => {
- sess.span_err(
+ let span = item.name_value_literal_span().unwrap();
+ let link_kind = match link_kind.as_str() {
+ "static" => NativeLibKind::Static { bundle: None, whole_archive: None },
+ "static-nobundle" => {
+ sess.struct_span_warn(
span,
- "bundle linking modifier is only compatible with \
- `static` linking kind",
- );
- }
-
- ("verbatim", _) => {
- if lib.verbatim.is_some() {
- has_duplicate_modifiers = true;
+ "link kind `static-nobundle` has been superseded by specifying \
+ modifier `-bundle` with link kind `static`",
+ )
+ .emit();
+ if !features.static_nobundle {
+ feature_err(
+ &sess.parse_sess,
+ sym::static_nobundle,
+ span,
+ "link kind `static-nobundle` is unstable",
+ )
+ .emit();
}
- lib.verbatim = Some(value);
+ NativeLibKind::Static { bundle: Some(false), whole_archive: None }
}
-
- ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
- if whole_archive.is_some() {
- has_duplicate_modifiers = true;
+ "dylib" => NativeLibKind::Dylib { as_needed: None },
+ "framework" => {
+ if !sess.target.is_like_osx {
+ struct_span_err!(
+ sess,
+ span,
+ E0455,
+ "link kind `framework` is only supported on Apple targets"
+ )
+ .emit();
}
- *whole_archive = Some(value);
+ NativeLibKind::Framework { as_needed: None }
}
- ("whole-archive", _) => {
- sess.span_err(
- span,
- "whole-archive linking modifier is only compatible with \
- `static` linking kind",
- );
- }
-
- ("as-needed", NativeLibKind::Dylib { as_needed })
- | ("as-needed", NativeLibKind::Framework { as_needed }) => {
- if as_needed.is_some() {
- has_duplicate_modifiers = true;
+ "raw-dylib" => {
+ if !sess.target.is_like_windows {
+ struct_span_err!(
+ sess,
+ span,
+ E0455,
+ "link kind `raw-dylib` is only supported on Windows targets"
+ )
+ .emit();
+ } else if !features.raw_dylib {
+ feature_err(
+ &sess.parse_sess,
+ sym::raw_dylib,
+ span,
+ "link kind `raw-dylib` is unstable",
+ )
+ .emit();
}
- *as_needed = Some(value);
+ NativeLibKind::RawDylib
}
- ("as-needed", _) => {
- sess.span_err(
- span,
- "as-needed linking modifier is only compatible with \
- `dylib` and `framework` linking kinds",
- );
- }
-
- _ => {
- sess.span_err(
- span,
- &format!(
- "unrecognized linking modifier `{}`, expected one \
- of: bundle, verbatim, whole-archive, as-needed",
- modifier
- ),
+ kind => {
+ let msg = format!(
+ "unknown link kind `{kind}`, expected one of: \
+ static, dylib, framework, raw-dylib"
);
+ struct_span_err!(sess, span, E0458, "{}", msg)
+ .span_label(span, "unknown link kind")
+ .emit();
+ continue;
}
+ };
+ kind = Some(link_kind);
+ }
+ sym::modifiers => {
+ if modifiers.is_some() {
+ let msg =
+ "multiple `modifiers` arguments in a single `#[link]` attribute";
+ sess.span_err(item.span(), msg);
+ continue;
+ }
+ let Some(link_modifiers) = item.value_str() else {
+ let msg = "link modifiers must be of the form `modifiers = \"string\"`";
+ sess.span_err(item.span(), msg);
+ continue;
+ };
+ modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
+ }
+ sym::cfg => {
+ if cfg.is_some() {
+ let msg = "multiple `cfg` arguments in a single `#[link]` attribute";
+ sess.span_err(item.span(), msg);
+ continue;
+ }
+ let Some(link_cfg) = item.meta_item_list() else {
+ let msg = "link cfg must be of the form `cfg(/* predicate */)`";
+ sess.span_err(item.span(), msg);
+ continue;
+ };
+ let [NestedMetaItem::MetaItem(link_cfg)] = link_cfg else {
+ let msg = "link cfg must have a single predicate argument";
+ sess.span_err(item.span(), msg);
+ continue;
+ };
+ if !features.link_cfg {
+ feature_err(
+ &sess.parse_sess,
+ sym::link_cfg,
+ item.span(),
+ "link cfg is unstable",
+ )
+ .emit();
+ }
+ cfg = Some(link_cfg.clone());
+ }
+ sym::wasm_import_module => {
+ if wasm_import_module.is_some() {
+ let msg = "multiple `wasm_import_module` arguments \
+ in a single `#[link]` attribute";
+ sess.span_err(item.span(), msg);
+ continue;
}
+ let Some(link_wasm_import_module) = item.value_str() else {
+ let msg = "wasm import module must be of the form \
+ `wasm_import_module = \"string\"`";
+ sess.span_err(item.span(), msg);
+ continue;
+ };
+ wasm_import_module = Some((link_wasm_import_module, item.span()));
}
- if has_duplicate_modifiers {
- let msg =
- "same modifier is used multiple times in a single `modifiers` argument";
+ _ => {
+ let msg = "unexpected `#[link]` argument, expected one of: \
+ name, kind, modifiers, cfg, wasm_import_module";
sess.span_err(item.span(), msg);
}
- } else {
- let msg = "must be of the form `#[link(modifiers = \"...\")]`";
- sess.span_err(item.span(), msg);
}
}
- if modifiers_count > 1 {
- let msg = "multiple `modifiers` arguments in a single `#[link]` attribute";
- sess.span_err(m.span, msg);
+ // Do this outside the above loop so we don't depend on modifiers coming after kinds
+ let mut verbatim = None;
+ if let Some((modifiers, span)) = modifiers {
+ for modifier in modifiers.as_str().split(',') {
+ let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
+ Some(m) => (m, modifier.starts_with('+')),
+ None => {
+ sess.span_err(
+ span,
+ "invalid linking modifier syntax, expected '+' or '-' prefix \
+ before one of: bundle, verbatim, whole-archive, as-needed",
+ );
+ continue;
+ }
+ };
+
+ macro report_unstable_modifier($feature: ident) {
+ if !features.$feature {
+ feature_err(
+ &sess.parse_sess,
+ sym::$feature,
+ span,
+ &format!("linking modifier `{modifier}` is unstable"),
+ )
+ .emit();
+ }
+ }
+ let assign_modifier = |dst: &mut Option<bool>| {
+ if dst.is_some() {
+ let msg = format!(
+ "multiple `{modifier}` modifiers in a single `modifiers` argument"
+ );
+ sess.span_err(span, &msg);
+ } else {
+ *dst = Some(value);
+ }
+ };
+ match (modifier, &mut kind) {
+ ("bundle", Some(NativeLibKind::Static { bundle, .. })) => {
+ report_unstable_modifier!(native_link_modifiers_bundle);
+ assign_modifier(bundle)
+ }
+ ("bundle", _) => {
+ sess.span_err(
+ span,
+ "linking modifier `bundle` is only compatible with \
+ `static` linking kind",
+ );
+ }
+
+ ("verbatim", _) => {
+ report_unstable_modifier!(native_link_modifiers_verbatim);
+ assign_modifier(&mut verbatim)
+ }
+
+ ("whole-archive", Some(NativeLibKind::Static { whole_archive, .. })) => {
+ assign_modifier(whole_archive)
+ }
+ ("whole-archive", _) => {
+ sess.span_err(
+ span,
+ "linking modifier `whole-archive` is only compatible with \
+ `static` linking kind",
+ );
+ }
+
+ ("as-needed", Some(NativeLibKind::Dylib { as_needed }))
+ | ("as-needed", Some(NativeLibKind::Framework { as_needed })) => {
+ report_unstable_modifier!(native_link_modifiers_as_needed);
+ assign_modifier(as_needed)
+ }
+ ("as-needed", _) => {
+ sess.span_err(
+ span,
+ "linking modifier `as-needed` is only compatible with \
+ `dylib` and `framework` linking kinds",
+ );
+ }
+
+ _ => {
+ sess.span_err(
+ span,
+ format!(
+ "unknown linking modifier `{modifier}`, expected one of: \
+ bundle, verbatim, whole-archive, as-needed"
+ ),
+ );
+ }
+ }
+ }
}
- // In general we require #[link(name = "...")] but we allow
- // #[link(wasm_import_module = "...")] without the `name`.
- let requires_name = kind_specified || lib.wasm_import_module.is_none();
- if lib.name.is_none() && requires_name {
+ if let Some((_, span)) = wasm_import_module {
+ if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
+ let msg = "`wasm_import_module` is incompatible with \
+ other arguments in `#[link]` attributes";
+ sess.span_err(span, msg);
+ }
+ } else if name.is_none() {
struct_span_err!(
sess,
m.span,
E0459,
- "`#[link(...)]` specified without \
- `name = \"foo\"`"
+ "`#[link]` attribute requires a `name = \"string\"` argument"
)
.span_label(m.span, "missing `name` argument")
.emit();
}
- if lib.kind == NativeLibKind::RawDylib {
- lib.dll_imports.extend(
+ let dll_imports = match kind {
+ Some(NativeLibKind::RawDylib) => {
+ if let Some((name, span)) = name && name.as_str().contains('\0') {
+ sess.span_err(
+ span,
+ "link name must not contain NUL characters if link kind is `raw-dylib`",
+ );
+ }
foreign_mod_items
.iter()
- .map(|child_item| self.build_dll_import(abi, child_item)),
- );
- }
-
- self.register_native_lib(Some(m.span), lib);
- }
- }
-
- fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLib) {
- if lib.name.as_ref().map_or(false, |&s| s == kw::Empty) {
- match span {
- Some(span) => {
- struct_span_err!(
- self.tcx.sess,
- span,
- E0454,
- "`#[link(name = \"\")]` given with empty name"
- )
- .span_label(span, "empty name given")
- .emit();
- }
- None => {
- self.tcx.sess.err("empty library name given via `-l`");
- }
- }
- return;
- }
- let is_osx = self.tcx.sess.target.is_like_osx;
- if matches!(lib.kind, NativeLibKind::Framework { .. }) && !is_osx {
- let msg = "native frameworks are only available on macOS targets";
- match span {
- Some(span) => {
- struct_span_err!(self.tcx.sess, span, E0455, "{}", msg).emit();
- }
- None => {
- self.tcx.sess.err(msg);
+ .map(|child_item| self.build_dll_import(abi, child_item))
+ .collect()
}
- }
- }
- if lib.cfg.is_some() && !self.tcx.features().link_cfg {
- feature_err(
- &self.tcx.sess.parse_sess,
- sym::link_cfg,
- span.unwrap(),
- "kind=\"link_cfg\" 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 Some(span) = span else {
- bug!("raw-dylib libraries are not supported on the command line");
+ _ => Vec::new(),
};
-
- if !self.tcx.sess.target.options.is_like_windows {
- self.tcx.sess.span_fatal(
- span,
- "`#[link(...)]` with `kind = \"raw-dylib\"` only supported on Windows",
- );
- }
-
- if lib_name.as_str().contains('\0') {
- self.tcx.sess.span_err(span, "library name may not contain NUL characters");
- }
-
- if !self.tcx.features().raw_dylib {
- feature_err(
- &self.tcx.sess.parse_sess,
- sym::raw_dylib,
- span,
- "kind=\"raw-dylib\" is unstable",
- )
- .emit();
- }
+ self.libs.push(NativeLib {
+ name: name.map(|(name, _)| name),
+ kind: kind.unwrap_or(NativeLibKind::Unspecified),
+ cfg,
+ foreign_module: Some(it.def_id.to_def_id()),
+ wasm_import_module: wasm_import_module.map(|(name, _)| name),
+ verbatim,
+ dll_imports,
+ });
}
-
- self.libs.push(lib);
}
// Process libs passed on the command line
// First, check for errors
let mut renames = FxHashSet::default();
for lib in &self.tcx.sess.opts.libs {
+ if let NativeLibKind::Framework { .. } = lib.kind && !self.tcx.sess.target.is_like_osx {
+ // Cannot check this when parsing options because the target is not yet available.
+ self.tcx.sess.err("library kind `framework` is only supported on Apple targets");
+ }
if let Some(ref new_name) = lib.new_name {
let any_duplicate = self
.libs
.filter_map(|lib| lib.name.as_ref())
.any(|n| n.as_str() == lib.name);
if new_name.is_empty() {
- self.tcx.sess.err(&format!(
+ self.tcx.sess.err(format!(
"an empty renaming target was specified for library `{}`",
lib.name
));
} else if !any_duplicate {
- self.tcx.sess.err(&format!(
+ self.tcx.sess.err(format!(
"renaming of the library `{}` was specified, \
however this crate contains no `#[link(...)]` \
attributes referencing this library",
lib.name
));
} else if !renames.insert(&lib.name) {
- self.tcx.sess.err(&format!(
+ self.tcx.sess.err(format!(
"multiple renamings were \
specified for library `{}`",
lib.name
if existing.is_empty() {
// Add if not found
let new_name: Option<&str> = passed_lib.new_name.as_deref();
- let lib = NativeLib {
+ self.libs.push(NativeLib {
name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))),
kind: passed_lib.kind,
cfg: None,
wasm_import_module: None,
verbatim: passed_lib.verbatim,
dll_imports: Vec::new(),
- };
- self.register_native_lib(None, lib);
+ });
} else {
// Move all existing libraries with the same name to the
// end of the command line.
use rustc_session::parse::feature_err;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
+use rustc_target::spec::abi::Abi;
use std::collections::hash_map::Entry;
pub(crate) fn target_from_impl_item<'tcx>(
/// Checks if `#[link]` is applied to an item other than a foreign module.
fn check_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
- match target {
- Target::ForeignMod => {}
- _ => {
- self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
- let mut diag = lint.build("attribute should be applied to an `extern` block");
- diag.warn(
- "this was previously accepted by the compiler but is \
- being phased out; it will become a hard error in \
- a future release!",
- );
+ if target == Target::ForeignMod
+ && let hir::Node::Item(item) = self.tcx.hir().get(hir_id)
+ && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item
+ && !matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic)
+ {
+ return;
+ }
- diag.span_label(span, "not an `extern` block");
- diag.emit();
- });
+ self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+ let mut diag =
+ lint.build("attribute should be applied to an `extern` block with non-Rust ABI");
+ diag.warn(
+ "this was previously accepted by the compiler but is \
+ being phased out; it will become a hard error in \
+ a future release!",
+ );
+ if target != Target::ForeignMod {
+ diag.span_label(span, "not an `extern` block");
}
- }
+ diag.emit();
+ });
}
/// Checks if `#[link_name]` is applied to an item other than a foreign function or static.
};
let kind = match kind {
- "dylib" => NativeLibKind::Dylib { as_needed: None },
- "framework" => NativeLibKind::Framework { as_needed: None },
"static" => NativeLibKind::Static { bundle: None, whole_archive: None },
"static-nobundle" => {
early_warn(
error_format,
"library kind `static-nobundle` has been superseded by specifying \
- `-bundle` on library kind `static`. Try `static:-bundle`",
+ modifier `-bundle` with 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 !nightly_options::match_is_nightly_build(matches) {
early_error(
error_format,
- "library kind `static-nobundle` are currently unstable and only accepted on \
- the nightly compiler",
+ "library kind `static-nobundle` is unstable \
+ and only accepted on the nightly compiler",
);
}
NativeLibKind::Static { bundle: Some(false), whole_archive: None }
}
- s => early_error(
+ "dylib" => NativeLibKind::Dylib { as_needed: None },
+ "framework" => NativeLibKind::Framework { as_needed: None },
+ _ => early_error(
error_format,
- &format!("unknown library kind `{s}`, expected one of dylib, framework, or static"),
+ &format!("unknown library kind `{kind}`, expected one of: static, dylib, framework"),
),
};
match modifiers {
error_format: ErrorOutputType,
matches: &getopts::Matches,
) -> (NativeLibKind, Option<bool>) {
- let report_unstable_modifier = |modifier| {
- if !nightly_options::is_unstable_enabled(matches) {
- let why = if nightly_options::match_is_nightly_build(matches) {
- " and only accepted on the nightly compiler"
- } else {
- ", the `-Z unstable-options` flag must also be passed to use it"
- };
- early_error(
- error_format,
- &format!("{modifier} linking modifier is currently unstable{why}"),
- )
- }
- };
-
- let mut has_duplicate_modifiers = false;
let mut verbatim = None;
for modifier in modifiers.split(',') {
let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
None => early_error(
error_format,
"invalid linking modifier syntax, expected '+' or '-' prefix \
- before one of: bundle, verbatim, whole-archive, as-needed",
+ before one of: bundle, verbatim, whole-archive, as-needed",
),
};
+ let report_unstable_modifier = || {
+ if !nightly_options::is_unstable_enabled(matches) {
+ let why = if nightly_options::match_is_nightly_build(matches) {
+ " and only accepted on the nightly compiler"
+ } else {
+ ", the `-Z unstable-options` flag must also be passed to use it"
+ };
+ early_error(
+ error_format,
+ &format!("linking modifier `{modifier}` is unstable{why}"),
+ )
+ }
+ };
+ let assign_modifier = |dst: &mut Option<bool>| {
+ if dst.is_some() {
+ let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
+ early_error(error_format, &msg)
+ } else {
+ *dst = Some(value);
+ }
+ };
match (modifier, &mut kind) {
("bundle", NativeLibKind::Static { bundle, .. }) => {
- report_unstable_modifier(modifier);
- if bundle.is_some() {
- has_duplicate_modifiers = true;
- }
- *bundle = Some(value);
+ report_unstable_modifier();
+ assign_modifier(bundle)
}
("bundle", _) => early_error(
error_format,
- "bundle linking modifier is only compatible with \
- `static` linking kind",
+ "linking modifier `bundle` is only compatible with `static` linking kind",
),
("verbatim", _) => {
- report_unstable_modifier(modifier);
- if verbatim.is_some() {
- has_duplicate_modifiers = true;
- }
- verbatim = Some(value);
+ report_unstable_modifier();
+ assign_modifier(&mut verbatim)
}
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
- if whole_archive.is_some() {
- has_duplicate_modifiers = true;
- }
- *whole_archive = Some(value);
+ assign_modifier(whole_archive)
}
("whole-archive", _) => early_error(
error_format,
- "whole-archive linking modifier is only compatible with \
- `static` linking kind",
+ "linking modifier `whole-archive` is only compatible with `static` linking kind",
),
("as-needed", NativeLibKind::Dylib { as_needed })
| ("as-needed", NativeLibKind::Framework { as_needed }) => {
- report_unstable_modifier(modifier);
- if as_needed.is_some() {
- has_duplicate_modifiers = true;
- }
- *as_needed = Some(value);
+ report_unstable_modifier();
+ assign_modifier(as_needed)
}
("as-needed", _) => early_error(
error_format,
- "as-needed linking modifier is only compatible with \
- `dylib` and `framework` linking kinds",
+ "linking modifier `as-needed` is only compatible with \
+ `dylib` and `framework` linking kinds",
),
// Note: this error also excludes the case with empty modifier
_ => early_error(
error_format,
&format!(
- "unrecognized linking modifier `{modifier}`, expected one \
- of: bundle, verbatim, whole-archive, as-needed"
+ "unknown linking modifier `{modifier}`, expected one \
+ of: bundle, verbatim, whole-archive, as-needed"
),
),
}
}
- if has_duplicate_modifiers {
- report_unstable_modifier("duplicating")
- }
(kind, verbatim)
}
None => (name, None),
Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
};
+ if name.is_empty() {
+ early_error(error_format, "library name must not be empty");
+ }
NativeLib { name, new_name, kind, verbatim }
})
.collect()
// 32-bit c_int. Below is -2, in two's complement, but that only works out
// because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
+#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
pub struct BorrowedFd<'fd> {
fd: RawFd,
// 32-bit c_int. Below is -2, in two's complement, but that only works out
// because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
+#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
pub struct OwnedFd {
fd: RawFd,
assert_eq!(stdin_as_file.as_fd().as_raw_fd(), raw_fd);
assert_eq!(Into::<OwnedFd>::into(stdin_as_file).into_raw_fd(), raw_fd);
}
+
+#[cfg(any(unix, target_os = "wasi"))]
+#[test]
+fn test_niche_optimizations() {
+ use crate::mem::size_of;
+ #[cfg(unix)]
+ use crate::os::unix::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
+ #[cfg(target_os = "wasi")]
+ use crate::os::wasi::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
+
+ assert_eq!(size_of::<Option<OwnedFd>>(), size_of::<RawFd>());
+ assert_eq!(size_of::<Option<BorrowedFd<'static>>>(), size_of::<RawFd>());
+ unsafe {
+ assert_eq!(OwnedFd::from_raw_fd(RawFd::MIN).into_raw_fd(), RawFd::MIN);
+ assert_eq!(OwnedFd::from_raw_fd(RawFd::MAX).into_raw_fd(), RawFd::MAX);
+ assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MIN)).unwrap().into_raw_fd(), RawFd::MIN);
+ assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MAX)).unwrap().into_raw_fd(), RawFd::MAX);
+ }
+}
}
/// Allow child processes to inherit the handle.
+ #[cfg(not(target_vendor = "uwp"))]
pub(crate) fn set_inheritable(&self) -> io::Result<()> {
cvt(unsafe {
c::SetHandleInformation(
pub use raw::*;
#[unstable(feature = "io_safety", issue = "87074")]
pub use socket::*;
+
+#[cfg(test)]
+mod tests;
use crate::mem::forget;
use crate::sys;
use crate::sys::c;
+#[cfg(not(target_vendor = "uwp"))]
use crate::sys::cvt;
/// A borrowed socket.
target_pointer_width = "64",
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)]
+#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
pub struct BorrowedSocket<'socket> {
socket: RawSocket,
target_pointer_width = "64",
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)]
+#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
pub struct OwnedSocket {
socket: RawSocket,
--- /dev/null
+#[test]
+fn test_niche_optimizations_socket() {
+ use crate::mem::size_of;
+ use crate::os::windows::io::{
+ BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
+ };
+
+ assert_eq!(size_of::<Option<OwnedSocket>>(), size_of::<RawSocket>());
+ assert_eq!(size_of::<Option<BorrowedSocket<'static>>>(), size_of::<RawSocket>(),);
+ unsafe {
+ #[cfg(target_pointer_width = "32")]
+ let (min, max) = (i32::MIN as u32, i32::MAX as u32);
+ #[cfg(target_pointer_width = "64")]
+ let (min, max) = (i64::MIN as u64, i64::MAX as u64);
+
+ assert_eq!(OwnedSocket::from_raw_socket(min).into_raw_socket(), min);
+ assert_eq!(OwnedSocket::from_raw_socket(max).into_raw_socket(), max);
+ assert_eq!(Some(OwnedSocket::from_raw_socket(min)).unwrap().into_raw_socket(), min);
+ assert_eq!(Some(OwnedSocket::from_raw_socket(max)).unwrap().into_raw_socket(), max);
+ }
+}
Ok(Self(self.0.duplicate(access, inherit, options)?))
}
+ #[cfg(not(target_vendor = "uwp"))]
pub(crate) fn set_inheritable(&self) -> io::Result<()> {
self.0.set_inheritable()
}
} else {
let (ours, theirs) = if ours_readable { (read, write) } else { (write, read) };
let ours = Handle::from_raw_handle(ours);
+ #[cfg(not(target_vendor = "uwp"))]
let theirs = Handle::from_raw_handle(theirs);
+ #[cfg(target_vendor = "uwp")]
+ let mut theirs = Handle::from_raw_handle(theirs);
if their_handle_inheritable {
- theirs.set_inheritable()?;
+ #[cfg(not(target_vendor = "uwp"))]
+ {
+ theirs.set_inheritable()?;
+ }
+
+ #[cfg(target_vendor = "uwp")]
+ {
+ theirs = theirs.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)?;
+ }
}
Ok(Pipes { ours: AnonPipe::Sync(ours), theirs: AnonPipe::Sync(theirs) })
If the kind is specified, then linking modifiers can be attached to it.
Modifiers are specified as a comma-delimited string with each modifier prefixed with
either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively.
-The last boolean value specified for a given modifier wins. \
+Specifying multiple `modifiers` arguments in a single `link` attribute,
+or multiple identical modifiers in the same `modifiers` argument is not currently supported. \
Example: `-l static:+whole-archive=mylib`.
The kind of library and the modifiers can also be specified in a [`#[link]`
To enable a sanitizer compile with `-Zsanitizer=address`,`-Zsanitizer=cfi`,
`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory`,
-`-Zsanitizer=memtag`, or `-Zsanitizer=thread`.
+`-Zsanitizer=memtag`, or `-Zsanitizer=thread`. You might also need the `--target` and `build-std` flags. Example:
+```shell
+$ RUSTFLAGS=-Zsanitizer=address cargo build -Zbuild-std --target x86_64-unknown-linux-gnu
+```
# AddressSanitizer
"no-var": ["error"],
"prefer-const": ["error"],
"prefer-arrow-callback": ["error"],
+ "brace-style": [
+ "error",
+ "1tbs",
+ { "allowSingleLine": false }
+ ],
}
};
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
if (e.parentNode.id !== "implementations-list" ||
(!hasClass(e, "implementors-toggle") &&
- !hasClass(e, "type-contents-toggle")))
- {
+ !hasClass(e, "type-contents-toggle"))
+ ) {
e.open = false;
}
});
// visible. This is necessary since updateScrapedExample calls scrollToLoc which
// depends on offsetHeight, a property that requires an element to be visible to
// compute correctly.
- setTimeout(() => { onEachLazy(moreExamples, updateScrapedExample); });
+ setTimeout(() => {
+ onEachLazy(moreExamples, updateScrapedExample);
+ });
}, {once: true});
});
})();
if (foundExclamation) {
throw new Error("Cannot have more than one `!` in an ident");
} else if (parserState.pos + 1 < parserState.length &&
- isIdentCharacter(parserState.userQuery[parserState.pos + 1]))
- {
+ isIdentCharacter(parserState.userQuery[parserState.pos + 1])
+ ) {
throw new Error("`!` can only be at the end of an ident");
}
foundExclamation = true;
} else if (
isStopCharacter(c) ||
isSpecialStartCharacter(c) ||
- isSeparatorCharacter(c))
- {
+ isSeparatorCharacter(c)
+ ) {
break;
- }
- // If we allow paths ("str::string" for example).
- else if (c === ":") {
+ } else if (c === ":") { // If we allow paths ("str::string" for example).
if (!isPathStart(parserState)) {
break;
}
end = getIdentEndPosition(parserState);
}
if (parserState.pos < parserState.length &&
- parserState.userQuery[parserState.pos] === "<")
- {
+ parserState.userQuery[parserState.pos] === "<"
+ ) {
if (isInGenerics) {
throw new Error("Unexpected `<` after `<`");
} else if (start >= end) {
if (elem &&
elem.value !== "All crates" &&
- hasOwnPropertyRustdoc(rawSearchIndex, elem.value))
- {
+ hasOwnPropertyRustdoc(rawSearchIndex, elem.value)
+ ) {
return elem.value;
}
return null;
// sort by exact match with regard to the last word (mismatch goes later)
a = (aaa.word !== userQuery);
b = (bbb.word !== userQuery);
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// Sort by non levenshtein results and then levenshtein results by the distance
// (less changes required to match means higher rankings)
a = (aaa.lev);
b = (bbb.lev);
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// sort by crate (non-current crate goes later)
a = (aaa.item.crate !== window.currentCrate);
b = (bbb.item.crate !== window.currentCrate);
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// sort by item name length (longer goes later)
a = aaa.word.length;
b = bbb.word.length;
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// sort by item name (lexicographically larger goes later)
a = aaa.word;
b = bbb.word;
- if (a !== b) { return (a > b ? +1 : -1); }
+ if (a !== b) {
+ return (a > b ? +1 : -1);
+ }
// sort by index of keyword in item name (no literal occurrence goes later)
a = (aaa.index < 0);
b = (bbb.index < 0);
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// (later literal occurrence, if any, goes later)
a = aaa.index;
b = bbb.index;
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// special precedence for primitive and keyword pages
if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) ||
// sort by description (no description goes later)
a = (aaa.item.desc === "");
b = (bbb.item.desc === "");
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// sort by type (later occurrence in `itemTypes` goes later)
a = aaa.item.ty;
b = bbb.item.ty;
- if (a !== b) { return a - b; }
+ if (a !== b) {
+ return a - b;
+ }
// sort by path (lexicographically larger goes later)
a = aaa.item.path;
b = bbb.item.path;
- if (a !== b) { return (a > b ? +1 : -1); }
+ if (a !== b) {
+ return (a > b ? +1 : -1);
+ }
// que sera, sera
return 0;
}
if (searchWord.indexOf(elem.pathLast) > -1 ||
- row.normalizedName.indexOf(elem.pathLast) > -1)
- {
+ row.normalizedName.indexOf(elem.pathLast) > -1
+ ) {
// filter type: ... queries
if (!results_others[fullId] !== undefined) {
index = row.normalizedName.indexOf(elem.pathLast);
}
}
lev = levenshtein(searchWord, elem.pathLast);
- if (lev > 0 && elem.pathLast.length > 2 && searchWord.indexOf(elem.pathLast) > -1)
- {
+ if (lev > 0 && elem.pathLast.length > 2 && searchWord.indexOf(elem.pathLast) > -1) {
if (elem.pathLast.length < 6) {
lev = 1;
} else {
// By default, the search DOM element is "empty" (meaning it has no children not
// text content). Once a search has been run, it won't be empty, even if you press
// ESC or empty the search input (which also "cancels" the search).
- && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText)))
- {
+ && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText))
+ ) {
const elem = document.createElement("a");
elem.href = results.others[0].href;
removeClass(elem, "active");
let i = 0;
for (const elem of elems) {
const j = i;
- elem.onclick = () => { printTab(j); };
+ elem.onclick = () => printTab(j);
searchState.focusedByTab.push(null);
i += 1;
}
function blurHandler(event) {
const settingsButton = getSettingsButton();
if (!elemIsInParent(document.activeElement, settingsButton) &&
- !elemIsInParent(event.relatedTarget, settingsButton))
- {
+ !elemIsInParent(event.relatedTarget, settingsButton)
+ ) {
window.hideSettings();
}
}
-#[link(name = "")] //~ ERROR: given with empty name
+#[link(name = "")] //~ ERROR: link name must not be empty
extern "C" {}
fn main() {}
-error[E0454]: `#[link(name = "")]` given with empty name
- --> $DIR/empty-linkname.rs:1:1
+error[E0454]: link name must not be empty
+ --> $DIR/empty-linkname.rs:1:15
|
LL | #[link(name = "")]
- | ^^^^^^^^^^^^^^^^^^ empty name given
+ | ^^ empty link name
error: aborting due to previous error
-error[E0454]: `#[link(name = "")]` given with empty name
- --> $DIR/E0454.rs:1:1
+error[E0454]: link name must not be empty
+ --> $DIR/E0454.rs:1:15
|
LL | #[link(name = "")] extern "C" {}
- | ^^^^^^^^^^^^^^^^^^ empty name given
+ | ^^ empty link name
error: aborting due to previous error
-error[E0458]: unknown kind: `wonderful_unicorn`
- --> $DIR/E0458.rs:1:8
+error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib
+ --> $DIR/E0458.rs:1:15
|
LL | #[link(kind = "wonderful_unicorn")] extern "C" {}
- | -------^^^^^^^^^^^^^^^^^^^^^^^^^^--
- | |
- | unknown kind
+ | ^^^^^^^^^^^^^^^^^^^ unknown link kind
-error[E0459]: `#[link(...)]` specified without `name = "foo"`
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
--> $DIR/E0458.rs:1:1
|
LL | #[link(kind = "wonderful_unicorn")] extern "C" {}
-error[E0459]: `#[link(...)]` specified without `name = "foo"`
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
--> $DIR/E0459.rs:1:1
|
LL | #[link(kind = "dylib")] extern "C" {}
-error[E0658]: kind="link_cfg" is unstable
- --> $DIR/feature-gate-link_cfg.rs:1:1
+error[E0658]: link cfg is unstable
+ --> $DIR/feature-gate-link_cfg.rs:1:22
|
LL | #[link(name = "foo", cfg(foo))]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^
|
= note: see issue #37406 <https://github.com/rust-lang/rust/issues/37406> for more information
= help: add `#![feature(link_cfg)]` to the crate attributes to enable
-#[link(name = "foo", modifiers = "+as-needed")]
-//~^ ERROR: `#[link(modifiers="as-needed")]` is unstable
+#[link(name = "foo", kind = "dylib", modifiers = "+as-needed")]
+//~^ ERROR: linking modifier `as-needed` is unstable
extern "C" {}
fn main() {}
-error[E0658]: `#[link(modifiers="as-needed")]` is unstable
- --> $DIR/feature-gate-native_link_modifiers_as_needed.rs:1:34
+error[E0658]: linking modifier `as-needed` is unstable
+ --> $DIR/feature-gate-native_link_modifiers_as_needed.rs:1:50
|
-LL | #[link(name = "foo", modifiers = "+as-needed")]
- | ^^^^^^^^^^^^
+LL | #[link(name = "foo", kind = "dylib", modifiers = "+as-needed")]
+ | ^^^^^^^^^^^^
|
= note: see issue #81490 <https://github.com/rust-lang/rust/issues/81490> for more information
= help: add `#![feature(native_link_modifiers_as_needed)]` to the crate attributes to enable
-error: bundle linking modifier is currently unstable and only accepted on the nightly compiler
+error: linking modifier `bundle` is unstable and only accepted on the nightly compiler
-#[link(name = "foo", modifiers = "+bundle")]
-//~^ ERROR: `#[link(modifiers="bundle")]` is unstable
+#[link(name = "foo", kind = "static", modifiers = "+bundle")]
+//~^ ERROR: linking modifier `bundle` is unstable
extern "C" {}
fn main() {}
-error[E0658]: `#[link(modifiers="bundle")]` is unstable
- --> $DIR/feature-gate-native_link_modifiers_bundle.rs:1:34
+error[E0658]: linking modifier `bundle` is unstable
+ --> $DIR/feature-gate-native_link_modifiers_bundle.rs:1:51
|
-LL | #[link(name = "foo", modifiers = "+bundle")]
- | ^^^^^^^^^
+LL | #[link(name = "foo", kind = "static", modifiers = "+bundle")]
+ | ^^^^^^^^^
|
= note: see issue #81490 <https://github.com/rust-lang/rust/issues/81490> for more information
= help: add `#![feature(native_link_modifiers_bundle)]` to the crate attributes to enable
#[link(name = "foo", modifiers = "+verbatim")]
-//~^ ERROR: `#[link(modifiers="verbatim")]` is unstable
+//~^ ERROR: linking modifier `verbatim` is unstable
extern "C" {}
fn main() {}
-error[E0658]: `#[link(modifiers="verbatim")]` is unstable
+error[E0658]: linking modifier `verbatim` is unstable
--> $DIR/feature-gate-native_link_modifiers_verbatim.rs:1:34
|
LL | #[link(name = "foo", modifiers = "+verbatim")]
// only-windows
#[link(name = "foo", kind = "raw-dylib")]
-//~^ ERROR: kind="raw-dylib" is unstable
+//~^ ERROR: link kind `raw-dylib` is unstable
extern "C" {}
fn main() {}
-error[E0658]: kind="raw-dylib" is unstable
- --> $DIR/feature-gate-raw-dylib.rs:2:1
+error[E0658]: link kind `raw-dylib` is unstable
+ --> $DIR/feature-gate-raw-dylib.rs:2:29
|
LL | #[link(name = "foo", kind = "raw-dylib")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^
|
= note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
= help: add `#![feature(raw_dylib)]` to the crate attributes to enable
-warning: library kind `static-nobundle` has been superseded by specifying `-bundle` on library kind `static`. Try `static:-bundle`
+warning: library kind `static-nobundle` has been superseded by specifying modifier `-bundle` with library kind `static`. Try `static:-bundle`
#[link(name = "foo", kind = "static-nobundle")]
-//~^ WARNING: library kind `static-nobundle` has been superseded by specifying modifier `-bundle` with library kind `static`
-//~^^ ERROR: kind="static-nobundle" is unstable
+//~^ WARNING: link kind `static-nobundle` has been superseded by specifying modifier `-bundle` with link kind `static`
+//~^^ ERROR: link kind `static-nobundle` is unstable
extern "C" {}
fn main() {}
-warning: library kind `static-nobundle` has been superseded by specifying modifier `-bundle` with library kind `static`
- --> $DIR/feature-gate-static-nobundle.rs:1:22
+warning: link kind `static-nobundle` has been superseded by specifying modifier `-bundle` with link kind `static`
+ --> $DIR/feature-gate-static-nobundle.rs:1:29
|
LL | #[link(name = "foo", kind = "static-nobundle")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
-error[E0658]: kind="static-nobundle" is unstable
- --> $DIR/feature-gate-static-nobundle.rs:1:22
+error[E0658]: link kind `static-nobundle` is unstable
+ --> $DIR/feature-gate-static-nobundle.rs:1:29
|
LL | #[link(name = "foo", kind = "static-nobundle")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
|
= note: see issue #37403 <https://github.com/rust-lang/rust/issues/37403> for more information
= help: add `#![feature(static_nobundle)]` to the crate attributes to enable
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block
+
+ #[link()] extern "Rust" {}
+ //~^ WARN attribute should be applied to an `extern` block
+ //~| WARN this was previously accepted
}
struct StructForDeprecated;
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-warning: attribute should be applied to an `extern` block
+warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:554:1
|
LL | #[link()]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: `#[must_use]` has no effect when applied to a module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:601:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:605:1
|
LL | #[must_use]
| ^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:614:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:618:1
|
LL | #[windows_subsystem = "windows"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:635:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:639:1
|
LL | #[crate_name = "0900"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:654:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:658:1
|
LL | #[crate_type = "0800"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:677:1
|
LL | #[feature(x0600)]
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:1
|
LL | #[no_main]
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:1
|
LL | #[no_builtins]
| ^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1
|
LL | #[recursion_limit="0200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:1
|
LL | #[type_length_limit="0100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-warning: attribute should be applied to an `extern` block
+warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
|
LL | #![link()]
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-warning: attribute should be applied to an `extern` block
+warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:560:17
|
LL | mod inner { #![link()] }
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-warning: attribute should be applied to an `extern` block
+warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:565:5
|
LL | #[link()] fn f() { }
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-warning: attribute should be applied to an `extern` block
+warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:570:5
|
LL | #[link()] struct S;
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-warning: attribute should be applied to an `extern` block
+warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:575:5
|
LL | #[link()] type T = S;
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-warning: attribute should be applied to an `extern` block
+warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:580:5
|
LL | #[link()] impl S { }
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+warning: attribute should be applied to an `extern` block with non-Rust ABI
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:585:5
+ |
+LL | #[link()] extern "Rust" {}
+ | ^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
warning: `#[must_use]` has no effect when applied to a module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:603:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:607:17
|
LL | mod inner { #![must_use] }
| ^^^^^^^^^^^^
warning: `#[must_use]` has no effect when applied to a type alias
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:609:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:613:5
|
LL | #[must_use] type T = S;
| ^^^^^^^^^^^
warning: `#[must_use]` has no effect when applied to an item
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:611:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:615:5
|
LL | #[must_use] impl S { }
| ^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:617:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:621:17
|
LL | mod inner { #![windows_subsystem="windows"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:620:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:624:5
|
LL | #[windows_subsystem = "windows"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:623:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:627:5
|
LL | #[windows_subsystem = "windows"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:626:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:630:5
|
LL | #[windows_subsystem = "windows"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:629:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:633:5
|
LL | #[windows_subsystem = "windows"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:638:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:642:17
|
LL | mod inner { #![crate_name="0900"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:641:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:645:5
|
LL | #[crate_name = "0900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:644:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:648:5
|
LL | #[crate_name = "0900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651:5
|
LL | #[crate_name = "0900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:650:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:654:5
|
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:657:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:661:17
|
LL | mod inner { #![crate_type="0800"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:664:5
|
LL | #[crate_type = "0800"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5
|
LL | #[crate_type = "0800"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:666:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:670:5
|
LL | #[crate_type = "0800"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:669:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:5
|
LL | #[crate_type = "0800"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:17
|
LL | mod inner { #![feature(x0600)] }
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5
|
LL | #[feature(x0600)] fn f() { }
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:686:5
|
LL | #[feature(x0600)] struct S;
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:689:5
|
LL | #[feature(x0600)] type T = S;
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5
|
LL | #[feature(x0600)] impl S { }
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:17
|
LL | mod inner { #![no_main] }
| ^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:5
|
LL | #[no_main] fn f() { }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:702:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:5
|
LL | #[no_main] struct S;
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:5
|
LL | #[no_main] type T = S;
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
|
LL | #[no_main] impl S { }
| ^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:17
|
LL | mod inner { #![no_builtins] }
| ^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:718:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:5
|
LL | #[no_builtins] fn f() { }
| ^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
|
LL | #[no_builtins] struct S;
| ^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:5
|
LL | #[no_builtins] type T = S;
| ^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:5
|
LL | #[no_builtins] impl S { }
| ^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:17
|
LL | mod inner { #![recursion_limit="0200"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:5
|
LL | #[recursion_limit="0200"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:5
|
LL | #[recursion_limit="0200"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:5
|
LL | #[recursion_limit="0200"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
|
LL | #[recursion_limit="0200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:17
|
LL | mod inner { #![type_length_limit="0100"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:760:5
|
LL | #[type_length_limit="0100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5
|
LL | #[type_length_limit="0100"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5
|
LL | #[type_length_limit="0100"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:769:5
|
LL | #[type_length_limit="0100"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(stable_features)]` on by default
-warning: 172 warnings emitted
+warning: 173 warnings emitted
-#[link(name = "foo", cfg("rlib"))] //~ ERROR invalid argument for `cfg(..)`
+#[link(name = "foo", cfg("rlib"))] //~ ERROR link cfg must have a single predicate argument
extern "C" {}
fn main() {}
-error: invalid argument for `cfg(..)`
- --> $DIR/issue-43925.rs:1:26
+error: link cfg must have a single predicate argument
+ --> $DIR/issue-43925.rs:1:22
|
LL | #[link(name = "foo", cfg("rlib"))]
- | ^^^^^^
+ | ^^^^^^^^^^^
error: aborting due to previous error
-#[link(name = "foo", cfg())] //~ ERROR `cfg()` must have an argument
+#[link(name = "foo", cfg())] //~ ERROR link cfg must have a single predicate argument
extern "C" {}
fn main() {}
-error: `cfg()` must have an argument
+error: link cfg must have a single predicate argument
--> $DIR/issue-43926.rs:1:22
|
LL | #[link(name = "foo", cfg())]
+++ /dev/null
-#[link()] //~ ERROR: specified without `name =
-#[link(name = "")] //~ ERROR: with empty name
-#[link(name = "foo")]
-#[link(name = "foo", kind = "bar")] //~ ERROR: unknown kind
-extern "C" {}
-
-fn main() {}
+++ /dev/null
-error[E0459]: `#[link(...)]` specified without `name = "foo"`
- --> $DIR/bad-extern-link-attrs.rs:1:1
- |
-LL | #[link()]
- | ^^^^^^^^^ missing `name` argument
-
-error[E0454]: `#[link(name = "")]` given with empty name
- --> $DIR/bad-extern-link-attrs.rs:2:1
- |
-LL | #[link(name = "")]
- | ^^^^^^^^^^^^^^^^^^ empty name given
-
-error[E0458]: unknown kind: `bar`
- --> $DIR/bad-extern-link-attrs.rs:4:22
- |
-LL | #[link(name = "foo", kind = "bar")]
- | ---------------------^^^^^^^^^^^^--
- | |
- | unknown kind
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0454, E0458, E0459.
-For more information about an error, try `rustc --explain E0454`.
--- /dev/null
+// Top-level ill-formed
+#[link] //~ ERROR attribute must be of the form
+ //~| WARN this was previously accepted
+#[link = "foo"] //~ ERROR attribute must be of the form
+ //~| WARN this was previously accepted
+extern "C" {}
+
+fn main() {}
--- /dev/null
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+ --> $DIR/link-attr-validation-early.rs:2:1
+ |
+LL | #[link]
+ | ^^^^^^^
+ |
+ = note: `#[deny(ill_formed_attribute_input)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+ --> $DIR/link-attr-validation-early.rs:4:1
+ |
+LL | #[link = "foo"]
+ | ^^^^^^^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+#![feature(native_link_modifiers_verbatim)]
+#![feature(link_cfg)]
+
+// Top-level ill-formed
+#[link(name = "...", "literal")] //~ ERROR unexpected `#[link]` argument
+#[link(name = "...", unknown)] //~ ERROR unexpected `#[link]` argument
+extern "C" {}
+
+// Duplicate arguments
+#[link(name = "foo", name = "bar")] //~ ERROR multiple `name` arguments
+#[link(name = "...", kind = "dylib", kind = "bar")] //~ ERROR multiple `kind` arguments
+#[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] //~ ERROR multiple `modifiers` arguments
+#[link(name = "...", cfg(FALSE), cfg(FALSE))] //~ ERROR multiple `cfg` arguments
+#[link(wasm_import_module = "foo", wasm_import_module = "bar")] //~ ERROR multiple `wasm_import_module` arguments
+extern "C" {}
+
+// Ill-formed arguments
+#[link(name)] //~ ERROR link name must be of the form `name = "string"`
+ //~| ERROR `#[link]` attribute requires a `name = "string"` argument
+#[link(name())] //~ ERROR link name must be of the form `name = "string"`
+ //~| ERROR `#[link]` attribute requires a `name = "string"` argument
+#[link(name = "...", kind)] //~ ERROR link kind must be of the form `kind = "string"`
+#[link(name = "...", kind())] //~ ERROR link kind must be of the form `kind = "string"`
+#[link(name = "...", modifiers)] //~ ERROR link modifiers must be of the form `modifiers = "string"`
+#[link(name = "...", modifiers())] //~ ERROR link modifiers must be of the form `modifiers = "string"`
+#[link(name = "...", cfg)] //~ ERROR link cfg must be of the form `cfg(/* predicate */)`
+#[link(name = "...", cfg = "literal")] //~ ERROR link cfg must be of the form `cfg(/* predicate */)`
+#[link(name = "...", cfg("literal"))] //~ ERROR link cfg must have a single predicate argument
+#[link(name = "...", wasm_import_module)] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"`
+#[link(name = "...", wasm_import_module())] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"`
+extern "C" {}
+
+// Basic modifier validation
+#[link(name = "...", modifiers = "")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix
+#[link(name = "...", modifiers = "no-plus-minus")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix
+#[link(name = "...", modifiers = "+unknown")] //~ ERROR unknown linking modifier `unknown`
+#[link(name = "...", modifiers = "+verbatim,+verbatim")] //~ ERROR multiple `verbatim` modifiers
+extern "C" {}
+
+fn main() {}
--- /dev/null
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+ --> $DIR/link-attr-validation-late.rs:5:22
+ |
+LL | #[link(name = "...", "literal")]
+ | ^^^^^^^^^
+
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+ --> $DIR/link-attr-validation-late.rs:6:22
+ |
+LL | #[link(name = "...", unknown)]
+ | ^^^^^^^
+
+error: multiple `name` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:10:22
+ |
+LL | #[link(name = "foo", name = "bar")]
+ | ^^^^^^^^^^^^
+
+error: multiple `kind` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:11:38
+ |
+LL | #[link(name = "...", kind = "dylib", kind = "bar")]
+ | ^^^^^^^^^^^^
+
+error: multiple `modifiers` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:12:47
+ |
+LL | #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
+ | ^^^^^^^^^^^^^^^^^
+
+error: multiple `cfg` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:13:34
+ |
+LL | #[link(name = "...", cfg(FALSE), cfg(FALSE))]
+ | ^^^^^^^^^^
+
+error: multiple `wasm_import_module` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:14:36
+ |
+LL | #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: link name must be of the form `name = "string"`
+ --> $DIR/link-attr-validation-late.rs:18:8
+ |
+LL | #[link(name)]
+ | ^^^^
+
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
+ --> $DIR/link-attr-validation-late.rs:18:1
+ |
+LL | #[link(name)]
+ | ^^^^^^^^^^^^^ missing `name` argument
+
+error: link name must be of the form `name = "string"`
+ --> $DIR/link-attr-validation-late.rs:20:8
+ |
+LL | #[link(name())]
+ | ^^^^^^
+
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
+ --> $DIR/link-attr-validation-late.rs:20:1
+ |
+LL | #[link(name())]
+ | ^^^^^^^^^^^^^^^ missing `name` argument
+
+error: link kind must be of the form `kind = "string"`
+ --> $DIR/link-attr-validation-late.rs:22:22
+ |
+LL | #[link(name = "...", kind)]
+ | ^^^^
+
+error: link kind must be of the form `kind = "string"`
+ --> $DIR/link-attr-validation-late.rs:23:22
+ |
+LL | #[link(name = "...", kind())]
+ | ^^^^^^
+
+error: link modifiers must be of the form `modifiers = "string"`
+ --> $DIR/link-attr-validation-late.rs:24:22
+ |
+LL | #[link(name = "...", modifiers)]
+ | ^^^^^^^^^
+
+error: link modifiers must be of the form `modifiers = "string"`
+ --> $DIR/link-attr-validation-late.rs:25:22
+ |
+LL | #[link(name = "...", modifiers())]
+ | ^^^^^^^^^^^
+
+error: link cfg must be of the form `cfg(/* predicate */)`
+ --> $DIR/link-attr-validation-late.rs:26:22
+ |
+LL | #[link(name = "...", cfg)]
+ | ^^^
+
+error: link cfg must be of the form `cfg(/* predicate */)`
+ --> $DIR/link-attr-validation-late.rs:27:22
+ |
+LL | #[link(name = "...", cfg = "literal")]
+ | ^^^^^^^^^^^^^^^
+
+error: link cfg must have a single predicate argument
+ --> $DIR/link-attr-validation-late.rs:28:22
+ |
+LL | #[link(name = "...", cfg("literal"))]
+ | ^^^^^^^^^^^^^^
+
+error: wasm import module must be of the form `wasm_import_module = "string"`
+ --> $DIR/link-attr-validation-late.rs:29:22
+ |
+LL | #[link(name = "...", wasm_import_module)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: wasm import module must be of the form `wasm_import_module = "string"`
+ --> $DIR/link-attr-validation-late.rs:30:22
+ |
+LL | #[link(name = "...", wasm_import_module())]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
+ --> $DIR/link-attr-validation-late.rs:34:34
+ |
+LL | #[link(name = "...", modifiers = "")]
+ | ^^
+
+error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
+ --> $DIR/link-attr-validation-late.rs:35:34
+ |
+LL | #[link(name = "...", modifiers = "no-plus-minus")]
+ | ^^^^^^^^^^^^^^^
+
+error: unknown linking modifier `unknown`, expected one of: bundle, verbatim, whole-archive, as-needed
+ --> $DIR/link-attr-validation-late.rs:36:34
+ |
+LL | #[link(name = "...", modifiers = "+unknown")]
+ | ^^^^^^^^^^
+
+error: multiple `verbatim` modifiers in a single `modifiers` argument
+ --> $DIR/link-attr-validation-late.rs:37:34
+ |
+LL | #[link(name = "...", modifiers = "+verbatim,+verbatim")]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 24 previous errors
+
+For more information about this error, try `rustc --explain E0459`.
// compile-flags:-l static=
-// error-pattern: empty library name given via `-l`
+// error-pattern: library name must not be empty
fn main() {
}
-error: empty library name given via `-l`
-
-error: aborting due to previous error
+error: library name must not be empty
// compile-flags:-l bar=foo
-// error-pattern: unknown library kind `bar`, expected one of dylib, framework, or static
+// error-pattern: unknown library kind `bar`, expected one of: static, dylib, framework
fn main() {
}
-error: unknown library kind `bar`, expected one of dylib, framework, or static
+error: unknown library kind `bar`, expected one of: static, dylib, framework
// ignore-macos
// ignore-ios
// compile-flags:-l framework=foo
-// error-pattern: native frameworks are only available on macOS targets
+// error-pattern: library kind `framework` is only supported on Apple targets
fn main() {
}
-error: native frameworks are only available on macOS targets
+error: library kind `framework` is only supported on Apple targets
error: aborting due to previous error
// compile-flags:-l raw-dylib=foo
-// error-pattern: unknown library kind `raw-dylib`, expected one of dylib, framework, or static
+// error-pattern: unknown library kind `raw-dylib`, expected one of: static, dylib, framework
fn main() {
}
-error: unknown library kind `raw-dylib`, expected one of dylib, framework, or static
+error: unknown library kind `raw-dylib`, expected one of: static, dylib, framework
// Unspecified kind should fail with an error
// compile-flags: -l =mylib
-// error-pattern: unknown library kind ``, expected one of dylib, framework, or static
+// error-pattern: unknown library kind ``, expected one of: static, dylib, framework
fn main() {}
-error: unknown library kind ``, expected one of dylib, framework, or static
+error: unknown library kind ``, expected one of: static, dylib, framework
// Unspecified kind should fail with an error
// compile-flags: -l :+bundle=mylib
-// error-pattern: unknown library kind ``, expected one of dylib, framework, or static
+// error-pattern: unknown library kind ``, expected one of: static, dylib, framework
fn main() {}
-error: unknown library kind ``, expected one of dylib, framework, or static
+error: unknown library kind ``, expected one of: static, dylib, framework
-error: duplicating linking modifier is currently unstable and only accepted on the nightly compiler
+error: multiple `whole-archive` modifiers in a single `-l` option
#![feature(native_link_modifiers_bundle)]
#[link(name = "foo")]
-#[link( //~ ERROR multiple `modifiers` arguments in a single `#[link]` attribute
+#[link(
name = "bar",
kind = "static",
modifiers = "+whole-archive,-whole-archive",
- //~^ ERROR same modifier is used multiple times in a single `modifiers` argument
+ //~^ ERROR multiple `whole-archive` modifiers in a single `modifiers` argument
modifiers = "+bundle"
+ //~^ ERROR multiple `modifiers` arguments in a single `#[link]` attribute
)]
extern "C" {}
//~^ ERROR overriding linking modifiers from command line is not supported
-error: same modifier is used multiple times in a single `modifiers` argument
- --> $DIR/modifiers-override.rs:9:5
+error: multiple `modifiers` arguments in a single `#[link]` attribute
+ --> $DIR/modifiers-override.rs:11:5
|
-LL | modifiers = "+whole-archive,-whole-archive",
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | modifiers = "+bundle"
+ | ^^^^^^^^^^^^^^^^^^^^^
-error: multiple `modifiers` arguments in a single `#[link]` attribute
- --> $DIR/modifiers-override.rs:6:1
+error: multiple `whole-archive` modifiers in a single `modifiers` argument
+ --> $DIR/modifiers-override.rs:9:17
|
-LL | / #[link(
-LL | | name = "bar",
-LL | | kind = "static",
-LL | | modifiers = "+whole-archive,-whole-archive",
-LL | |
-LL | | modifiers = "+bundle"
-LL | | )]
- | |__^
+LL | modifiers = "+whole-archive,-whole-archive",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: overriding linking modifiers from command line is not supported
- --> $DIR/modifiers-override.rs:13:1
+ --> $DIR/modifiers-override.rs:14:1
|
LL | extern "C" {}
| ^^^^^^^^^^^^^
error: overriding linking modifiers from command line is not supported
- --> $DIR/modifiers-override.rs:13:1
+ --> $DIR/modifiers-override.rs:14:1
|
LL | extern "C" {}
| ^^^^^^^^^^^^^
#[link(name = "foo", kind = "framework")]
extern "C" {}
-//~^^ ERROR: native frameworks are only available on macOS
+//~^^ ERROR: link kind `framework` is only supported on Apple targets
fn main() {}
-error[E0455]: native frameworks are only available on macOS targets
- --> $DIR/osx-frameworks.rs:3:1
+error[E0455]: link kind `framework` is only supported on Apple targets
+ --> $DIR/osx-frameworks.rs:3:29
|
LL | #[link(name = "foo", kind = "framework")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^
error: aborting due to previous error
--- /dev/null
+// compile-flags: -l dylib=foo:bar
+// error-pattern: overriding linking modifiers from command line is not supported
+
+#![feature(native_link_modifiers_as_needed)]
+
+#![crate_type = "lib"]
+
+#[link(name = "foo", kind = "dylib", modifiers = "-as-needed")]
+extern "C" {}
--- /dev/null
+error: overriding linking modifiers from command line is not supported
+ --> $DIR/rename-modifiers.rs:9:1
+ |
+LL | extern "C" {}
+ | ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
#![feature(raw_dylib)]
//~^ WARNING: the feature `raw_dylib` is incomplete
#[link(name = "foo", kind = "raw-dylib")]
-//~^ ERROR: `#[link(...)]` with `kind = "raw-dylib"` only supported on Windows
+//~^ ERROR: link kind `raw-dylib` is only supported on Windows targets
extern "C" {}
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
-error: `#[link(...)]` with `kind = "raw-dylib"` only supported on Windows
- --> $DIR/raw-dylib-windows-only.rs:5:1
+error[E0455]: link kind `raw-dylib` is only supported on Windows targets
+ --> $DIR/raw-dylib-windows-only.rs:5:29
|
LL | #[link(name = "foo", kind = "raw-dylib")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^
error: aborting due to previous error; 1 warning emitted
+For more information about this error, try `rustc --explain E0455`.
+#![feature(link_cfg)]
+
#[link(name = "...", wasm_import_module)] //~ ERROR: must be of the form
extern "C" {}
#[link(name = "...", wasm_import_module())] //~ ERROR: must be of the form
extern "C" {}
+#[link(wasm_import_module = "foo", name = "bar")] //~ ERROR: `wasm_import_module` is incompatible with other arguments
+extern "C" {}
+
+#[link(wasm_import_module = "foo", kind = "dylib")] //~ ERROR: `wasm_import_module` is incompatible with other arguments
+extern "C" {}
+
+#[link(wasm_import_module = "foo", cfg(FALSE))] //~ ERROR: `wasm_import_module` is incompatible with other arguments
+extern "C" {}
+
fn main() {}
-error: must be of the form `#[link(wasm_import_module = "...")]`
- --> $DIR/wasm-import-module.rs:1:22
+error: wasm import module must be of the form `wasm_import_module = "string"`
+ --> $DIR/wasm-import-module.rs:3:22
|
LL | #[link(name = "...", wasm_import_module)]
| ^^^^^^^^^^^^^^^^^^
-error: must be of the form `#[link(wasm_import_module = "...")]`
- --> $DIR/wasm-import-module.rs:4:22
+error: wasm import module must be of the form `wasm_import_module = "string"`
+ --> $DIR/wasm-import-module.rs:6:22
|
LL | #[link(name = "...", wasm_import_module(x))]
| ^^^^^^^^^^^^^^^^^^^^^
-error: must be of the form `#[link(wasm_import_module = "...")]`
- --> $DIR/wasm-import-module.rs:7:22
+error: wasm import module must be of the form `wasm_import_module = "string"`
+ --> $DIR/wasm-import-module.rs:9:22
|
LL | #[link(name = "...", wasm_import_module())]
| ^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 3 previous errors
+error: `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
+ --> $DIR/wasm-import-module.rs:12:8
+ |
+LL | #[link(wasm_import_module = "foo", name = "bar")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
+ --> $DIR/wasm-import-module.rs:15:8
+ |
+LL | #[link(wasm_import_module = "foo", kind = "dylib")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
+ --> $DIR/wasm-import-module.rs:18:8
+ |
+LL | #[link(wasm_import_module = "foo", cfg(FALSE))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
-Subproject commit 3b8b6aa8b689971d3b8776cefe3d809501e1b8ff
+Subproject commit 19ef76477c0ea1722f91ab6b1c2dcb365f064992