Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
18 changes: 16 additions & 2 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause_span: Option<Span>,
projection: ty::PolyProjectionClause<'tcx>,
) -> Option<ExpectedSig<'tcx>> {
// FIXME(non_lifetime_binders): provide better diagnostics. Should non-lifetime binders
// in opaques with fn traits bound be rejected?
if projection.has_non_region_bound_vars() {
return None;
}
let projection = self.deeply_resolve_ignoring_regions(projection);

let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1);
debug!(?arg_param_ty);

Expand Down Expand Up @@ -526,6 +530,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause_span: Option<Span>,
projection: ty::PolyProjectionClause<'tcx>,
) -> Option<ExpectedSig<'tcx>> {
// FIXME(non_lifetime_binders): provide better diagnostics. Should non-lifetime binders
// in opaques with fn traits bound be rejected?
if projection.has_non_region_bound_vars() {
return None;
}
let projection = self.deeply_resolve_ignoring_regions(projection);

let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1);
Expand Down Expand Up @@ -665,7 +674,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Watch out for some surprises and just ignore the
// expectation if things don't see to match up with what we
// expect.
if expected_sig.sig.c_variadic() != decl.c_variadic() {

// FIXME(non_lifetime_binders): provide better diagnostics. Should non-lifetime binders
// in opaques with fn traits bound be rejected?
if expected_sig.sig.c_variadic() != decl.c_variadic()
|| expected_sig.sig.has_non_region_bound_vars()
{
return self.sig_of_closure_no_expectation(expr_def_id, decl, closure_kind);
} else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 {
return self.sig_of_closure_with_mismatched_number_of_arguments(
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,7 @@ supported_targets! {
("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc),
("thumbv7a-uwp-windows-msvc", thumbv7a_uwp_windows_msvc),

("wasm32-none-component", wasm32_none_component),
("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
("wasm32-unknown-unknown", wasm32_unknown_unknown),
("wasm32v1-none", wasm32v1_none),
Expand Down
31 changes: 31 additions & 0 deletions compiler/rustc_target/src/spec/targets/wasm32_none_component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::spec::{Arch, Cc, LinkerFlavor, Os, Target, TargetMetadata, base};

pub(crate) fn target() -> Target {
let mut options = base::wasm::options();

options.os = Os::None;
options.linker = Some("wasm-component-ld".into());

options.add_pre_link_args(
LinkerFlavor::WasmLld(Cc::No),
&[
// For now this target just never has an entry symbol no matter the output
// type, so unconditionally pass this.
"--no-entry",
],
);

Target {
llvm_target: "wasm32-none-component".into(),
metadata: TargetMetadata {
description: Some("WebAssembly".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 32,
data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(),
arch: Arch::Wasm32,
options,
}
}
16 changes: 11 additions & 5 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2851,7 +2851,9 @@ impl DirEntry {
///
/// On Windows this function is cheap to call (no extra system calls
/// needed), but on Unix platforms this function is the equivalent of
/// calling `symlink_metadata` on the path.
/// calling `symlink_metadata` on the path. In that case, if the file has been renamed or
/// replaced since the `DirEntry` was created, this can fail or return the metadata of a
/// different file!
///
/// # Examples
///
Expand Down Expand Up @@ -2884,9 +2886,11 @@ impl DirEntry {
///
/// # Platform-specific behavior
///
/// On Windows and most Unix platforms this function is free (no extra
/// system calls needed), but some Unix platforms may require the equivalent
/// call to `symlink_metadata` to learn about the target file type.
/// On Windows and most Unix platforms and file systems this function is free (no extra
/// system calls needed), but some Unix platforms or file systems may require the equivalent of
/// calling `symlink_metadata` to learn about the target file type. In that case, if the file
/// has been renamed or replaced since the `DirEntry` was created, this can fail or return the
/// file type of a different file!
///
/// # Examples
///
Expand Down Expand Up @@ -3572,7 +3576,9 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// carefully!
///
/// This function does **not** follow symbolic links and it will simply remove the
/// symbolic link itself.
/// symbolic link itself. If `path` itself is a symbolic link to a directory, it will get
/// removed. If it is a symbolic link to a file, behavior is platform-specific:
/// currently, it will get removed on Unix-like systems but not on Windows.
///
/// # Platform-specific behavior
///
Expand Down
14 changes: 7 additions & 7 deletions library/std/src/fs/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1416,7 +1416,7 @@ fn recursive_rmdir() {
}

#[test]
fn recursive_rmdir_of_symlink() {
fn recursive_rmdir_of_dir_symlink() {
// test we do not recursively delete a symlink but only dirs.
let tmpdir = tmpdir();
let link = tmpdir.join("d1");
Expand All @@ -1443,8 +1443,6 @@ fn recursive_rmdir_of_file_fails() {
}

#[test]
// only Windows makes a distinction between file and directory symlinks.
#[cfg(windows)]
fn recursive_rmdir_of_file_symlink() {
let tmpdir = tmpdir();
if !got_symlink_permission(&tmpdir) {
Expand All @@ -1455,9 +1453,12 @@ fn recursive_rmdir_of_file_symlink() {
let f2 = tmpdir.join("f2");
check!(check!(File::create(&f1)).write(b"foo"));
check!(symlink_file(&f1, &f2));
match fs::remove_dir_all(&f2) {
Ok(..) => panic!("wanted a failure"),
Err(..) => {}
let res = fs::remove_dir_all(&f2);
// Windows and Unix behavior differs here.
if cfg!(windows) {
let _err = res.unwrap_err();
} else {
let _ok = res.unwrap();
}
}

Expand Down Expand Up @@ -1831,7 +1832,6 @@ fn fchmod_works() {
check!(file.set_permissions(p));
}

#[cfg(not(target_os = "android"))]
#[test]
fn fchmodat_works() {
let tmpdir = tmpdir();
Expand Down
5 changes: 4 additions & 1 deletion library/std/src/os/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,10 @@ pub impl(self) trait CommandExt {
/// see the [Remarks][1] section of the `CreateProcessW` documentation.
///
/// [1]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw#remarks
#[unstable(feature = "windows_process_extensions_inherit_handles", issue = "146407")]
#[stable(
feature = "windows_process_extensions_inherit_handles",
since = "CURRENT_RUSTC_VERSION"
)]
fn inherit_handles(&mut self, inherit_handles: bool) -> &mut process::Command;
}

Expand Down
9 changes: 8 additions & 1 deletion library/std/src/sys/fs/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2555,6 +2555,9 @@ mod remove_dir_impl {
}
}

/// `parent_fd` being `None` indicates that this is the root where we start.
/// In that case, `path` will only be deleted if it is a directory.
/// When it is `Some`, this will delete anything.
fn remove_dir_all_recursive(parent_fd: Option<RawFd>, path: &CStr) -> io::Result<()> {
// try opening as directory
let fd = match openat_nofollow_dironly(parent_fd, path) {
Expand All @@ -2566,7 +2569,8 @@ mod remove_dir_impl {
Some(parent_fd) => {
cvt(unsafe { unlinkat(parent_fd, path.as_ptr(), 0) }).map(drop)
}
// ...unless this was supposed to be the deletion root directory
// ...unless this was supposed to be the deletion root directory. We don't want
// to delete a file at the root, so we just forward the error.
None => Err(err),
};
}
Expand Down Expand Up @@ -2625,6 +2629,9 @@ mod remove_dir_impl {
// into symlinks.
let attr = lstat(p)?;
if attr.file_type().is_symlink() {
// This would error in `remove_dir_all_recursive` as it is not a directory.
// We promise to delete directory symlinks, so use `unlink` to do that. On Unix, we
// inadvertently also delete symlinks to files.
super::unlink(p)
} else {
remove_dir_all_recursive(None, p)
Expand Down
28 changes: 18 additions & 10 deletions library/std/src/sys/net/connection/xous/tcpstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ pub struct TcpStream {
nonblocking: Arc<Atomic<bool>>,
}

fn sockaddr_to_buf(duration: Duration, addr: &SocketAddr, buf: &mut [u8]) {
fn sockaddr_to_buf(duration: Option<Duration>, addr: &SocketAddr, buf: &mut [u8]) {
// Construct the request.
let port_bytes = addr.port().to_le_bytes();
buf[0] = port_bytes[0];
buf[1] = port_bytes[1];
for (dest, src) in buf[2..].iter_mut().zip((duration.as_millis() as u64).to_le_bytes()) {
let millis = duration.map_or(0, |d| u64::try_from(d.as_millis()).unwrap_or(u64::MAX).max(1));
for (dest, src) in buf[2..].iter_mut().zip(millis.to_le_bytes()) {
*dest = src;
}
match addr.ip() {
Expand Down Expand Up @@ -82,15 +83,11 @@ impl TcpStream {
}
}

pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
each_addr(addr, |addr| Self::connect_timeout(addr, Duration::ZERO))
}

pub fn connect_timeout(addr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
fn connect_inner(addr: &SocketAddr, timeout: Option<Duration>) -> io::Result<TcpStream> {
let mut connect_request = ConnectRequest { raw: [0u8; 4096] };

// Construct the request.
sockaddr_to_buf(duration, &addr, &mut connect_request.raw);
sockaddr_to_buf(timeout, &addr, &mut connect_request.raw);

let Ok((_, valid)) = crate::os::xous::ffi::lend_mut(
services::net_server(),
Expand Down Expand Up @@ -138,14 +135,25 @@ impl TcpStream {
})
}

pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
each_addr(addr, |addr| Self::connect_inner(addr, None))
}

pub fn connect_timeout(addr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
if duration.is_zero() {
return Err(io::Error::ZERO_TIMEOUT);
}
Self::connect_inner(addr, Some(duration))
}

pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
if let Some(to) = timeout {
if to.is_zero() {
return Err(io::Error::ZERO_TIMEOUT);
}
}
self.read_timeout.store(
timeout.map(|t| t.as_millis().min(u32::MAX as u128) as u32).unwrap_or_default(),
timeout.map_or(0, |t| u32::try_from(t.as_millis()).unwrap_or(u32::MAX).max(1)),
Ordering::Relaxed,
);
Ok(())
Expand All @@ -158,7 +166,7 @@ impl TcpStream {
}
}
self.write_timeout.store(
timeout.map(|t| t.as_millis().min(u32::MAX as u128) as u32).unwrap_or_default(),
timeout.map_or(0, |t| u32::try_from(t.as_millis()).unwrap_or(u32::MAX).max(1)),
Ordering::Relaxed,
);
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/doc/nomicon
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
- [\*-pc-windows-msvc](platform-support/windows-msvc.md)
- [\*-uwp-windows-msvc](platform-support/uwp-windows-msvc.md)
- [\*-wrs-vxworks](platform-support/vxworks.md)
- [wasm32-none-component](platform-support/wasm32-none-component.md)
- [wasm32-wasip1](platform-support/wasm32-wasip1.md)
- [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md)
- [wasm32-wasip2](platform-support/wasm32-wasip2.md)
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ target | std | host | notes
[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Baseline with NuttX
[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX
[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat
[`wasm32-none-component`](platform-support/wasm32-none-component.md) | * | | WebAssembly bare components
[`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly
[`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI)
[`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS
Expand Down
54 changes: 54 additions & 0 deletions src/doc/rustc/src/platform-support/wasm32-none-component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# `wasm32-none-component`

**Tier: 3**

The `wasm32-none-component` target is a `no_std` WebAssembly compilation target. This
target produces a WebAssembly Component as the output and otherwise makes no
assumptions about the environment that it is compiled within. As a `no_std`
compilation target you're required to bring your own `#[global_allocator]` and
`#[panic_handler]`.

The purpose of this target is to represent a compilation target that produces a
WebAssembly component which otherwise does not bring in any APIs by default.
This is suitable for testing out new component targets, for example, or for
building possibly leaner components than one might acquire with the
`wasm32-wasip{2,3}` targets, for example.

Components produced for this target are not assumed to have any particular host
that they're going to run within, so ecosystem crates are expected to fall back
to `no_std` paths or wasm paths otherwise.

One example usage of this target is to build a custom SDK based on the
`wit-bindgen` crate on crates.io. This provides users the ability to import
functions into a component, but this is an opt-in feature per build and
otherwise won't happen by default. This can additionally be used to define
exports as well.

## Target maintainers

[@alexcrichton](https://github.com/alexcrichton)

## Requirements

This target is cross-compiled and has no requirements beyond the base LLVM
toolchain. The target uses `wasm-component-ld` to link which requires LLD to be
built from the Rust source tree, and this ships by default with compiler builds.

## Conditionally compiling code

It's recommended to conditionally compile code for this target with:

```text
#[cfg(all(target_family = "wasm", target_os = "none"))]
```

It's worth noting though that this does not specifically select this target
uniquely as this also matches the `wasm32v1-none` target, for example. Detecting
this target and this target alone currently requires a `build.rs` to look at the
`TARGET` being compiled for to look for the `wasm32-none-component` target name.

## Enabled WebAssembly features

The default set of WebAssembly features enabled for compilation is currently the
same as [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md). See the
documentation there for more information.
3 changes: 3 additions & 0 deletions tests/assembly-llvm/targets/targets-elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,9 @@
//@ revisions: wasm32_unknown_unknown
//@ [wasm32_unknown_unknown] compile-flags: --target wasm32-unknown-unknown
//@ [wasm32_unknown_unknown] needs-llvm-components: webassembly
//@ revisions: wasm32_none_component
//@ [wasm32_none_component] compile-flags: --target wasm32-none-component
//@ [wasm32_none_component] needs-llvm-components: webassembly
//@ revisions: wasm32v1_none
//@ [wasm32v1_none] compile-flags: --target wasm32v1-none
//@ [wasm32v1_none] needs-llvm-components: webassembly
Expand Down
9 changes: 0 additions & 9 deletions tests/crashes/108814.rs

This file was deleted.

8 changes: 0 additions & 8 deletions tests/crashes/110627.rs

This file was deleted.

14 changes: 0 additions & 14 deletions tests/crashes/125841.rs

This file was deleted.

Loading
Loading