Skip to content

Commit d44f647

Browse files
committed
Auto merge of #84982 - Dylan-DPC:rollup-q4cbec2, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #83507 (Implement RFC 2951: Native link modifiers) - #84328 (Stablize {HashMap,BTreeMap}::into_{keys,values}) - #84712 (Simplify chdir implementation and minimize unsafe block) - #84851 (:arrow_up: rust-analyzer) - #84923 (Only compute Obligation `cache_key` once in `register_obligation_at`) - #84945 (E0583: Include secondary path in error message) - #84949 (Fix typo in `MaybeUninit::array_assume_init` safety comment) - #84950 (Revert PR 83866) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 109248a + ccc820e commit d44f647

File tree

60 files changed

+885
-273
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+885
-273
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+39
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,45 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
326326
);
327327
}
328328
}
329+
330+
// Check for unstable modifiers on `#[link(..)]` attribute
331+
if self.sess.check_name(attr, sym::link) {
332+
for nested_meta in attr.meta_item_list().unwrap_or_default() {
333+
if nested_meta.has_name(sym::modifiers) {
334+
gate_feature_post!(
335+
self,
336+
native_link_modifiers,
337+
nested_meta.span(),
338+
"native link modifiers are experimental"
339+
);
340+
341+
if let Some(modifiers) = nested_meta.value_str() {
342+
for modifier in modifiers.as_str().split(',') {
343+
if let Some(modifier) = modifier.strip_prefix(&['+', '-'][..]) {
344+
macro_rules! gate_modifier { ($($name:literal => $feature:ident)*) => {
345+
$(if modifier == $name {
346+
let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable");
347+
gate_feature_post!(
348+
self,
349+
$feature,
350+
nested_meta.name_value_literal_span().unwrap(),
351+
msg
352+
);
353+
})*
354+
}}
355+
356+
gate_modifier!(
357+
"bundle" => native_link_modifiers_bundle
358+
"verbatim" => native_link_modifiers_verbatim
359+
"whole-archive" => native_link_modifiers_whole_archive
360+
"as-needed" => native_link_modifiers_as_needed
361+
);
362+
}
363+
}
364+
}
365+
}
366+
}
367+
}
329368
}
330369

331370
fn visit_item(&mut self, i: &'a ast::Item) {

compiler/rustc_codegen_cranelift/src/archive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
8585
));
8686
}
8787

88-
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol) {
89-
let location = find_library(name, &self.lib_search_paths, self.sess);
88+
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol, verbatim: bool) {
89+
let location = find_library(name, verbatim, &self.lib_search_paths, self.sess);
9090
self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| {
9191
panic!("failed to add native library {}: {}", location.to_string_lossy(), e);
9292
});

compiler/rustc_codegen_llvm/src/back/archive.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
100100

101101
/// Adds all of the contents of a native library to this archive. This will
102102
/// search in the relevant locations for a library named `name`.
103-
fn add_native_library(&mut self, name: Symbol) {
104-
let location = find_library(name, &self.config.lib_search_paths, self.config.sess);
103+
fn add_native_library(&mut self, name: Symbol, verbatim: bool) {
104+
let location =
105+
find_library(name, verbatim, &self.config.lib_search_paths, self.config.sess);
105106
self.add_archive(&location, |_| false).unwrap_or_else(|e| {
106107
self.config.sess.fatal(&format!(
107108
"failed to add native library {}: {}",

compiler/rustc_codegen_ssa/src/back/archive.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,19 @@ use rustc_span::symbol::Symbol;
44
use std::io;
55
use std::path::{Path, PathBuf};
66

7-
pub fn find_library(name: Symbol, search_paths: &[PathBuf], sess: &Session) -> PathBuf {
7+
pub fn find_library(
8+
name: Symbol,
9+
verbatim: bool,
10+
search_paths: &[PathBuf],
11+
sess: &Session,
12+
) -> PathBuf {
813
// On Windows, static libraries sometimes show up as libfoo.a and other
914
// times show up as foo.lib
10-
let oslibname =
11-
format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix);
15+
let oslibname = if verbatim {
16+
name.to_string()
17+
} else {
18+
format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix)
19+
};
1220
let unixlibname = format!("lib{}.a", name);
1321

1422
for path in search_paths {
@@ -45,7 +53,7 @@ pub trait ArchiveBuilder<'a> {
4553
lto: bool,
4654
skip_objects: bool,
4755
) -> io::Result<()>;
48-
fn add_native_library(&mut self, name: Symbol);
56+
fn add_native_library(&mut self, name: Symbol, verbatim: bool);
4957
fn update_symbols(&mut self);
5058

5159
fn build(self);

compiler/rustc_codegen_ssa/src/back/link.rs

+47-26
Original file line numberDiff line numberDiff line change
@@ -329,15 +329,15 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
329329
// metadata of the rlib we're generating somehow.
330330
for lib in codegen_results.crate_info.used_libraries.iter() {
331331
match lib.kind {
332-
NativeLibKind::StaticBundle => {}
333-
NativeLibKind::StaticNoBundle
334-
| NativeLibKind::Dylib
335-
| NativeLibKind::Framework
332+
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
333+
NativeLibKind::Static { bundle: Some(false), .. }
334+
| NativeLibKind::Dylib { .. }
335+
| NativeLibKind::Framework { .. }
336336
| NativeLibKind::RawDylib
337337
| NativeLibKind::Unspecified => continue,
338338
}
339339
if let Some(name) = lib.name {
340-
ab.add_native_library(name);
340+
ab.add_native_library(name, lib.verbatim.unwrap_or(false));
341341
}
342342
}
343343

@@ -430,9 +430,10 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
430430
// Clearly this is not sufficient for a general purpose feature, and
431431
// we'd want to read from the library's metadata to determine which
432432
// object files come from where and selectively skip them.
433-
let skip_object_files = native_libs
434-
.iter()
435-
.any(|lib| lib.kind == NativeLibKind::StaticBundle && !relevant_lib(sess, lib));
433+
let skip_object_files = native_libs.iter().any(|lib| {
434+
matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
435+
&& !relevant_lib(sess, lib)
436+
});
436437
ab.add_rlib(
437438
path,
438439
&name.as_str(),
@@ -931,7 +932,7 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
931932
let path = find_sanitizer_runtime(&sess, &filename);
932933
let rpath = path.to_str().expect("non-utf8 component in path");
933934
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
934-
linker.link_dylib(Symbol::intern(&filename));
935+
linker.link_dylib(Symbol::intern(&filename), false, true);
935936
} else {
936937
let filename = format!("librustc{}_rt.{}.a", channel, name);
937938
let path = find_sanitizer_runtime(&sess, &filename).join(&filename);
@@ -1080,21 +1081,25 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
10801081
.filter_map(|lib| {
10811082
let name = lib.name?;
10821083
match lib.kind {
1083-
NativeLibKind::StaticNoBundle
1084-
| NativeLibKind::Dylib
1084+
NativeLibKind::Static { bundle: Some(false), .. }
1085+
| NativeLibKind::Dylib { .. }
10851086
| NativeLibKind::Unspecified => {
1087+
let verbatim = lib.verbatim.unwrap_or(false);
10861088
if sess.target.is_like_msvc {
1087-
Some(format!("{}.lib", name))
1089+
Some(format!("{}{}", name, if verbatim { "" } else { ".lib" }))
1090+
} else if sess.target.linker_is_gnu {
1091+
Some(format!("-l{}{}", if verbatim { ":" } else { "" }, name))
10881092
} else {
10891093
Some(format!("-l{}", name))
10901094
}
10911095
}
1092-
NativeLibKind::Framework => {
1096+
NativeLibKind::Framework { .. } => {
10931097
// ld-only syntax, since there are no frameworks in MSVC
10941098
Some(format!("-framework {}", name))
10951099
}
10961100
// These are included, no need to print them
1097-
NativeLibKind::StaticBundle | NativeLibKind::RawDylib => None,
1101+
NativeLibKind::Static { bundle: None | Some(true), .. }
1102+
| NativeLibKind::RawDylib => None,
10981103
}
10991104
})
11001105
.collect();
@@ -1812,11 +1817,20 @@ fn add_local_native_libraries(
18121817
Some(l) => l,
18131818
None => continue,
18141819
};
1820+
let verbatim = lib.verbatim.unwrap_or(false);
18151821
match lib.kind {
1816-
NativeLibKind::Dylib | NativeLibKind::Unspecified => cmd.link_dylib(name),
1817-
NativeLibKind::Framework => cmd.link_framework(name),
1818-
NativeLibKind::StaticNoBundle => cmd.link_staticlib(name),
1819-
NativeLibKind::StaticBundle => cmd.link_whole_staticlib(name, &search_path),
1822+
NativeLibKind::Dylib { as_needed } => {
1823+
cmd.link_dylib(name, verbatim, as_needed.unwrap_or(true))
1824+
}
1825+
NativeLibKind::Unspecified => cmd.link_dylib(name, verbatim, true),
1826+
NativeLibKind::Framework { as_needed } => {
1827+
cmd.link_framework(name, as_needed.unwrap_or(true))
1828+
}
1829+
NativeLibKind::Static { bundle: None | Some(true), .. }
1830+
| NativeLibKind::Static { whole_archive: Some(true), .. } => {
1831+
cmd.link_whole_staticlib(name, verbatim, &search_path);
1832+
}
1833+
NativeLibKind::Static { .. } => cmd.link_staticlib(name, verbatim),
18201834
NativeLibKind::RawDylib => {
18211835
// FIXME(#58713): Proper handling for raw dylibs.
18221836
bug!("raw_dylib feature not yet implemented");
@@ -2000,9 +2014,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
20002014
// there's a static library that's not relevant we skip all object
20012015
// files.
20022016
let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
2003-
let skip_native = native_libs
2004-
.iter()
2005-
.any(|lib| lib.kind == NativeLibKind::StaticBundle && !relevant_lib(sess, lib));
2017+
let skip_native = native_libs.iter().any(|lib| {
2018+
matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
2019+
&& !relevant_lib(sess, lib)
2020+
});
20062021

20072022
if (!are_upstream_rust_objects_already_included(sess)
20082023
|| ignored_for_lto(sess, &codegen_results.crate_info, cnum))
@@ -2144,22 +2159,28 @@ fn add_upstream_native_libraries(
21442159
if !relevant_lib(sess, &lib) {
21452160
continue;
21462161
}
2162+
let verbatim = lib.verbatim.unwrap_or(false);
21472163
match lib.kind {
2148-
NativeLibKind::Dylib | NativeLibKind::Unspecified => cmd.link_dylib(name),
2149-
NativeLibKind::Framework => cmd.link_framework(name),
2150-
NativeLibKind::StaticNoBundle => {
2164+
NativeLibKind::Dylib { as_needed } => {
2165+
cmd.link_dylib(name, verbatim, as_needed.unwrap_or(true))
2166+
}
2167+
NativeLibKind::Unspecified => cmd.link_dylib(name, verbatim, true),
2168+
NativeLibKind::Framework { as_needed } => {
2169+
cmd.link_framework(name, as_needed.unwrap_or(true))
2170+
}
2171+
NativeLibKind::Static { bundle: Some(false), .. } => {
21512172
// Link "static-nobundle" native libs only if the crate they originate from
21522173
// is being linked statically to the current crate. If it's linked dynamically
21532174
// or is an rlib already included via some other dylib crate, the symbols from
21542175
// native libs will have already been included in that dylib.
21552176
if data[cnum.as_usize() - 1] == Linkage::Static {
2156-
cmd.link_staticlib(name)
2177+
cmd.link_staticlib(name, verbatim)
21572178
}
21582179
}
21592180
// ignore statically included native libraries here as we've
21602181
// already included them when we included the rust library
21612182
// previously
2162-
NativeLibKind::StaticBundle => {}
2183+
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
21632184
NativeLibKind::RawDylib => {
21642185
// FIXME(#58713): Proper handling for raw dylibs.
21652186
bug!("raw_dylib feature not yet implemented");

0 commit comments

Comments
 (0)