Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #134057

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
529aae6
wasi/fs: Improve stopping condition for <ReadDir as Iterator>::next
osiewicz Nov 18, 2024
692c19a
Refactor ReadDir into a state machine
osiewicz Nov 26, 2024
f4ab982
chore: Improve doc comments
osiewicz Nov 26, 2024
18f8657
Pass -bnoipath when adding rust upstream dynamic crates
Aug 9, 2024
1ae1f8c
Clarify comment
daltenty Dec 6, 2024
3109f07
Replace sa_sigaction with sa_union.__su_sigaction for AIX.
xingxue-ibm Dec 6, 2024
ab2ee7a
Use option "-sf" for the AIX "ln" command.
xingxue-ibm Dec 6, 2024
f884f18
Move tests for `-l` and `#[link(..)]` into `tests/ui/link-native-libs`
Zalathar Dec 7, 2024
0a48b96
Move more tests into `tests/ui/link-native-libs`
Zalathar Dec 7, 2024
88669ae
Don't use AsyncFnOnce::CallOnceFuture bounds for signature deduction
compiler-errors Dec 7, 2024
c4d7f1d
implement `TargetSelection::is_cygwin` function
onur-ozkan Dec 8, 2024
d3b5340
handle cygwin environments in `install::sanitize_sh`
onur-ozkan Dec 8, 2024
5e66869
Pass the arch rather than full target name to windows_registry::find_…
bjorn3 Dec 6, 2024
999aed4
Add URL to test cases
notriddle Dec 9, 2024
b531854
rustdoc: rename `issue-\d+.rs` tests to have meaningful names
notriddle Dec 9, 2024
7554a8a
Rollup merge of #133184 - osiewicz:wasm-fix-infinite-loop-in-remove-d…
GuillaumeGomez Dec 9, 2024
9cccfc1
Rollup merge of #133955 - bjorn3:cc_pass_arch_only, r=ChrisDenton
GuillaumeGomez Dec 9, 2024
88ddf00
Rollup merge of #133967 - daltenty:daltenty/bnoipath, r=jieyouxu
GuillaumeGomez Dec 9, 2024
66c3b19
Rollup merge of #133970 - xingxue-ibm:sigaction, r=nnethercote
GuillaumeGomez Dec 9, 2024
a061eb1
Rollup merge of #133980 - xingxue-ibm:ln-option-aix, r=jieyouxu
GuillaumeGomez Dec 9, 2024
9857c85
Rollup merge of #133996 - Zalathar:ui-link-native-libs, r=jieyouxu
GuillaumeGomez Dec 9, 2024
8aae532
Rollup merge of #134017 - compiler-errors:call-once-deduction, r=jiey…
GuillaumeGomez Dec 9, 2024
5240cc1
Rollup merge of #134023 - onur-ozkan:132507, r=jieyouxu
GuillaumeGomez Dec 9, 2024
0a7c477
Rollup merge of #134053 - notriddle:notriddle/issue-d, r=GuillaumeGomez
GuillaumeGomez Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading