Skip to content

Commit 75a0d20

Browse files
committed
Auto merge of rust-lang#129705 - matthiaskrgr:rollup-zqpqyyl, r=matthiaskrgr
Rollup of 11 pull requests Successful merges: - rust-lang#128166 (Improved `checked_isqrt` and `isqrt` methods) - rust-lang#129170 (Add an ability to convert between `Span` and `visit::Location`) - rust-lang#129366 (linker: Synchronize native library search in rustc and linker) - rust-lang#129467 (derive(SmartPointer): assume pointee from the single generic and better error messages) - rust-lang#129494 (format code in tests/ui/threads-sendsync) - rust-lang#129527 (Don't use `TyKind` in a lint) - rust-lang#129617 (Update books) - rust-lang#129673 (Add fmt::Debug to sync::Weak<T, A>) - rust-lang#129683 (copysign with sign being a NaN can have non-portable results) - rust-lang#129689 (Move `'tcx` lifetime off of impl and onto methods for `CrateMetadataRef`) - rust-lang#129695 (Fix path to run clippy on rustdoc) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 100fde5 + 7320663 commit 75a0d20

File tree

97 files changed

+1318
-475
lines changed

Some content is hidden

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

97 files changed

+1318
-475
lines changed

compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs

+47-28
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1111
use rustc_expand::base::{Annotatable, ExtCtxt};
1212
use rustc_span::symbol::{sym, Ident};
1313
use rustc_span::{Span, Symbol};
14-
use smallvec::{smallvec, SmallVec};
1514
use thin_vec::{thin_vec, ThinVec};
1615

1716
macro_rules! path {
@@ -68,43 +67,63 @@ pub(crate) fn expand_deriving_smart_ptr(
6867
};
6968

7069
// Convert generic parameters (from the struct) into generic args.
71-
let mut pointee_param = None;
72-
let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![];
73-
let self_params = generics
70+
let self_params: Vec<_> = generics
7471
.params
7572
.iter()
76-
.enumerate()
77-
.map(|(idx, p)| match p.kind {
73+
.map(|p| match p.kind {
7874
GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
79-
GenericParamKind::Type { .. } => {
80-
if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) {
81-
if pointee_param.is_some() {
82-
multiple_pointee_diag.push(cx.dcx().struct_span_err(
83-
p.span(),
84-
"`SmartPointer` can only admit one type as pointee",
85-
));
86-
} else {
87-
pointee_param = Some(idx);
88-
}
89-
}
90-
GenericArg::Type(cx.ty_ident(p.span(), p.ident))
91-
}
75+
GenericParamKind::Type { .. } => GenericArg::Type(cx.ty_ident(p.span(), p.ident)),
9276
GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
9377
})
94-
.collect::<Vec<_>>();
95-
let Some(pointee_param_idx) = pointee_param else {
78+
.collect();
79+
let type_params: Vec<_> = generics
80+
.params
81+
.iter()
82+
.enumerate()
83+
.filter_map(|(idx, p)| {
84+
if let GenericParamKind::Type { .. } = p.kind {
85+
Some((idx, p.span(), p.attrs().iter().any(|attr| attr.has_name(sym::pointee))))
86+
} else {
87+
None
88+
}
89+
})
90+
.collect();
91+
92+
let pointee_param_idx = if type_params.is_empty() {
93+
// `#[derive(SmartPointer)]` requires at least one generic type on the target `struct`
9694
cx.dcx().struct_span_err(
9795
span,
98-
"At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits",
96+
"`SmartPointer` can only be derived on `struct`s that are generic over at least one type",
9997
).emit();
10098
return;
101-
};
102-
if !multiple_pointee_diag.is_empty() {
103-
for diag in multiple_pointee_diag {
104-
diag.emit();
99+
} else if type_params.len() == 1 {
100+
// Regardless of the only type param being designed as `#[pointee]` or not, we can just use it as such
101+
type_params[0].0
102+
} else {
103+
let mut pointees = type_params
104+
.iter()
105+
.filter_map(|&(idx, span, is_pointee)| is_pointee.then_some((idx, span)))
106+
.fuse();
107+
match (pointees.next(), pointees.next()) {
108+
(Some((idx, _span)), None) => idx,
109+
(None, _) => {
110+
cx.dcx().struct_span_err(
111+
span,
112+
"exactly one generic type parameter must be marked as #[pointee] to derive SmartPointer traits",
113+
).emit();
114+
return;
115+
}
116+
(Some((_, one)), Some((_, another))) => {
117+
cx.dcx()
118+
.struct_span_err(
119+
vec![one, another],
120+
"only one type parameter can be marked as `#[pointee]` when deriving SmartPointer traits",
121+
)
122+
.emit();
123+
return;
124+
}
105125
}
106-
return;
107-
}
126+
};
108127

109128
// Create the type of `self`.
110129
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());

compiler/rustc_codegen_ssa/src/back/link.rs

+15-46
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::BTreeSet;
22
use std::ffi::OsString;
33
use std::fs::{read, File, OpenOptions};
44
use std::io::{BufWriter, Write};
5-
use std::ops::Deref;
5+
use std::ops::{ControlFlow, Deref};
66
use std::path::{Path, PathBuf};
77
use std::process::{ExitStatus, Output, Stdio};
88
use std::{env, fmt, fs, io, mem, str};
@@ -18,8 +18,8 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
1818
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
1919
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
2020
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
21-
use rustc_metadata::find_native_static_library;
2221
use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
22+
use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
2323
use rustc_middle::bug;
2424
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2525
use rustc_middle::middle::dependency_format::Linkage;
@@ -2110,50 +2110,19 @@ fn add_library_search_dirs(
21102110
return;
21112111
}
21122112

2113-
// Library search paths explicitly supplied by user (`-L` on the command line).
2114-
for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
2115-
cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir));
2116-
}
2117-
for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
2118-
// Contrary to the `-L` docs only framework-specific paths are considered here.
2119-
if search_path.kind != PathKind::All {
2120-
cmd.framework_path(&search_path.dir);
2121-
}
2122-
}
2123-
2124-
// The toolchain ships some native library components and self-contained linking was enabled.
2125-
// Add the self-contained library directory to search paths.
2126-
if self_contained_components.intersects(
2127-
LinkSelfContainedComponents::LIBC
2128-
| LinkSelfContainedComponents::UNWIND
2129-
| LinkSelfContainedComponents::MINGW,
2130-
) {
2131-
let lib_path = sess.target_tlib_path.dir.join("self-contained");
2132-
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
2133-
}
2134-
2135-
// Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
2136-
// library directory instead of the self-contained directories.
2137-
// Sanitizer libraries have the same issue and are also linked by name on Apple targets.
2138-
// The targets here should be in sync with `copy_third_party_objects` in bootstrap.
2139-
// FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
2140-
// and sanitizers to self-contained directory, and stop adding this search path.
2141-
if sess.target.vendor == "fortanix"
2142-
|| sess.target.os == "linux"
2143-
|| sess.target.os == "fuchsia"
2144-
|| sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
2145-
{
2146-
cmd.include_path(&fix_windows_verbatim_for_gcc(&sess.target_tlib_path.dir));
2147-
}
2148-
2149-
// Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
2150-
// we must have the support library stubs in the library search path (#121430).
2151-
if let Some(sdk_root) = apple_sdk_root
2152-
&& sess.target.llvm_target.contains("macabi")
2153-
{
2154-
cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib"));
2155-
cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"));
2156-
}
2113+
walk_native_lib_search_dirs(
2114+
sess,
2115+
self_contained_components,
2116+
apple_sdk_root,
2117+
|dir, is_framework| {
2118+
if is_framework {
2119+
cmd.framework_path(dir);
2120+
} else {
2121+
cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
2122+
}
2123+
ControlFlow::<()>::Continue(())
2124+
},
2125+
);
21572126
}
21582127

21592128
/// Add options making relocation sections in the produced ELF files read-only

compiler/rustc_codegen_ssa/src/back/linker.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{env, iter, mem, str};
77

88
use cc::windows_registry;
99
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
10-
use rustc_metadata::find_native_static_library;
10+
use rustc_metadata::{find_native_static_library, try_find_native_static_library};
1111
use rustc_middle::bug;
1212
use rustc_middle::middle::dependency_format::Linkage;
1313
use rustc_middle::middle::exported_symbols;
@@ -891,9 +891,15 @@ impl<'a> Linker for MsvcLinker<'a> {
891891
}
892892

893893
fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) {
894-
let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
895-
let suffix = if verbatim { "" } else { ".lib" };
896-
self.link_arg(format!("{prefix}{name}{suffix}"));
894+
// On MSVC-like targets rustc supports static libraries using alternative naming
895+
// scheme (`libfoo.a`) unsupported by linker, search for such libraries manually.
896+
if let Some(path) = try_find_native_static_library(self.sess, name, verbatim) {
897+
self.link_staticlib_by_path(&path, whole_archive);
898+
} else {
899+
let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
900+
let suffix = if verbatim { "" } else { ".lib" };
901+
self.link_arg(format!("{prefix}{name}{suffix}"));
902+
}
897903
}
898904

899905
fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) {

compiler/rustc_lint/src/foreign_modules.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,6 @@ fn structurally_same_type_impl<'tcx>(
265265
} else {
266266
// Do a full, depth-first comparison between the two.
267267
use rustc_type_ir::TyKind::*;
268-
let a_kind = a.kind();
269-
let b_kind = b.kind();
270268

271269
let compare_layouts = |a, b| -> Result<bool, &'tcx LayoutError<'tcx>> {
272270
debug!("compare_layouts({:?}, {:?})", a, b);
@@ -281,12 +279,11 @@ fn structurally_same_type_impl<'tcx>(
281279
Ok(a_layout == b_layout)
282280
};
283281

284-
#[allow(rustc::usage_of_ty_tykind)]
285282
let is_primitive_or_pointer =
286-
|kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..));
283+
|ty: Ty<'tcx>| ty.is_primitive() || matches!(ty.kind(), RawPtr(..) | Ref(..));
287284

288285
ensure_sufficient_stack(|| {
289-
match (a_kind, b_kind) {
286+
match (a.kind(), b.kind()) {
290287
(Adt(a_def, _), Adt(b_def, _)) => {
291288
// We can immediately rule out these types as structurally same if
292289
// their layouts differ.
@@ -382,17 +379,21 @@ fn structurally_same_type_impl<'tcx>(
382379

383380
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
384381
// enum layout optimisation is being applied.
385-
(Adt(..), other_kind) | (other_kind, Adt(..))
386-
if is_primitive_or_pointer(other_kind) =>
387-
{
388-
let (primitive, adt) =
389-
if is_primitive_or_pointer(a.kind()) { (a, b) } else { (b, a) };
390-
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, adt, ckind) {
391-
ty == primitive
382+
(Adt(..), _) if is_primitive_or_pointer(b) => {
383+
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
384+
ty == b
392385
} else {
393386
compare_layouts(a, b).unwrap_or(false)
394387
}
395388
}
389+
(_, Adt(..)) if is_primitive_or_pointer(a) => {
390+
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
391+
ty == a
392+
} else {
393+
compare_layouts(a, b).unwrap_or(false)
394+
}
395+
}
396+
396397
// Otherwise, just compare the layouts. This may fail to lint for some
397398
// incompatible types, but at the very least, will stop reads into
398399
// uninitialised memory.

compiler/rustc_metadata/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![allow(rustc::potential_query_instability)]
44
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
55
#![doc(rust_logo)]
6+
#![feature(control_flow_enum)]
67
#![feature(coroutines)]
78
#![feature(decl_macro)]
89
#![feature(error_iter)]
@@ -34,7 +35,9 @@ pub mod locator;
3435

3536
pub use creader::{load_symbol_from_dylib, DylibError};
3637
pub use fs::{emit_wrapper_file, METADATA_FILENAME};
37-
pub use native_libs::find_native_static_library;
38+
pub use native_libs::{
39+
find_native_static_library, try_find_native_static_library, walk_native_lib_search_dirs,
40+
};
3841
pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER};
3942

4043
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

compiler/rustc_metadata/src/native_libs.rs

+82-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use std::path::PathBuf;
1+
use std::ops::ControlFlow;
2+
use std::path::{Path, PathBuf};
23

34
use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
45
use rustc_attr as attr;
@@ -16,10 +17,68 @@ use rustc_session::Session;
1617
use rustc_span::def_id::{DefId, LOCAL_CRATE};
1718
use rustc_span::symbol::{sym, Symbol};
1819
use rustc_target::spec::abi::Abi;
20+
use rustc_target::spec::LinkSelfContainedComponents;
1921

2022
use crate::{errors, fluent_generated};
2123

22-
pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
24+
pub fn walk_native_lib_search_dirs<R>(
25+
sess: &Session,
26+
self_contained_components: LinkSelfContainedComponents,
27+
apple_sdk_root: Option<&Path>,
28+
mut f: impl FnMut(&Path, bool /*is_framework*/) -> ControlFlow<R>,
29+
) -> ControlFlow<R> {
30+
// Library search paths explicitly supplied by user (`-L` on the command line).
31+
for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
32+
f(&search_path.dir, false)?;
33+
}
34+
for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
35+
// Frameworks are looked up strictly in framework-specific paths.
36+
if search_path.kind != PathKind::All {
37+
f(&search_path.dir, true)?;
38+
}
39+
}
40+
41+
// The toolchain ships some native library components and self-contained linking was enabled.
42+
// Add the self-contained library directory to search paths.
43+
if self_contained_components.intersects(
44+
LinkSelfContainedComponents::LIBC
45+
| LinkSelfContainedComponents::UNWIND
46+
| LinkSelfContainedComponents::MINGW,
47+
) {
48+
f(&sess.target_tlib_path.dir.join("self-contained"), false)?;
49+
}
50+
51+
// Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
52+
// library directory instead of the self-contained directories.
53+
// Sanitizer libraries have the same issue and are also linked by name on Apple targets.
54+
// The targets here should be in sync with `copy_third_party_objects` in bootstrap.
55+
// FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
56+
// and sanitizers to self-contained directory, and stop adding this search path.
57+
if sess.target.vendor == "fortanix"
58+
|| sess.target.os == "linux"
59+
|| sess.target.os == "fuchsia"
60+
|| sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
61+
{
62+
f(&sess.target_tlib_path.dir, false)?;
63+
}
64+
65+
// Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
66+
// we must have the support library stubs in the library search path (#121430).
67+
if let Some(sdk_root) = apple_sdk_root
68+
&& sess.target.llvm_target.contains("macabi")
69+
{
70+
f(&sdk_root.join("System/iOSSupport/usr/lib"), false)?;
71+
f(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"), true)?;
72+
}
73+
74+
ControlFlow::Continue(())
75+
}
76+
77+
pub fn try_find_native_static_library(
78+
sess: &Session,
79+
name: &str,
80+
verbatim: bool,
81+
) -> Option<PathBuf> {
2382
let formats = if verbatim {
2483
vec![("".into(), "".into())]
2584
} else {
@@ -30,16 +89,29 @@ pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) ->
3089
if os == unix { vec![os] } else { vec![os, unix] }
3190
};
3291

33-
for path in sess.target_filesearch(PathKind::Native).search_paths() {
34-
for (prefix, suffix) in &formats {
35-
let test = path.dir.join(format!("{prefix}{name}{suffix}"));
36-
if test.exists() {
37-
return test;
92+
// FIXME: Account for self-contained linking settings and Apple SDK.
93+
walk_native_lib_search_dirs(
94+
sess,
95+
LinkSelfContainedComponents::empty(),
96+
None,
97+
|dir, is_framework| {
98+
if !is_framework {
99+
for (prefix, suffix) in &formats {
100+
let test = dir.join(format!("{prefix}{name}{suffix}"));
101+
if test.exists() {
102+
return ControlFlow::Break(test);
103+
}
104+
}
38105
}
39-
}
40-
}
106+
ControlFlow::Continue(())
107+
},
108+
)
109+
.break_value()
110+
}
41111

42-
sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim));
112+
pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
113+
try_find_native_static_library(sess, name, verbatim)
114+
.unwrap_or_else(|| sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim)))
43115
}
44116

45117
fn find_bundled_library(

0 commit comments

Comments
 (0)