Skip to content

Commit

Permalink
Auto merge of rust-lang#134057 - GuillaumeGomez:rollup-kzesbgh, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

Rollup of 9 pull requests

Successful merges:

 - rust-lang#133184 (wasi/fs: Improve stopping condition for <ReadDir as Iterator>::next)
 - rust-lang#133955 (Pass the arch rather than full target name to windows_registry::find_tool)
 - rust-lang#133967 ([AIX] Pass -bnoipath when adding rust upstream dynamic crates)
 - rust-lang#133970 ([AIX] Replace sa_sigaction with sa_union.__su_sigaction for AIX)
 - rust-lang#133980 ([AIX] Remove option "-n" from AIX "ln" command)
 - rust-lang#133996 (Move most tests for `-l` and `#[link(..)]` into `tests/ui/link-native-libs`)
 - rust-lang#134017 (Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction)
 - rust-lang#134023 (handle cygwin environment in `install::sanitize_sh`)
 - rust-lang#134053 (rustdoc: rename `issue-\d+.rs` tests to have meaningful names (part 10))

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 9, 2024
2 parents f6cb952 + 0a7c477 commit 1da727e
Show file tree
Hide file tree
Showing 85 changed files with 290 additions and 194 deletions.
17 changes: 11 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,12 +1015,8 @@ fn link_natively(
&& (code < 1000 || code > 9999)
{
let is_vs_installed = windows_registry::find_vs_version().is_ok();
// FIXME(cc-rs#1265) pass only target arch to find_tool()
let has_linker = windows_registry::find_tool(
sess.opts.target_triple.tuple(),
"link.exe",
)
.is_some();
let has_linker =
windows_registry::find_tool(&sess.target.arch, "link.exe").is_some();

sess.dcx().emit_note(errors::LinkExeUnexpectedError);
if is_vs_installed && has_linker {
Expand Down Expand Up @@ -2745,6 +2741,15 @@ fn add_upstream_rust_crates(
.find(|(ty, _)| *ty == crate_type)
.expect("failed to find crate type in dependency format list");

if sess.target.is_like_aix {
// Unlike ELF linkers, AIX doesn't feature `DT_SONAME` to override
// the dependency name when outputing a shared library. Thus, `ld` will
// use the full path to shared libraries as the dependency if passed it
// by default unless `noipath` is passed.
// https://www.ibm.com/docs/en/aix/7.3?topic=l-ld-command.
cmd.link_or_cc_arg("-bnoipath");
}

for &cnum in &codegen_results.crate_info.used_crates {
// We may not pass all crates through to the linker. Some crates may appear statically in
// an existing dylib, meaning we'll pick up all the symbols from the dylib.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ pub(crate) fn get_linker<'a>(
self_contained: bool,
target_cpu: &'a str,
) -> Box<dyn Linker + 'a> {
// FIXME(cc-rs#1265) pass only target arch to find_tool()
let msvc_tool = windows_registry::find_tool(sess.opts.target_triple.tuple(), "link.exe");
let msvc_tool = windows_registry::find_tool(&sess.target.arch, "link.exe");

// If our linker looks like a batch script on Windows then to execute this
// we'll need to spawn `cmd` explicitly. This is primarily done to handle
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,28 +454,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
closure_kind: hir::ClosureKind,
projection: ty::PolyProjectionPredicate<'tcx>,
) -> Option<ExpectedSig<'tcx>> {
let tcx = self.tcx;

let trait_def_id = projection.trait_def_id(tcx);
let def_id = projection.projection_def_id();

// For now, we only do signature deduction based off of the `Fn` and `AsyncFn` traits,
// for closures and async closures, respectively.
match closure_kind {
hir::ClosureKind::Closure
if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() =>
{
hir::ClosureKind::Closure if self.tcx.is_lang_item(def_id, LangItem::FnOnceOutput) => {
self.extract_sig_from_projection(cause_span, projection)
}
hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async)
if self.tcx.async_fn_trait_kind_from_def_id(trait_def_id).is_some() =>
if self.tcx.is_lang_item(def_id, LangItem::AsyncFnOnceOutput) =>
{
self.extract_sig_from_projection(cause_span, projection)
}
// It's possible we've passed the closure to a (somewhat out-of-fashion)
// `F: FnOnce() -> Fut, Fut: Future<Output = T>` style bound. Let's still
// guide inference here, since it's beneficial for the user.
hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async)
if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() =>
if self.tcx.is_lang_item(def_id, LangItem::FnOnceOutput) =>
{
self.extract_sig_from_projection_and_future_bound(cause_span, projection)
}
Expand Down
175 changes: 105 additions & 70 deletions library/std/src/sys/pal/wasi/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,27 @@ pub struct FileAttr {

pub struct ReadDir {
inner: Arc<ReadDirInner>,
cookie: Option<wasi::Dircookie>,
buf: Vec<u8>,
offset: usize,
cap: usize,
state: ReadDirState,
}

enum ReadDirState {
/// Fill `buf` with `buf.len()` bytes starting from `next_read_offset`.
FillBuffer {
next_read_offset: wasi::Dircookie,
buf: Vec<u8>,
},
ProcessEntry {
buf: Vec<u8>,
next_read_offset: Option<wasi::Dircookie>,
offset: usize,
},
/// There is no more data to get in [`Self::FillBuffer`]; keep returning
/// entries via ProcessEntry until `buf` is exhausted.
RunUntilExhaustion {
buf: Vec<u8>,
offset: usize,
},
Done,
}

struct ReadDirInner {
Expand Down Expand Up @@ -147,11 +164,8 @@ impl FileType {
impl ReadDir {
fn new(dir: File, root: PathBuf) -> ReadDir {
ReadDir {
cookie: Some(0),
buf: vec![0; 128],
offset: 0,
cap: 0,
inner: Arc::new(ReadDirInner { dir, root }),
state: ReadDirState::FillBuffer { next_read_offset: 0, buf: vec![0; 128] },
}
}
}
Expand All @@ -162,78 +176,99 @@ impl fmt::Debug for ReadDir {
}
}

impl core::iter::FusedIterator for ReadDir {}

impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;

fn next(&mut self) -> Option<io::Result<DirEntry>> {
loop {
// If we've reached the capacity of our buffer then we need to read
// some more from the OS, otherwise we pick up at our old offset.
let offset = if self.offset == self.cap {
let cookie = self.cookie.take()?;
match self.inner.dir.fd.readdir(&mut self.buf, cookie) {
Ok(bytes) => self.cap = bytes,
Err(e) => return Some(Err(e)),
}
self.offset = 0;
self.cookie = Some(cookie);

// If we didn't actually read anything, this is in theory the
// end of the directory.
if self.cap == 0 {
self.cookie = None;
return None;
}

0
} else {
self.offset
};
let data = &self.buf[offset..self.cap];

// If we're not able to read a directory entry then that means it
// must have been truncated at the end of the buffer, so reset our
// offset so we can go back and reread into the buffer, picking up
// where we last left off.
let dirent_size = mem::size_of::<wasi::Dirent>();
if data.len() < dirent_size {
assert!(self.cookie.is_some());
assert!(self.buf.len() >= dirent_size);
self.offset = self.cap;
continue;
}
let (dirent, data) = data.split_at(dirent_size);
let dirent = unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) };

// If the file name was truncated, then we need to reinvoke
// `readdir` so we truncate our buffer to start over and reread this
// descriptor. Note that if our offset is 0 that means the file name
// is massive and we need a bigger buffer.
if data.len() < dirent.d_namlen as usize {
if offset == 0 {
let amt_to_add = self.buf.capacity();
self.buf.extend(iter::repeat(0).take(amt_to_add));
match &mut self.state {
ReadDirState::FillBuffer { next_read_offset, ref mut buf } => {
let result = self.inner.dir.fd.readdir(buf, *next_read_offset);
match result {
Ok(read_bytes) => {
if read_bytes < buf.len() {
buf.truncate(read_bytes);
self.state =
ReadDirState::RunUntilExhaustion { buf: mem::take(buf), offset: 0 };
} else {
debug_assert_eq!(read_bytes, buf.len());
self.state = ReadDirState::ProcessEntry {
buf: mem::take(buf),
offset: 0,
next_read_offset: Some(*next_read_offset),
};
}
self.next()
}
Err(e) => {
self.state = ReadDirState::Done;
return Some(Err(e));
}
}
assert!(self.cookie.is_some());
self.offset = self.cap;
continue;
}
self.cookie = Some(dirent.d_next);
self.offset = offset + dirent_size + dirent.d_namlen as usize;
ReadDirState::ProcessEntry { ref mut buf, next_read_offset, offset } => {
let contents = &buf[*offset..];
const DIRENT_SIZE: usize = crate::mem::size_of::<wasi::Dirent>();
if contents.len() >= DIRENT_SIZE {
let (dirent, data) = contents.split_at(DIRENT_SIZE);
let dirent =
unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) };
// If the file name was truncated, then we need to reinvoke
// `readdir` so we truncate our buffer to start over and reread this
// descriptor.
if data.len() < dirent.d_namlen as usize {
if buf.len() < dirent.d_namlen as usize + DIRENT_SIZE {
buf.resize(dirent.d_namlen as usize + DIRENT_SIZE, 0);
}
if let Some(next_read_offset) = *next_read_offset {
self.state =
ReadDirState::FillBuffer { next_read_offset, buf: mem::take(buf) };
} else {
self.state = ReadDirState::Done;
}

return self.next();
}
next_read_offset.as_mut().map(|cookie| {
*cookie = dirent.d_next;
});
*offset = *offset + DIRENT_SIZE + dirent.d_namlen as usize;

let name = &data[..(dirent.d_namlen as usize)];
let name = &data[..(dirent.d_namlen as usize)];

// These names are skipped on all other platforms, so let's skip
// them here too
if name == b"." || name == b".." {
return self.next();
}

// These names are skipped on all other platforms, so let's skip
// them here too
if name == b"." || name == b".." {
continue;
return Some(Ok(DirEntry {
meta: dirent,
name: name.to_vec(),
inner: self.inner.clone(),
}));
} else if let Some(next_read_offset) = *next_read_offset {
self.state = ReadDirState::FillBuffer { next_read_offset, buf: mem::take(buf) };
} else {
self.state = ReadDirState::Done;
}
self.next()
}
ReadDirState::RunUntilExhaustion { buf, offset } => {
if *offset >= buf.len() {
self.state = ReadDirState::Done;
} else {
self.state = ReadDirState::ProcessEntry {
buf: mem::take(buf),
offset: *offset,
next_read_offset: None,
};
}

return Some(Ok(DirEntry {
meta: dirent,
name: name.to_vec(),
inner: self.inner.clone(),
}));
self.next()
}
ReadDirState::Done => None,
}
}
}
Expand Down
25 changes: 13 additions & 12 deletions src/bootstrap/src/core/build_steps/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ const SHELL: &str = "sh";

/// We have to run a few shell scripts, which choke quite a bit on both `\`
/// characters and on `C:\` paths, so normalize both of them away.
fn sanitize_sh(path: &Path) -> String {
fn sanitize_sh(path: &Path, is_cygwin: bool) -> String {
let path = path.to_str().unwrap().replace('\\', "/");
return change_drive(unc_to_lfs(&path)).unwrap_or(path);
return if is_cygwin { path } else { change_drive(unc_to_lfs(&path)).unwrap_or(path) };

fn unc_to_lfs(s: &str) -> &str {
s.strip_prefix("//?/").unwrap_or(s)
Expand Down Expand Up @@ -71,6 +71,7 @@ fn install_sh(
let prefix = default_path(&builder.config.prefix, "/usr/local");
let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
let destdir_env = env::var_os("DESTDIR").map(PathBuf::from);
let is_cygwin = builder.config.build.is_cygwin();

// Sanity checks on the write access of user.
//
Expand Down Expand Up @@ -103,14 +104,14 @@ fn install_sh(

let mut cmd = command(SHELL);
cmd.current_dir(&empty_dir)
.arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
.arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix)))
.arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir)))
.arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir)))
.arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir)))
.arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir)))
.arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir)))
.arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir)))
.arg(sanitize_sh(&tarball.decompressed_output().join("install.sh"), is_cygwin))
.arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix, is_cygwin)))
.arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir, is_cygwin)))
.arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir, is_cygwin)))
.arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir, is_cygwin)))
.arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir, is_cygwin)))
.arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir, is_cygwin)))
.arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir, is_cygwin)))
.arg("--disable-ldconfig");
cmd.run(builder);
t!(fs::remove_dir_all(&empty_dir));
Expand All @@ -120,7 +121,7 @@ fn default_path(config: &Option<PathBuf>, default: &str) -> PathBuf {
config.as_ref().cloned().unwrap_or_else(|| PathBuf::from(default))
}

fn prepare_dir(destdir_env: &Option<PathBuf>, mut path: PathBuf) -> String {
fn prepare_dir(destdir_env: &Option<PathBuf>, mut path: PathBuf, is_cygwin: bool) -> String {
// The DESTDIR environment variable is a standard way to install software in a subdirectory
// while keeping the original directory structure, even if the prefix or other directories
// contain absolute paths.
Expand All @@ -146,7 +147,7 @@ fn prepare_dir(destdir_env: &Option<PathBuf>, mut path: PathBuf) -> String {
assert!(path.is_absolute(), "could not make the path relative");
}

sanitize_sh(&path)
sanitize_sh(&path, is_cygwin)
}

macro_rules! install {
Expand Down
6 changes: 6 additions & 0 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,12 @@ impl TargetSelection {
self.ends_with("windows-gnu")
}

pub fn is_cygwin(&self) -> bool {
self.is_windows() &&
// ref. https://cygwin.com/pipermail/cygwin/2022-February/250802.html
env::var("OSTYPE").is_ok_and(|v| v.to_lowercase().contains("cygwin"))
}

/// Path to the file defining the custom target, if any.
pub fn filepath(&self) -> Option<&Path> {
self.file.as_ref().map(Path::new)
Expand Down
10 changes: 5 additions & 5 deletions src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2295,8 +2295,6 @@ ui/issues/issue-43853.rs
ui/issues/issue-4387.rs
ui/issues/issue-43910.rs
ui/issues/issue-43923.rs
ui/issues/issue-43925.rs
ui/issues/issue-43926.rs
ui/issues/issue-43988.rs
ui/issues/issue-44023.rs
ui/issues/issue-44056.rs
Expand Down Expand Up @@ -2545,8 +2543,6 @@ ui/issues/issue-6936.rs
ui/issues/issue-69455.rs
ui/issues/issue-69602-type-err-during-codegen-ice.rs
ui/issues/issue-69683.rs
ui/issues/issue-70093/issue-70093-link-directives.rs
ui/issues/issue-70093/issue-70093.rs
ui/issues/issue-7012.rs
ui/issues/issue-70381.rs
ui/issues/issue-7044.rs
Expand Down Expand Up @@ -2711,11 +2707,15 @@ ui/limits/issue-17913.rs
ui/limits/issue-55878.rs
ui/limits/issue-69485-var-size-diffs-too-large.rs
ui/limits/issue-75158-64.rs
ui/link-native-libs/issue-109144.rs
ui/link-native-libs/issue-43925.rs
ui/link-native-libs/issue-43926.rs
ui/link-native-libs/issue-70093/issue-70093-link-directives.rs
ui/link-native-libs/issue-70093/issue-70093.rs
ui/linkage-attr/auxiliary/issue-12133-dylib.rs
ui/linkage-attr/auxiliary/issue-12133-dylib2.rs
ui/linkage-attr/auxiliary/issue-12133-rlib.rs
ui/linkage-attr/issue-10755.rs
ui/linkage-attr/issue-109144.rs
ui/linkage-attr/issue-12133-1.rs
ui/linkage-attr/issue-12133-2.rs
ui/linkage-attr/issue-12133-3.rs
Expand Down
2 changes: 1 addition & 1 deletion src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use ignore::Walk;
const ENTRY_LIMIT: u32 = 901;
// FIXME: The following limits should be reduced eventually.

const ISSUES_ENTRY_LIMIT: u32 = 1672;
const ISSUES_ENTRY_LIMIT: u32 = 1667;

const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files
Expand Down
Loading

0 comments on commit 1da727e

Please sign in to comment.