Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b46ba116ae | |||
| 4c8551a7a4 | |||
| 69c5a7f895 | |||
| 3e7f518a1d | |||
| d822648ddd | |||
| da1c51a6d1 | |||
| 6388aab487 | |||
| c123bfb0f6 | |||
| 3f70d2eb96 | |||
| ac9607f8fb | |||
| 5c222c6e01 | |||
| 9aca77a99d | |||
| 64c8a5cab9 | |||
| 4223772986 | |||
| ab9d982a24 | |||
| 9d42312987 | |||
| 308f6a3d13 | |||
| 82882dfbc7 | |||
| 23c99b6d2c | |||
| 85449aa8c3 | |||
| e7746a8445 | |||
| 7d4c743cf1 | |||
| aa4283ac3b | |||
| 71ad1196c9 | |||
| 6ba4e6f8e2 | |||
| 97c94c8814 | |||
| 6c71a2798b | |||
| 4883af9371 | |||
| e8b7d33684 | |||
| 3a77d57bab | |||
| bc22846ab3 | |||
| 8a5d469dc3 | |||
| 957d3dec43 | |||
| 3668bbdf3a | |||
| eea1569466 | |||
| 6e4718e6cd | |||
| d3a8b67604 | |||
| 44a0cc2a48 | |||
| 7f5344419b | |||
| f64dcb305b | |||
| 1390823c9c | |||
| 4621c13b78 | |||
| 19819a25a2 | |||
| f3735a19c6 | |||
| d5da273762 | |||
| 198f3e254b | |||
| 7a442f76a6 | |||
| e137e6480a | |||
| ba03bb87b6 | |||
| 6eee868877 | |||
| d3296ec5f6 | |||
| 3d580a2b02 | |||
| 0a15cff03f | |||
| 8b39059da8 | |||
| defb036456 | |||
| 22228b3aa5 | |||
| 90c541806f | |||
| 4930c02c00 | |||
| c30ed50fe6 | |||
| 09571d448a | |||
| d332def19c | |||
| 8fc89a21d0 | |||
| 655516b5a4 | |||
| 8b07c8821b | |||
| 7cfea71beb | |||
| ebe9af7c7a | |||
| 2687f47c4e | |||
| f2e37f7bcd | |||
| a365f58bf6 | |||
| 1a42cb7fff | |||
| 16ec1c0a80 | |||
| 7a0af0973c | |||
| 8b7deda58d | |||
| ec1d458777 | |||
| 2013813b65 | |||
| c11cc10558 | |||
| 428ac2a66e | |||
| 7fc63a62ee | |||
| cc38d9fe09 | |||
| dd253c0be1 | |||
| 071f14baae | |||
| 4e2f52c516 | |||
| 12fcfa089c | |||
| b93f9e56ae | |||
| 53e5649ae4 | |||
| b50332ccfb | |||
| 828d9471bd | |||
| d580176d4d | |||
| 1b7dd2252b | |||
| 988610a083 | |||
| 86dfb0d0d1 | |||
| 58cfc1c97f | |||
| a27ea2b497 | |||
| 8df541968f |
@@ -322,7 +322,7 @@ jobs:
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: macos-12-xl
|
||||
os: macos-latest
|
||||
- name: dist-apple-various
|
||||
env:
|
||||
SCRIPT: "./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim"
|
||||
@@ -333,7 +333,7 @@ jobs:
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-12-xl
|
||||
os: macos-latest
|
||||
- name: dist-x86_64-apple-alt
|
||||
env:
|
||||
SCRIPT: "./x.py dist bootstrap --include-default-paths"
|
||||
@@ -344,7 +344,7 @@ jobs:
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-12-xl
|
||||
os: macos-latest
|
||||
- name: x86_64-apple-1
|
||||
env:
|
||||
SCRIPT: "./x.py --stage 2 test --exclude tests/ui --exclude tests/rustdoc --exclude tests/run-make-fulldeps"
|
||||
@@ -355,7 +355,7 @@ jobs:
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-12-xl
|
||||
os: macos-latest
|
||||
- name: x86_64-apple-2
|
||||
env:
|
||||
SCRIPT: "./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps"
|
||||
@@ -366,7 +366,7 @@ jobs:
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-12-xl
|
||||
os: macos-latest
|
||||
- name: dist-aarch64-apple
|
||||
env:
|
||||
SCRIPT: "./x.py dist bootstrap --include-default-paths --stage 2"
|
||||
@@ -381,7 +381,7 @@ jobs:
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
JEMALLOC_SYS_WITH_LG_PAGE: 14
|
||||
os: macos-12-xl
|
||||
os: macos-latest
|
||||
- name: x86_64-msvc-1
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler"
|
||||
|
||||
@@ -78,4 +78,9 @@ package.json
|
||||
## Rustdoc GUI tests
|
||||
tests/rustdoc-gui/src/**.lock
|
||||
|
||||
## Yggdrasil OS ABI link
|
||||
/yggdrasil-rt
|
||||
/yggdrasil-abi
|
||||
/libyalloc
|
||||
|
||||
# Before adding new lines, see the comment at the top.
|
||||
|
||||
@@ -32,3 +32,7 @@
|
||||
[submodule "library/backtrace"]
|
||||
path = library/backtrace
|
||||
url = https://github.com/rust-lang/backtrace-rs.git
|
||||
|
||||
[submodule "yggdrasil-rt"]
|
||||
path = yggdrasil-rt
|
||||
url = git@git.alnyan.me:yggdrasil/yggdrasil-rt.git
|
||||
|
||||
+32
@@ -3013,6 +3013,16 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libyalloc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
"rustc-std-workspace-core",
|
||||
"yggdrasil-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.3"
|
||||
@@ -6011,6 +6021,7 @@ dependencies = [
|
||||
"hashbrown 0.12.3",
|
||||
"hermit-abi 0.3.0",
|
||||
"libc",
|
||||
"libyalloc",
|
||||
"miniz_oxide",
|
||||
"object 0.29.0",
|
||||
"panic_abort",
|
||||
@@ -6022,6 +6033,7 @@ dependencies = [
|
||||
"std_detect",
|
||||
"unwind",
|
||||
"wasi",
|
||||
"yggdrasil-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7158,6 +7170,26 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yggdrasil-abi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yggdrasil-rt"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
"yggdrasil-abi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.7.0"
|
||||
|
||||
@@ -118,3 +118,10 @@ rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' }
|
||||
|
||||
[patch."https://github.com/rust-lang/rust-clippy"]
|
||||
clippy_lints = { path = "src/tools/clippy/clippy_lints" }
|
||||
|
||||
[patch."https://git.alnyan.me/yggdrasil/yggdrasil-rt.git"]
|
||||
yggdrasil-rt = { path = "yggdrasil-rt" }
|
||||
[patch."https://git.alnyan.me/yggdrasil/yggdrasil-abi.git"]
|
||||
yggdrasil-abi = { path = "yggdrasil-abi" }
|
||||
[patch."https://git.alnyan.me/yggdrasil/libyalloc.git"]
|
||||
libyalloc = { path = "libyalloc" }
|
||||
|
||||
+248
-6
@@ -1,3 +1,245 @@
|
||||
Version 1.70.0 (2023-06-01)
|
||||
==========================
|
||||
|
||||
<a id="1.70.0-Language"></a>
|
||||
|
||||
Language
|
||||
--------
|
||||
- [Relax ordering rules for `asm!` operands](https://github.com/rust-lang/rust/pull/105798/)
|
||||
- [Properly allow macro expanded `format_args` invocations to uses captures](https://github.com/rust-lang/rust/pull/106505/)
|
||||
- [Lint ambiguous glob re-exports](https://github.com/rust-lang/rust/pull/107880/)
|
||||
- [Perform const and unsafe checking for expressions in `let _ = expr` position.](https://github.com/rust-lang/rust/pull/102256/)
|
||||
|
||||
<a id="1.70.0-Compiler"></a>
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [Extend -Cdebuginfo with new options and named aliases](https://github.com/rust-lang/rust/pull/109808/)
|
||||
This provides a smaller version of debuginfo for cases that only need line number information
|
||||
(`-Cdebuginfo=line-tables-only`), which may eventually become the default for `-Cdebuginfo=1`.
|
||||
- [Make `unused_allocation` lint against `Box::new` too](https://github.com/rust-lang/rust/pull/104363/)
|
||||
- [Detect uninhabited types early in const eval](https://github.com/rust-lang/rust/pull/109435/)
|
||||
- [Switch to LLD as default linker for {arm,thumb}v4t-none-eabi](https://github.com/rust-lang/rust/pull/109721/)
|
||||
- [Add tier 3 target `loongarch64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/96971)
|
||||
- [Add tier 3 target for `i586-pc-nto-qnx700` (QNX Neutrino RTOS, version 7.0)](https://github.com/rust-lang/rust/pull/109173/),
|
||||
- [Insert alignment checks for pointer dereferences as debug assertions](https://github.com/rust-lang/rust/pull/98112)
|
||||
This catches undefined behavior at runtime, and may cause existing code to fail.
|
||||
|
||||
Refer to Rust's [platform support page][platform-support-doc]
|
||||
for more information on Rust's tiered platform support.
|
||||
|
||||
<a id="1.70.0-Libraries"></a>
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [Document NonZeroXxx layout guarantees](https://github.com/rust-lang/rust/pull/94786/)
|
||||
- [Windows: make `Command` prefer non-verbatim paths](https://github.com/rust-lang/rust/pull/96391/)
|
||||
- [Implement Default for some alloc/core iterators](https://github.com/rust-lang/rust/pull/99929/)
|
||||
- [Fix handling of trailing bare CR in str::lines](https://github.com/rust-lang/rust/pull/100311/)
|
||||
- [allow negative numeric literals in `concat!`](https://github.com/rust-lang/rust/pull/106844/)
|
||||
- [Add documentation about the memory layout of `Cell`](https://github.com/rust-lang/rust/pull/106921/)
|
||||
- [Use `partial_cmp` to implement tuple `lt`/`le`/`ge`/`gt`](https://github.com/rust-lang/rust/pull/108157/)
|
||||
- [Stabilize `atomic_as_ptr`](https://github.com/rust-lang/rust/pull/108419/)
|
||||
- [Stabilize `nonnull_slice_from_raw_parts`](https://github.com/rust-lang/rust/pull/97506/)
|
||||
- [Partial stabilization of `once_cell`](https://github.com/rust-lang/rust/pull/105587/)
|
||||
- [Stabilize `nonzero_min_max`](https://github.com/rust-lang/rust/pull/106633/)
|
||||
- [Flatten/inline format_args!() and (string and int) literal arguments into format_args!()](https://github.com/rust-lang/rust/pull/106824/)
|
||||
- [Stabilize movbe target feature](https://github.com/rust-lang/rust/pull/107711/)
|
||||
- [don't splice from files into pipes in io::copy](https://github.com/rust-lang/rust/pull/108283/)
|
||||
- [Add a builtin unstable `FnPtr` trait that is implemented for all function pointers](https://github.com/rust-lang/rust/pull/108080/)
|
||||
This extends `Debug`, `Pointer`, `Hash`, `PartialEq`, `Eq`, `PartialOrd`, and `Ord`
|
||||
implementations for function pointers with all ABIs.
|
||||
|
||||
<a id="1.70.0-Stabilized-APIs"></a>
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`NonZero*::MIN/MAX`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html#associatedconstant.MIN)
|
||||
- [`BinaryHeap::retain`](https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.retain)
|
||||
- [`Default for std::collections::binary_heap::IntoIter`](https://doc.rust-lang.org/stable/std/collections/binary_heap/struct.IntoIter.html)
|
||||
- [`Default for std::collections::btree_map::{IntoIter, Iter, IterMut}`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.IntoIter.html)
|
||||
- [`Default for std::collections::btree_map::{IntoKeys, Keys}`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.IntoKeys.html)
|
||||
- [`Default for std::collections::btree_map::{IntoValues, Values}`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.IntoKeys.html)
|
||||
- [`Default for std::collections::btree_map::Range`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.Range.html)
|
||||
- [`Default for std::collections::btree_set::{IntoIter, Iter}`](https://doc.rust-lang.org/stable/std/collections/btree_set/struct.IntoIter.html)
|
||||
- [`Default for std::collections::btree_set::Range`](https://doc.rust-lang.org/stable/std/collections/btree_set/struct.Range.html)
|
||||
- [`Default for std::collections::linked_list::{IntoIter, Iter, IterMut}`](https://doc.rust-lang.org/stable/alloc/collections/linked_list/struct.IntoIter.html)
|
||||
- [`Default for std::vec::IntoIter`](https://doc.rust-lang.org/stable/alloc/vec/struct.IntoIter.html#impl-Default-for-IntoIter%3CT,+A%3E)
|
||||
- [`Default for std::iter::Chain`](https://doc.rust-lang.org/stable/std/iter/struct.Chain.html)
|
||||
- [`Default for std::iter::Cloned`](https://doc.rust-lang.org/stable/std/iter/struct.Cloned.html)
|
||||
- [`Default for std::iter::Copied`](https://doc.rust-lang.org/stable/std/iter/struct.Copied.html)
|
||||
- [`Default for std::iter::Enumerate`](https://doc.rust-lang.org/stable/std/iter/struct.Enumerate.html)
|
||||
- [`Default for std::iter::Flatten`](https://doc.rust-lang.org/stable/std/iter/struct.Flatten.html)
|
||||
- [`Default for std::iter::Fuse`](https://doc.rust-lang.org/stable/std/iter/struct.Fuse.html)
|
||||
- [`Default for std::iter::Rev`](https://doc.rust-lang.org/stable/std/iter/struct.Rev.html)
|
||||
- [`Default for std::slice::Iter`](https://doc.rust-lang.org/stable/std/slice/struct.Iter.html)
|
||||
- [`Default for std::slice::IterMut`](https://doc.rust-lang.org/stable/std/slice/struct.IterMut.html)
|
||||
- [`Rc::into_inner`](https://doc.rust-lang.org/stable/alloc/rc/struct.Rc.html#method.into_inner)
|
||||
- [`Arc::into_inner`](https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html#method.into_inner)
|
||||
- [`std::cell::OnceCell`](https://doc.rust-lang.org/stable/std/cell/struct.OnceCell.html)
|
||||
- [`Option::is_some_and`](https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.is_some_and)
|
||||
- [`NonNull::slice_from_raw_parts`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.slice_from_raw_parts)
|
||||
- [`Result::is_ok_and`](https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.is_ok_and)
|
||||
- [`Result::is_err_and`](https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.is_err_and)
|
||||
- [`std::sync::atomic::Atomic*::as_ptr`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU8.html#method.as_ptr)
|
||||
- [`std::io::IsTerminal`](https://doc.rust-lang.org/stable/std/io/trait.IsTerminal.html)
|
||||
- [`std::os::linux::net::SocketAddrExt`](https://doc.rust-lang.org/stable/std/os/linux/net/trait.SocketAddrExt.html)
|
||||
- [`std::os::unix::net::UnixDatagram::bind_addr`](https://doc.rust-lang.org/stable/std/os/unix/net/struct.UnixDatagram.html#method.bind_addr)
|
||||
- [`std::os::unix::net::UnixDatagram::connect_addr`](https://doc.rust-lang.org/stable/std/os/unix/net/struct.UnixDatagram.html#method.connect_addr)
|
||||
- [`std::os::unix::net::UnixDatagram::send_to_addr`](https://doc.rust-lang.org/stable/std/os/unix/net/struct.UnixDatagram.html#method.send_to_addr)
|
||||
- [`std::os::unix::net::UnixListener::bind_addr`](https://doc.rust-lang.org/stable/std/os/unix/net/struct.UnixListener.html#method.bind_addr)
|
||||
- [`std::path::Path::as_mut_os_str`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.as_mut_os_str)
|
||||
- [`std::sync::OnceLock`](https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html)
|
||||
|
||||
<a id="1.70.0-Cargo"></a>
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
- [Add `CARGO_PKG_README`](https://github.com/rust-lang/cargo/pull/11645/)
|
||||
- [Make `sparse` the default protocol for crates.io](https://github.com/rust-lang/cargo/pull/11791/)
|
||||
- [Accurately show status when downgrading dependencies](https://github.com/rust-lang/cargo/pull/11839/)
|
||||
- [Use registry.default for login/logout](https://github.com/rust-lang/cargo/pull/11949/)
|
||||
- [Stabilize `cargo logout`](https://github.com/rust-lang/cargo/pull/11950/)
|
||||
|
||||
<a id="1.70.0-Misc"></a>
|
||||
|
||||
Misc
|
||||
----
|
||||
|
||||
- [Stabilize rustdoc `--test-run-directory`](https://github.com/rust-lang/rust/pull/103682/)
|
||||
|
||||
<a id="1.70.0-Compatibility-Notes"></a>
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- [Prevent stable `libtest` from supporting `-Zunstable-options`](https://github.com/rust-lang/rust/pull/109044/)
|
||||
- [Perform const and unsafe checking for expressions in `let _ = expr` position.](https://github.com/rust-lang/rust/pull/102256/)
|
||||
- [WebAssembly targets enable `sign-ext` and `mutable-globals` features in codegen](https://github.com/rust-lang/rust/issues/109807)
|
||||
This may cause incompatibility with older execution environments.
|
||||
- [Insert alignment checks for pointer dereferences as debug assertions](https://github.com/rust-lang/rust/pull/98112)
|
||||
This catches undefined behavior at runtime, and may cause existing code to fail.
|
||||
|
||||
<a id="1.70.0-Internal-Changes"></a>
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
These changes do not affect any public interfaces of Rust, but they represent
|
||||
significant improvements to the performance or internals of rustc and related
|
||||
tools.
|
||||
|
||||
- [Upgrade to LLVM 16](https://github.com/rust-lang/rust/pull/109474/)
|
||||
- [Use SipHash-1-3 instead of SipHash-2-4 for StableHasher](https://github.com/rust-lang/rust/pull/107925/)
|
||||
|
||||
Version 1.69.0 (2023-04-20)
|
||||
==========================
|
||||
|
||||
<a id="1.69.0-Language"></a>
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
- [Deriving built-in traits on packed structs works with `Copy` fields.](https://github.com/rust-lang/rust/pull/104429/)
|
||||
- [Stabilize the `cmpxchg16b` target feature on x86 and x86_64.](https://github.com/rust-lang/rust/pull/106774/)
|
||||
- [Improve analysis of trait bounds for associated types.](https://github.com/rust-lang/rust/pull/103695/)
|
||||
- [Allow associated types to be used as union fields.](https://github.com/rust-lang/rust/pull/106938/)
|
||||
- [Allow `Self: Autotrait` bounds on dyn-safe trait methods.](https://github.com/rust-lang/rust/pull/107082/)
|
||||
- [Treat `str` as containing `[u8]` for auto trait purposes.](https://github.com/rust-lang/rust/pull/107941/)
|
||||
|
||||
<a id="1.69.0-Compiler"></a>
|
||||
|
||||
Compiler
|
||||
--------
|
||||
|
||||
- [Upgrade `*-pc-windows-gnu` on CI to mingw-w64 v10 and GCC 12.2.](https://github.com/rust-lang/rust/pull/100178/)
|
||||
- [Rework min_choice algorithm of member constraints.](https://github.com/rust-lang/rust/pull/105300/)
|
||||
- [Support `true` and `false` as boolean flags in compiler arguments.](https://github.com/rust-lang/rust/pull/107043/)
|
||||
- [Default `repr(C)` enums to `c_int` size.](https://github.com/rust-lang/rust/pull/107592/)
|
||||
|
||||
<a id="1.69.0-Libraries"></a>
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
- [Implement the unstable `DispatchFromDyn` for cell types, allowing downstream experimentation with custom method receivers.](https://github.com/rust-lang/rust/pull/97373/)
|
||||
- [Document that `fmt::Arguments::as_str()` may return `Some(_)` in more cases after optimization, subject to change.](https://github.com/rust-lang/rust/pull/106823/)
|
||||
- [Implement `AsFd` and `AsRawFd` for `Rc`.](https://github.com/rust-lang/rust/pull/107317/)
|
||||
|
||||
<a id="1.69.0-Stabilized-APIs"></a>
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`CStr::from_bytes_until_nul`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html#method.from_bytes_until_nul)
|
||||
- [`core::ffi::FromBytesUntilNulError`](https://doc.rust-lang.org/stable/core/ffi/struct.FromBytesUntilNulError.html)
|
||||
|
||||
These APIs are now stable in const contexts:
|
||||
|
||||
- [`SocketAddr::new`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.new)
|
||||
- [`SocketAddr::ip`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.ip)
|
||||
- [`SocketAddr::port`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.port)
|
||||
- [`SocketAddr::is_ipv4`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.is_ipv4)
|
||||
- [`SocketAddr::is_ipv6`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.is_ipv6)
|
||||
- [`SocketAddrV4::new`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.new)
|
||||
- [`SocketAddrV4::ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.ip)
|
||||
- [`SocketAddrV4::port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.port)
|
||||
- [`SocketAddrV6::new`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.new)
|
||||
- [`SocketAddrV6::ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.ip)
|
||||
- [`SocketAddrV6::port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.port)
|
||||
- [`SocketAddrV6::flowinfo`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.flowinfo)
|
||||
- [`SocketAddrV6::scope_id`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.scope_id)
|
||||
|
||||
<a id="1.69.0-Cargo"></a>
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
- [Cargo now suggests `cargo fix` or `cargo clippy --fix` when compilation warnings are auto-fixable.](https://github.com/rust-lang/cargo/pull/11558/)
|
||||
- [Cargo now suggests `cargo add` if you try to install a library crate.](https://github.com/rust-lang/cargo/pull/11410/)
|
||||
- [Cargo now sets the `CARGO_BIN_NAME` environment variable also for binary examples.](https://github.com/rust-lang/cargo/pull/11705/)
|
||||
|
||||
<a id="1.69.0-Rustdoc"></a>
|
||||
|
||||
Rustdoc
|
||||
-----
|
||||
|
||||
- [Vertically compact trait bound formatting.](https://github.com/rust-lang/rust/pull/102842/)
|
||||
- [Only include stable lints in `rustdoc::all` group.](https://github.com/rust-lang/rust/pull/106316/)
|
||||
- [Compute maximum Levenshtein distance based on the query.](https://github.com/rust-lang/rust/pull/107141/)
|
||||
- [Remove inconsistently-present sidebar tooltips.](https://github.com/rust-lang/rust/pull/107490/)
|
||||
- [Search by macro when query ends with `!`.](https://github.com/rust-lang/rust/pull/108143/)
|
||||
|
||||
<a id="1.69.0-Compatibility-Notes"></a>
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- [The `rust-analysis` component from `rustup` now only contains a warning placeholder.](https://github.com/rust-lang/rust/pull/101841/) This was primarily intended for RLS, and the corresponding `-Zsave-analysis` flag has been removed from the compiler as well.
|
||||
- [Unaligned references to packed fields are now a hard error.](https://github.com/rust-lang/rust/pull/102513/) This has been a warning since 1.53, and denied by default with a future-compatibility warning since 1.62.
|
||||
- [Update the minimum external LLVM to 14.](https://github.com/rust-lang/rust/pull/107573/)
|
||||
- [Cargo now emits errors on invalid characters in a registry token.](https://github.com/rust-lang/cargo/pull/11600/)
|
||||
- [When `default-features` is set to false of a workspace dependency, and an inherited dependency of a member has `default-features = true`, Cargo will enable default features of that dependency.](https://github.com/rust-lang/cargo/pull/11409/)
|
||||
- [Cargo denies `CARGO_HOME` in the `[env]` configuration table. Cargo itself doesn't pick up this value, but recursive calls to cargo would, which was not intended.](https://github.com/rust-lang/cargo/pull/11644/)
|
||||
- [Debuginfo for build dependencies is now off if not explicitly set. This is expected to improve the overall build time.](https://github.com/rust-lang/cargo/pull/11252/)
|
||||
- [The Rust distribution no longer always includes rustdoc](https://github.com/rust-lang/rust/pull/106886)
|
||||
If `tools = [...]` is set in config.toml, we will respect a missing rustdoc in that list. By
|
||||
default rustdoc remains included. To retain the prior behavior explicitly add `"rustdoc"` to the
|
||||
list.
|
||||
|
||||
<a id="1.69.0-Internal-Changes"></a>
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
These changes do not affect any public interfaces of Rust, but they represent
|
||||
significant improvements to the performance or internals of rustc and related
|
||||
tools.
|
||||
|
||||
- [Move `format_args!()` into AST (and expand it during AST lowering)](https://github.com/rust-lang/rust/pull/106745/)
|
||||
|
||||
Version 1.68.2 (2023-03-28)
|
||||
===========================
|
||||
|
||||
@@ -861,7 +1103,7 @@ Compatibility Notes
|
||||
- [rustdoc: doctests are now run on unexported `macro_rules!` macros, matching other private items][96630]
|
||||
- [rustdoc: Remove .woff font files][96279]
|
||||
- [Enforce Copy bounds for repeat elements while considering lifetimes][95819]
|
||||
- [Windows: Fix potentinal unsoundness by aborting if `File` reads or writes cannot
|
||||
- [Windows: Fix potential unsoundness by aborting if `File` reads or writes cannot
|
||||
complete synchronously][95469].
|
||||
|
||||
Internal Changes
|
||||
@@ -1375,7 +1617,7 @@ and related tools.
|
||||
[is_power_of_two_usize]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroUsize.html#method.is_power_of_two
|
||||
[stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266
|
||||
|
||||
Version 1.58.1 (2022-01-19)
|
||||
Version 1.58.1 (2022-01-20)
|
||||
===========================
|
||||
|
||||
* Fix race condition in `std::fs::remove_dir_all` ([CVE-2022-21658])
|
||||
@@ -1692,10 +1934,10 @@ Libraries
|
||||
- [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744]
|
||||
- [`impl From<[(K, V); N]>` for all collections.][rust#84111]
|
||||
- [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363]
|
||||
- [Treat invalid environment variable names as non-existent.][rust#86183]
|
||||
- [Treat invalid environment variable names as nonexistent.][rust#86183]
|
||||
Previously, the environment functions would panic if given a variable name
|
||||
with an internal null character or equal sign (`=`). Now, these functions will
|
||||
just treat such names as non-existent variables, since the OS cannot represent
|
||||
just treat such names as nonexistent variables, since the OS cannot represent
|
||||
the existence of a variable with such a name.
|
||||
|
||||
Stabilised APIs
|
||||
@@ -1888,7 +2130,7 @@ Compatibility Notes
|
||||
kinds of errors could be categorised [into newer more specific `ErrorKind`
|
||||
variants][79965], and that they do not represent a user error.
|
||||
- [Using environment variable names with `process::Command` on Windows now
|
||||
behaves as expected.][85270] Previously using envionment variables with
|
||||
behaves as expected.][85270] Previously using environment variables with
|
||||
`Command` would cause them to be ASCII-uppercased.
|
||||
- [Rustdoc will now warn on using rustdoc lints that aren't prefixed
|
||||
with `rustdoc::`][86849]
|
||||
@@ -6265,7 +6507,7 @@ eg. `static MINUTE: Duration = Duration::from_secs(60);`
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013]
|
||||
- [`cargo new` no longer removes `rust` or `rs` prefixes/suffixes.][cargo/5013]
|
||||
- [`cargo new` now defaults to creating a binary crate, instead of a
|
||||
library crate.][cargo/5029]
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |
|
||||
|
||||
PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) |
|
||||
|
||||
@@ -775,9 +775,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
ty::Invariant
|
||||
}
|
||||
PlaceContext::NonMutatingUse(
|
||||
Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf
|
||||
| Projection,
|
||||
) => ty::Covariant,
|
||||
Inspect | Copy | Move | SharedBorrow | ShallowBorrow | AddressOf | Projection
|
||||
) => {
|
||||
ty::Covariant
|
||||
},
|
||||
PlaceContext::NonUse(AscribeUserTy) => ty::Covariant,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let def_id = instance.def_id();
|
||||
let containing_scope = get_containing_scope(self, instance);
|
||||
let (containing_scope, is_method) = get_containing_scope(self, instance);
|
||||
let span = tcx.def_span(def_id);
|
||||
let loc = self.lookup_debug_loc(span.lo());
|
||||
let file_metadata = file_metadata(self, &loc.file);
|
||||
@@ -377,8 +377,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
return llvm::LLVMRustDIBuilderCreateFunction(
|
||||
// When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because
|
||||
// LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition.
|
||||
// When we use this `decl` below, the subprogram definition gets created at the CU level
|
||||
// with a DW_AT_specification pointing back to the type's declaration.
|
||||
let decl = is_method.then(|| unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateMethod(
|
||||
DIB(self),
|
||||
containing_scope,
|
||||
name.as_ptr().cast(),
|
||||
name.len(),
|
||||
linkage_name.as_ptr().cast(),
|
||||
linkage_name.len(),
|
||||
file_metadata,
|
||||
loc.line,
|
||||
function_type_metadata,
|
||||
flags,
|
||||
spflags & !DISPFlags::SPFlagDefinition,
|
||||
template_parameters,
|
||||
)
|
||||
});
|
||||
|
||||
return unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateFunction(
|
||||
DIB(self),
|
||||
containing_scope,
|
||||
name.as_ptr().cast(),
|
||||
@@ -393,9 +414,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
spflags,
|
||||
maybe_definition_llfn,
|
||||
template_parameters,
|
||||
None,
|
||||
);
|
||||
}
|
||||
decl,
|
||||
)
|
||||
};
|
||||
|
||||
fn get_function_signature<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
@@ -494,14 +515,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
names
|
||||
}
|
||||
|
||||
/// Returns a scope, plus `true` if that's a type scope for "class" methods,
|
||||
/// otherwise `false` for plain namespace scopes.
|
||||
fn get_containing_scope<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
) -> &'ll DIScope {
|
||||
) -> (&'ll DIScope, bool) {
|
||||
// First, let's see if this is a method within an inherent impl. Because
|
||||
// if yes, we want to make the result subroutine DIE a child of the
|
||||
// subroutine's self-type.
|
||||
let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| {
|
||||
if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) {
|
||||
// If the method does *not* belong to a trait, proceed
|
||||
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
|
||||
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
|
||||
@@ -512,39 +535,34 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
|
||||
// Only "class" methods are generally understood by LLVM,
|
||||
// so avoid methods on other types (e.g., `<*mut T>::null`).
|
||||
match impl_self_ty.kind() {
|
||||
ty::Adt(def, ..) if !def.is_box() => {
|
||||
// Again, only create type information if full debuginfo is enabled
|
||||
if cx.sess().opts.debuginfo == DebugInfo::Full
|
||||
&& !impl_self_ty.needs_subst()
|
||||
{
|
||||
Some(type_di_node(cx, impl_self_ty))
|
||||
} else {
|
||||
Some(namespace::item_namespace(cx, def.did()))
|
||||
}
|
||||
if let ty::Adt(def, ..) = impl_self_ty.kind() && !def.is_box() {
|
||||
// Again, only create type information if full debuginfo is enabled
|
||||
if cx.sess().opts.debuginfo == DebugInfo::Full
|
||||
&& !impl_self_ty.needs_subst()
|
||||
{
|
||||
return (type_di_node(cx, impl_self_ty), true);
|
||||
} else {
|
||||
return (namespace::item_namespace(cx, def.did()), false);
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
// For trait method impls we still use the "parallel namespace"
|
||||
// strategy
|
||||
None
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self_type.unwrap_or_else(|| {
|
||||
namespace::item_namespace(
|
||||
cx,
|
||||
DefId {
|
||||
krate: instance.def_id().krate,
|
||||
index: cx
|
||||
.tcx
|
||||
.def_key(instance.def_id())
|
||||
.parent
|
||||
.expect("get_containing_scope: missing parent?"),
|
||||
},
|
||||
)
|
||||
})
|
||||
let scope = namespace::item_namespace(
|
||||
cx,
|
||||
DefId {
|
||||
krate: instance.def_id().krate,
|
||||
index: cx
|
||||
.tcx
|
||||
.def_key(instance.def_id())
|
||||
.parent
|
||||
.expect("get_containing_scope: missing parent?"),
|
||||
},
|
||||
);
|
||||
(scope, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1986,6 +1986,21 @@ extern "C" {
|
||||
Decl: Option<&'a DIDescriptor>,
|
||||
) -> &'a DISubprogram;
|
||||
|
||||
pub fn LLVMRustDIBuilderCreateMethod<'a>(
|
||||
Builder: &DIBuilder<'a>,
|
||||
Scope: &'a DIDescriptor,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
LinkageName: *const c_char,
|
||||
LinkageNameLen: size_t,
|
||||
File: &'a DIFile,
|
||||
LineNo: c_uint,
|
||||
Ty: &'a DIType,
|
||||
Flags: DIFlags,
|
||||
SPFlags: DISPFlags,
|
||||
TParam: &'a DIArray,
|
||||
) -> &'a DISubprogram;
|
||||
|
||||
pub fn LLVMRustDIBuilderCreateBasicType<'a>(
|
||||
Builder: &DIBuilder<'a>,
|
||||
Name: *const c_char,
|
||||
|
||||
@@ -349,7 +349,10 @@ fn link_rlib<'a>(
|
||||
let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else {
|
||||
continue;
|
||||
};
|
||||
if whole_archive == Some(true) && !codegen_results.crate_info.feature_packed_bundled_libs {
|
||||
if whole_archive == Some(true)
|
||||
&& flavor == RlibFlavor::Normal
|
||||
&& !codegen_results.crate_info.feature_packed_bundled_libs
|
||||
{
|
||||
sess.emit_err(errors::IncompatibleLinkingModifiers);
|
||||
}
|
||||
if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename {
|
||||
|
||||
@@ -232,7 +232,6 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
|
||||
| PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::Inspect
|
||||
| NonMutatingUseContext::SharedBorrow
|
||||
| NonMutatingUseContext::UniqueBorrow
|
||||
| NonMutatingUseContext::ShallowBorrow
|
||||
| NonMutatingUseContext::AddressOf
|
||||
| NonMutatingUseContext::Projection,
|
||||
|
||||
@@ -412,9 +412,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
BorrowKind::Shallow => {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
|
||||
}
|
||||
BorrowKind::Unique => {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
|
||||
}
|
||||
BorrowKind::Unique => PlaceContext::MutatingUse(MutatingUseContext::Borrow),
|
||||
BorrowKind::Mut { .. } => {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ declare_features! (
|
||||
/// Allows using `Self` and associated types in struct expressions and patterns.
|
||||
(accepted, more_struct_aliases, "1.16.0", Some(37544), None),
|
||||
/// Allows using the MOVBE target feature.
|
||||
(accepted, movbe_target_feature, "CURRENT_RUSTC_VERSION", Some(44839), None),
|
||||
(accepted, movbe_target_feature, "1.70.0", Some(44839), None),
|
||||
/// Allows patterns with concurrent by-move and by-ref bindings.
|
||||
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
|
||||
(accepted, move_ref_pattern, "1.49.0", Some(68354), None),
|
||||
|
||||
@@ -417,7 +417,7 @@ declare_features! (
|
||||
/// Allows `if let` guard in match arms.
|
||||
(active, if_let_guard, "1.47.0", Some(51114), None),
|
||||
/// Allows `impl Trait` to be used inside associated types (RFC 2515).
|
||||
(active, impl_trait_in_assoc_type, "CURRENT_RUSTC_VERSION", Some(63063), None),
|
||||
(active, impl_trait_in_assoc_type, "1.70.0", Some(63063), None),
|
||||
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
|
||||
(active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None),
|
||||
/// Allows referencing `Self` and projections in impl-trait.
|
||||
@@ -498,7 +498,7 @@ declare_features! (
|
||||
/// Allows return-position `impl Trait` in traits.
|
||||
(incomplete, return_position_impl_trait_in_trait, "1.65.0", Some(91611), None),
|
||||
/// Allows bounding the return type of AFIT/RPITIT.
|
||||
(incomplete, return_type_notation, "CURRENT_RUSTC_VERSION", Some(109417), None),
|
||||
(incomplete, return_type_notation, "1.70.0", Some(109417), None),
|
||||
/// Allows `extern "rust-cold"`.
|
||||
(active, rust_cold_cc, "1.63.0", Some(97544), None),
|
||||
/// Allows the use of SIMD types in functions declared in `extern` blocks.
|
||||
@@ -521,7 +521,7 @@ declare_features! (
|
||||
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
|
||||
(active, trait_upcasting, "1.56.0", Some(65991), None),
|
||||
/// Allows for transmuting between arrays with sizes that contain generic consts.
|
||||
(active, transmute_generic_consts, "CURRENT_RUSTC_VERSION", Some(109929), None),
|
||||
(active, transmute_generic_consts, "1.70.0", Some(109929), None),
|
||||
/// Allows #[repr(transparent)] on unions (RFC 2645).
|
||||
(active, transparent_unions, "1.37.0", Some(60405), None),
|
||||
/// Allows inconsistent bounds in where clauses.
|
||||
|
||||
@@ -53,7 +53,7 @@ declare_features! (
|
||||
(removed, await_macro, "1.38.0", Some(50547), None,
|
||||
Some("subsumed by `.await` syntax")),
|
||||
/// Allows using the `box $expr` syntax.
|
||||
(removed, box_syntax, "CURRENT_RUSTC_VERSION", Some(49733), None, Some("replaced with `#[rustc_box]`")),
|
||||
(removed, box_syntax, "1.70.0", Some(49733), None, Some("replaced with `#[rustc_box]`")),
|
||||
/// Allows capturing disjoint fields in a closure/generator (RFC 2229).
|
||||
(removed, capture_disjoint_fields, "1.49.0", Some(53488), None, Some("stabilized in Rust 2021")),
|
||||
/// Allows comparing raw pointers during const eval.
|
||||
|
||||
@@ -103,8 +103,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
&& let ty = cx.typeck_results().expr_ty(&await_expr)
|
||||
&& let ty::Alias(ty::Opaque, ty::AliasTy { def_id: future_def_id, .. }) = ty.kind()
|
||||
&& cx.tcx.ty_is_opaque_future(ty)
|
||||
// FIXME: This also includes non-async fns that return `impl Future`.
|
||||
&& let async_fn_def_id = cx.tcx.parent(*future_def_id)
|
||||
&& matches!(cx.tcx.def_kind(async_fn_def_id), DefKind::Fn | DefKind::AssocFn)
|
||||
// Check that this `impl Future` actually comes from an `async fn`
|
||||
&& cx.tcx.asyncness(async_fn_def_id).is_async()
|
||||
&& check_must_use_def(
|
||||
cx,
|
||||
async_fn_def_id,
|
||||
|
||||
@@ -831,6 +831,28 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
|
||||
return wrap(Sub);
|
||||
}
|
||||
|
||||
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod(
|
||||
LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
|
||||
const char *Name, size_t NameLen,
|
||||
const char *LinkageName, size_t LinkageNameLen,
|
||||
LLVMMetadataRef File, unsigned LineNo,
|
||||
LLVMMetadataRef Ty, LLVMRustDIFlags Flags,
|
||||
LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) {
|
||||
DITemplateParameterArray TParams =
|
||||
DITemplateParameterArray(unwrap<MDTuple>(TParam));
|
||||
DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
|
||||
DINode::DIFlags llvmFlags = fromRust(Flags);
|
||||
DISubprogram *Sub = Builder->createMethod(
|
||||
unwrapDI<DIScope>(Scope),
|
||||
StringRef(Name, NameLen),
|
||||
StringRef(LinkageName, LinkageNameLen),
|
||||
unwrapDI<DIFile>(File), LineNo,
|
||||
unwrapDI<DISubroutineType>(Ty),
|
||||
0, 0, nullptr, // VTable params aren't used
|
||||
llvmFlags, llvmSPFlags, TParams);
|
||||
return wrap(Sub);
|
||||
}
|
||||
|
||||
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
|
||||
LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
|
||||
uint64_t SizeInBits, unsigned Encoding) {
|
||||
|
||||
@@ -857,7 +857,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
|
||||
fn get_variant(
|
||||
self,
|
||||
kind: DefKind,
|
||||
index: DefIndex,
|
||||
parent_did: DefId,
|
||||
) -> (VariantIdx, ty::VariantDef) {
|
||||
let adt_kind = match kind {
|
||||
DefKind::Variant => ty::AdtKind::Enum,
|
||||
DefKind::Struct => ty::AdtKind::Struct,
|
||||
@@ -871,27 +876,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
|
||||
let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
|
||||
|
||||
ty::VariantDef::new(
|
||||
self.item_name(index),
|
||||
variant_did,
|
||||
ctor,
|
||||
data.discr,
|
||||
self.root
|
||||
.tables
|
||||
.children
|
||||
.get(self, index)
|
||||
.expect("fields are not encoded for a variant")
|
||||
.decode(self)
|
||||
.map(|index| ty::FieldDef {
|
||||
did: self.local_def_id(index),
|
||||
name: self.item_name(index),
|
||||
vis: self.get_visibility(index),
|
||||
})
|
||||
.collect(),
|
||||
adt_kind,
|
||||
parent_did,
|
||||
false,
|
||||
data.is_non_exhaustive,
|
||||
(
|
||||
data.idx,
|
||||
ty::VariantDef::new(
|
||||
self.item_name(index),
|
||||
variant_did,
|
||||
ctor,
|
||||
data.discr,
|
||||
self.root
|
||||
.tables
|
||||
.children
|
||||
.get(self, index)
|
||||
.expect("fields are not encoded for a variant")
|
||||
.decode(self)
|
||||
.map(|index| ty::FieldDef {
|
||||
did: self.local_def_id(index),
|
||||
name: self.item_name(index),
|
||||
vis: self.get_visibility(index),
|
||||
})
|
||||
.collect(),
|
||||
adt_kind,
|
||||
parent_did,
|
||||
false,
|
||||
data.is_non_exhaustive,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -907,7 +915,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
};
|
||||
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
|
||||
|
||||
let variants = if let ty::AdtKind::Enum = adt_kind {
|
||||
let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
|
||||
self.root
|
||||
.tables
|
||||
.children
|
||||
@@ -918,15 +926,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
let kind = self.def_kind(index);
|
||||
match kind {
|
||||
DefKind::Ctor(..) => None,
|
||||
_ => Some(self.get_variant(&kind, index, did)),
|
||||
_ => Some(self.get_variant(kind, index, did)),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
|
||||
std::iter::once(self.get_variant(kind, item_id, did)).collect()
|
||||
};
|
||||
|
||||
tcx.mk_adt_def(did, adt_kind, variants, repr)
|
||||
variants.sort_by_key(|(idx, _)| *idx);
|
||||
|
||||
tcx.mk_adt_def(
|
||||
did,
|
||||
adt_kind,
|
||||
variants.into_iter().map(|(_, variant)| variant).collect(),
|
||||
repr,
|
||||
)
|
||||
}
|
||||
|
||||
fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {
|
||||
|
||||
@@ -823,6 +823,8 @@ fn should_encode_span(def_kind: DefKind) -> bool {
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
| DefKind::TyParam
|
||||
| DefKind::ConstParam
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::Fn
|
||||
| DefKind::Const
|
||||
| DefKind::Static(_)
|
||||
@@ -837,12 +839,10 @@ fn should_encode_span(def_kind: DefKind) -> bool {
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Closure
|
||||
| DefKind::Generator => true,
|
||||
DefKind::ConstParam
|
||||
| DefKind::ExternCrate
|
||||
DefKind::ExternCrate
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm => false,
|
||||
}
|
||||
}
|
||||
@@ -1376,9 +1376,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
// Therefore, the loop over variants will encode its fields as the adt's children.
|
||||
}
|
||||
|
||||
for variant in adt_def.variants().iter() {
|
||||
for (idx, variant) in adt_def.variants().iter_enumerated() {
|
||||
let data = VariantData {
|
||||
discr: variant.discr,
|
||||
idx,
|
||||
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
};
|
||||
|
||||
@@ -31,6 +31,7 @@ use rustc_span::edition::Edition;
|
||||
use rustc_span::hygiene::{ExpnIndex, MacroKind};
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::spec::{PanicStrategy, TargetTriple};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
@@ -423,6 +424,7 @@ define_tables! {
|
||||
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
struct VariantData {
|
||||
idx: VariantIdx,
|
||||
discr: ty::VariantDiscr,
|
||||
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
|
||||
ctor: Option<(CtorKind, DefIndex)>,
|
||||
|
||||
@@ -220,6 +220,11 @@ pub enum BorrowKind {
|
||||
/// immutable, but not aliasable. This solves the problem. For
|
||||
/// simplicity, we don't give users the way to express this
|
||||
/// borrow, it's just used when translating closures.
|
||||
///
|
||||
// FIXME(#112072): This is wrong. Unique borrows are mutable borrows except
|
||||
// that they do not require their pointee to be marked as a mutable.
|
||||
// They should still be treated as mutable borrows in every other way,
|
||||
// e.g. for variance or overlap checking.
|
||||
Unique,
|
||||
|
||||
/// Data is mutable and not aliasable.
|
||||
|
||||
@@ -640,8 +640,8 @@ macro_rules! make_mir_visitor {
|
||||
BorrowKind::Shallow => PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::ShallowBorrow
|
||||
),
|
||||
BorrowKind::Unique => PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::UniqueBorrow
|
||||
BorrowKind::Unique => PlaceContext::MutatingUse(
|
||||
MutatingUseContext::Borrow
|
||||
),
|
||||
BorrowKind::Mut { .. } =>
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow),
|
||||
@@ -1247,8 +1247,6 @@ pub enum NonMutatingUseContext {
|
||||
SharedBorrow,
|
||||
/// Shallow borrow.
|
||||
ShallowBorrow,
|
||||
/// Unique borrow.
|
||||
UniqueBorrow,
|
||||
/// AddressOf for *const pointer.
|
||||
AddressOf,
|
||||
/// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
|
||||
@@ -1324,9 +1322,7 @@ impl PlaceContext {
|
||||
matches!(
|
||||
self,
|
||||
PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::SharedBorrow
|
||||
| NonMutatingUseContext::ShallowBorrow
|
||||
| NonMutatingUseContext::UniqueBorrow
|
||||
NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::ShallowBorrow
|
||||
) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -697,9 +697,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
}
|
||||
|
||||
pub fn borrow_nested_obligations(&self) -> &[N] {
|
||||
match &self {
|
||||
ImplSource::UserDefined(i) => &i.nested[..],
|
||||
ImplSource::Param(n, _) => &n,
|
||||
match self {
|
||||
ImplSource::UserDefined(i) => &i.nested,
|
||||
ImplSource::Param(n, _) => n,
|
||||
ImplSource::Builtin(i) => &i.nested,
|
||||
ImplSource::AutoImpl(d) => &d.nested,
|
||||
ImplSource::Closure(c) => &c.nested,
|
||||
@@ -713,6 +713,23 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
|
||||
match self {
|
||||
ImplSource::UserDefined(i) => &mut i.nested,
|
||||
ImplSource::Param(n, _) => n,
|
||||
ImplSource::Builtin(i) => &mut i.nested,
|
||||
ImplSource::AutoImpl(d) => &mut d.nested,
|
||||
ImplSource::Closure(c) => &mut c.nested,
|
||||
ImplSource::Generator(c) => &mut c.nested,
|
||||
ImplSource::Future(c) => &mut c.nested,
|
||||
ImplSource::Object(d) => &mut d.nested,
|
||||
ImplSource::FnPointer(d) => &mut d.nested,
|
||||
ImplSource::TraitAlias(d) => &mut d.nested,
|
||||
ImplSource::TraitUpcasting(d) => &mut d.nested,
|
||||
ImplSource::ConstDestruct(i) => &mut i.nested,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
|
||||
where
|
||||
F: FnMut(N) -> M,
|
||||
|
||||
@@ -334,9 +334,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||
let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
|
||||
Some((expr.span, refutable))
|
||||
}
|
||||
ExprKind::LogicalOp { op: LogicalOp::And, .. } => {
|
||||
bug!()
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -198,8 +198,7 @@ impl DefUse {
|
||||
| NonMutatingUseContext::Inspect
|
||||
| NonMutatingUseContext::Move
|
||||
| NonMutatingUseContext::ShallowBorrow
|
||||
| NonMutatingUseContext::SharedBorrow
|
||||
| NonMutatingUseContext::UniqueBorrow,
|
||||
| NonMutatingUseContext::SharedBorrow,
|
||||
) => Some(DefUse::Use),
|
||||
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Projection)
|
||||
|
||||
@@ -75,6 +75,14 @@ struct PointerFinder<'tcx, 'a> {
|
||||
}
|
||||
|
||||
impl<'tcx, 'a> Visitor<'tcx> for PointerFinder<'tcx, 'a> {
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
if let Rvalue::AddressOf(..) = rvalue {
|
||||
// Ignore dereferences inside of an AddressOf
|
||||
return;
|
||||
}
|
||||
self.super_rvalue(rvalue, location);
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
|
||||
if let PlaceContext::NonUse(_) = context {
|
||||
return;
|
||||
|
||||
@@ -822,7 +822,6 @@ impl Visitor<'_> for CanConstProp {
|
||||
// mutation.
|
||||
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
||||
| NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
|
||||
| NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
|
||||
| NonMutatingUse(NonMutatingUseContext::AddressOf)
|
||||
| MutatingUse(MutatingUseContext::Borrow)
|
||||
| MutatingUse(MutatingUseContext::AddressOf) => {
|
||||
|
||||
@@ -131,7 +131,6 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
|
||||
PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::SharedBorrow
|
||||
| NonMutatingUseContext::ShallowBorrow
|
||||
| NonMutatingUseContext::UniqueBorrow
|
||||
| NonMutatingUseContext::AddressOf,
|
||||
) => true,
|
||||
// For debuginfo, merging locals is ok.
|
||||
|
||||
@@ -227,28 +227,29 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
|
||||
))?;
|
||||
|
||||
// if `dir` points target's dir, move up to the sysroot
|
||||
if dir.ends_with(crate::config::host_triple()) {
|
||||
let mut sysroot_dir = if dir.ends_with(crate::config::host_triple()) {
|
||||
dir.parent() // chop off `$target`
|
||||
.and_then(|p| p.parent()) // chop off `rustlib`
|
||||
.and_then(|p| {
|
||||
// chop off `lib` (this could be also $arch dir if the host sysroot uses a
|
||||
// multi-arch layout like Debian or Ubuntu)
|
||||
match p.parent() {
|
||||
Some(p) => match p.file_name() {
|
||||
Some(f) if f == "lib" => p.parent(), // first chop went for $arch, so chop again for `lib`
|
||||
_ => Some(p),
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
})
|
||||
.and_then(|p| p.parent()) // chop off `lib`
|
||||
.map(|s| s.to_owned())
|
||||
.ok_or(format!(
|
||||
"Could not move 3 levels upper using `parent()` on {}",
|
||||
dir.display()
|
||||
))
|
||||
.ok_or_else(|| {
|
||||
format!("Could not move 3 levels upper using `parent()` on {}", dir.display())
|
||||
})?
|
||||
} else {
|
||||
Ok(dir.to_owned())
|
||||
dir.to_owned()
|
||||
};
|
||||
|
||||
// On multiarch linux systems, there will be multiarch directory named
|
||||
// with the architecture(e.g `x86_64-linux-gnu`) under the `lib` directory.
|
||||
// Which cause us to mistakenly end up in the lib directory instead of the sysroot directory.
|
||||
if sysroot_dir.ends_with("lib") {
|
||||
sysroot_dir =
|
||||
sysroot_dir.parent().map(|real_sysroot| real_sysroot.to_owned()).ok_or_else(
|
||||
|| format!("Could not move to parent path of {}", sysroot_dir.display()),
|
||||
)?
|
||||
}
|
||||
|
||||
Ok(sysroot_dir)
|
||||
}
|
||||
|
||||
// Use env::args().next() to get the path of the executable without
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#![feature(min_specialization)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(round_char_boundary)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
|
||||
@@ -1019,36 +1019,19 @@ impl SourceMap {
|
||||
|
||||
let src = local_begin.sf.external_src.borrow();
|
||||
|
||||
// We need to extend the snippet to the end of the src rather than to end_index so when
|
||||
// searching forwards for boundaries we've got somewhere to search.
|
||||
let snippet = if let Some(ref src) = local_begin.sf.src {
|
||||
&src[start_index..]
|
||||
let snippet = if let Some(src) = &local_begin.sf.src {
|
||||
src
|
||||
} else if let Some(src) = src.get_source() {
|
||||
&src[start_index..]
|
||||
src
|
||||
} else {
|
||||
return 1;
|
||||
};
|
||||
debug!("snippet=`{:?}`", snippet);
|
||||
|
||||
let mut target = if forwards { end_index + 1 } else { end_index - 1 };
|
||||
debug!("initial target=`{:?}`", target);
|
||||
|
||||
while !snippet.is_char_boundary(target - start_index) && target < source_len {
|
||||
target = if forwards {
|
||||
target + 1
|
||||
} else {
|
||||
match target.checked_sub(1) {
|
||||
Some(target) => target,
|
||||
None => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
debug!("target=`{:?}`", target);
|
||||
if forwards {
|
||||
(snippet.ceil_char_boundary(end_index + 1) - end_index) as u32
|
||||
} else {
|
||||
(end_index - snippet.floor_char_boundary(end_index - 1)) as u32
|
||||
}
|
||||
debug!("final target=`{:?}`", target);
|
||||
|
||||
if forwards { (target - end_index) as u32 } else { (end_index - target) as u32 }
|
||||
}
|
||||
|
||||
pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
use crate::spec::{PanicStrategy, Target};
|
||||
|
||||
// Have specific requirements about how segments are aligned
|
||||
const LINKER_SCRIPT: &str = include_str!("./aarch64_unknown_yggdrasil_linker_script.ld");
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::yggdrasil_base::opts();
|
||||
|
||||
base.disable_redzone = true;
|
||||
base.panic_strategy = PanicStrategy::Abort;
|
||||
base.features = "-fp-armv8,-neon,+strict-align,+v8a".into();
|
||||
base.link_script = Some(LINKER_SCRIPT.into());
|
||||
|
||||
Target {
|
||||
llvm_target: "aarch64-unknown-none".into(),
|
||||
pointer_width: 64,
|
||||
arch: "aarch64".into(),
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
|
||||
options: base,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
OUTPUT_FORMAT(elf64-littleaarch64)
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(runtime_entry)
|
||||
|
||||
BASE_ADDR = 0x400000;
|
||||
|
||||
SECTIONS {
|
||||
. = BASE_ADDR;
|
||||
|
||||
.text : {
|
||||
*(.text*)
|
||||
*(.plt*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.rodata : {
|
||||
*(.rodata*)
|
||||
/* TODO: this is unused currently */
|
||||
*(.eh_frame*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.data : {
|
||||
*(.data*)
|
||||
*(.got*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.bss : {
|
||||
*(COMMON)
|
||||
*(.bss*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.tbss : {
|
||||
*(.tbss*)
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,8 @@ mod windows_msvc_base;
|
||||
mod windows_uwp_gnu_base;
|
||||
mod windows_uwp_msvc_base;
|
||||
|
||||
mod yggdrasil_base;
|
||||
|
||||
/// Linker is called through a C/C++ compiler.
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub enum Cc {
|
||||
@@ -1266,6 +1268,9 @@ supported_targets! {
|
||||
|
||||
("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos),
|
||||
("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos),
|
||||
|
||||
("aarch64-unknown-yggdrasil", aarch64_unknown_yggdrasil),
|
||||
("x86_64-unknown-yggdrasil", x86_64_unknown_yggdrasil),
|
||||
}
|
||||
|
||||
/// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
use crate::spec::{PanicStrategy, Target};
|
||||
|
||||
// Have specific requirements about how segments are aligned
|
||||
const LINKER_SCRIPT: &str = include_str!("./x86_64_unknown_yggdrasil_linker_script.ld");
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::yggdrasil_base::opts();
|
||||
|
||||
base.disable_redzone = true;
|
||||
base.panic_strategy = PanicStrategy::Abort;
|
||||
base.link_script = Some(LINKER_SCRIPT.into());
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-unknown-linux-gnu".into(),
|
||||
pointer_width: 64,
|
||||
arch: "x86_64".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
.into(),
|
||||
options: base,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
ENTRY(runtime_entry)
|
||||
|
||||
BASE_ADDR = 0x400000;
|
||||
|
||||
SECTIONS {
|
||||
. = BASE_ADDR;
|
||||
|
||||
.text : {
|
||||
*(.text*)
|
||||
*(.plt*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.rodata : {
|
||||
*(.rodata*)
|
||||
/* TODO: this is unused currently */
|
||||
*(.eh_frame*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.data : {
|
||||
*(.data*)
|
||||
*(.got*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.bss : {
|
||||
*(COMMON)
|
||||
*(.bss*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.tbss : {
|
||||
*(.tbss*)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
use crate::spec::{Cc, LinkerFlavor, RelocModel, StackProbeType, TargetOptions};
|
||||
|
||||
use super::{Lld, LldFlavor};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
os: "yggdrasil".into(),
|
||||
executables: true,
|
||||
linker: Some("ld.lld".into()),
|
||||
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
|
||||
lld_flavor_json: LldFlavor::Ld,
|
||||
stack_probes: StackProbeType::Inline,
|
||||
has_thread_local: true,
|
||||
max_atomic_width: Some(128),
|
||||
eh_frame_header: false,
|
||||
relocation_model: RelocModel::Static,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
// The obligations returned by confirmation are recursively evaluated
|
||||
// so we need to make sure they have the correct depth.
|
||||
for subobligation in impl_src.borrow_nested_obligations_mut() {
|
||||
subobligation.set_depth_from_parent(obligation.recursion_depth);
|
||||
}
|
||||
|
||||
if !obligation.predicate.is_const_if_const() {
|
||||
// normalize nested predicates according to parent predicate's constness.
|
||||
impl_src = impl_src.map(|mut o| {
|
||||
|
||||
@@ -853,7 +853,7 @@ impl<T: Ord> BinaryHeap<T> {
|
||||
///
|
||||
/// assert_eq!(heap.into_sorted_vec(), [-10, 2, 4])
|
||||
/// ```
|
||||
#[stable(feature = "binary_heap_retain", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "binary_heap_retain", since = "1.70.0")]
|
||||
pub fn retain<F>(&mut self, mut f: F)
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
@@ -1463,7 +1463,7 @@ impl<T> ExactSizeIterator for IntoIter<T> {
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T> FusedIterator for IntoIter<T> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for IntoIter<T> {
|
||||
/// Creates an empty `binary_heap::IntoIter`.
|
||||
///
|
||||
|
||||
@@ -362,7 +362,7 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<'a, K: 'a, V: 'a> Default for Iter<'a, K, V> {
|
||||
/// Creates an empty `btree_map::Iter`.
|
||||
///
|
||||
@@ -400,7 +400,7 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> {
|
||||
/// Creates an empty `btree_map::IterMut`.
|
||||
///
|
||||
@@ -448,7 +448,7 @@ impl<K: Debug, V: Debug, A: Allocator + Clone> Debug for IntoIter<K, V, A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<K, V, A> Default for IntoIter<K, V, A>
|
||||
where
|
||||
A: Allocator + Default + Clone,
|
||||
@@ -1812,7 +1812,7 @@ impl<K, V> Clone for Keys<'_, K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<K, V> Default for Keys<'_, K, V> {
|
||||
/// Creates an empty `btree_map::Keys`.
|
||||
///
|
||||
@@ -1867,7 +1867,7 @@ impl<K, V> Clone for Values<'_, K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<K, V> Default for Values<'_, K, V> {
|
||||
/// Creates an empty `btree_map::Values`.
|
||||
///
|
||||
@@ -2017,7 +2017,7 @@ impl<'a, K, V> Iterator for Range<'a, K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<K, V> Default for Range<'_, K, V> {
|
||||
/// Creates an empty `btree_map::Range`.
|
||||
///
|
||||
@@ -2107,7 +2107,7 @@ impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoKeys<K, V, A> {
|
||||
#[stable(feature = "map_into_keys_values", since = "1.54.0")]
|
||||
impl<K, V, A: Allocator + Clone> FusedIterator for IntoKeys<K, V, A> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<K, V, A> Default for IntoKeys<K, V, A>
|
||||
where
|
||||
A: Allocator + Default + Clone,
|
||||
@@ -2158,7 +2158,7 @@ impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoValues<K, V, A> {
|
||||
#[stable(feature = "map_into_keys_values", since = "1.54.0")]
|
||||
impl<K, V, A: Allocator + Clone> FusedIterator for IntoValues<K, V, A> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<K, V, A> Default for IntoValues<K, V, A>
|
||||
where
|
||||
A: Allocator + Default + Clone,
|
||||
|
||||
@@ -1538,7 +1538,7 @@ impl<T, A: Allocator + Clone> Iterator for IntoIter<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for Iter<'_, T> {
|
||||
/// Creates an empty `btree_set::Iter`.
|
||||
///
|
||||
@@ -1568,7 +1568,7 @@ impl<T, A: Allocator + Clone> ExactSizeIterator for IntoIter<T, A> {
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T, A: Allocator + Clone> FusedIterator for IntoIter<T, A> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T, A> Default for IntoIter<T, A>
|
||||
where
|
||||
A: Allocator + Default + Clone,
|
||||
@@ -1623,7 +1623,7 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> {
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T> FusedIterator for Range<'_, T> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for Range<'_, T> {
|
||||
/// Creates an empty `btree_set::Range`.
|
||||
///
|
||||
|
||||
@@ -1074,7 +1074,7 @@ impl<T> ExactSizeIterator for Iter<'_, T> {}
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T> FusedIterator for Iter<'_, T> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for Iter<'_, T> {
|
||||
/// Creates an empty `linked_list::Iter`.
|
||||
///
|
||||
@@ -1142,7 +1142,7 @@ impl<T> ExactSizeIterator for IterMut<'_, T> {}
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T> FusedIterator for IterMut<'_, T> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for IterMut<'_, T> {
|
||||
fn default() -> Self {
|
||||
IterMut { head: None, tail: None, len: 0, marker: Default::default() }
|
||||
@@ -1828,7 +1828,7 @@ impl<T> ExactSizeIterator for IntoIter<T> {}
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T> FusedIterator for IntoIter<T> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for IntoIter<T> {
|
||||
/// Creates an empty `linked_list::IntoIter`.
|
||||
///
|
||||
|
||||
@@ -693,7 +693,7 @@ impl<T> Rc<T> {
|
||||
/// This is equivalent to `Rc::try_unwrap(this).ok()`. (Note that these are not equivalent for
|
||||
/// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`.)
|
||||
#[inline]
|
||||
#[stable(feature = "rc_into_inner", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "rc_into_inner", since = "1.70.0")]
|
||||
pub fn into_inner(this: Self) -> Option<T> {
|
||||
Rc::try_unwrap(this).ok()
|
||||
}
|
||||
|
||||
@@ -793,7 +793,7 @@ impl<T> Arc<T> {
|
||||
/// y_thread.join().unwrap();
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "arc_into_inner", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "arc_into_inner", since = "1.70.0")]
|
||||
pub fn into_inner(this: Self) -> Option<T> {
|
||||
// Make sure that the ordinary `Drop` implementation isn’t called as well
|
||||
let mut this = mem::ManuallyDrop::new(this);
|
||||
|
||||
@@ -342,7 +342,7 @@ impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T, A> Default for IntoIter<T, A>
|
||||
where
|
||||
A: Allocator + Default,
|
||||
|
||||
@@ -247,7 +247,7 @@ mod once;
|
||||
|
||||
#[unstable(feature = "lazy_cell", issue = "109736")]
|
||||
pub use lazy::LazyCell;
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub use once::OnceCell;
|
||||
|
||||
/// A mutable memory location.
|
||||
|
||||
@@ -29,7 +29,7 @@ use crate::mem;
|
||||
/// assert_eq!(value, "Hello, World!");
|
||||
/// assert!(cell.get().is_some());
|
||||
/// ```
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub struct OnceCell<T> {
|
||||
// Invariant: written to at most once.
|
||||
inner: UnsafeCell<Option<T>>,
|
||||
@@ -39,8 +39,8 @@ impl<T> OnceCell<T> {
|
||||
/// Creates a new empty cell.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
#[rustc_const_stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub const fn new() -> OnceCell<T> {
|
||||
OnceCell { inner: UnsafeCell::new(None) }
|
||||
}
|
||||
@@ -49,7 +49,7 @@ impl<T> OnceCell<T> {
|
||||
///
|
||||
/// Returns `None` if the cell is empty.
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn get(&self) -> Option<&T> {
|
||||
// SAFETY: Safe due to `inner`'s invariant
|
||||
unsafe { &*self.inner.get() }.as_ref()
|
||||
@@ -59,7 +59,7 @@ impl<T> OnceCell<T> {
|
||||
///
|
||||
/// Returns `None` if the cell is empty.
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn get_mut(&mut self) -> Option<&mut T> {
|
||||
self.inner.get_mut().as_mut()
|
||||
}
|
||||
@@ -85,7 +85,7 @@ impl<T> OnceCell<T> {
|
||||
/// assert!(cell.get().is_some());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn set(&self, value: T) -> Result<(), T> {
|
||||
// SAFETY: Safe because we cannot have overlapping mutable borrows
|
||||
let slot = unsafe { &*self.inner.get() };
|
||||
@@ -125,7 +125,7 @@ impl<T> OnceCell<T> {
|
||||
/// assert_eq!(value, &92);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn get_or_init<F>(&self, f: F) -> &T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
@@ -206,7 +206,7 @@ impl<T> OnceCell<T> {
|
||||
/// assert_eq!(cell.into_inner(), Some("hello".to_string()));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn into_inner(self) -> Option<T> {
|
||||
// Because `into_inner` takes `self` by value, the compiler statically verifies
|
||||
// that it is not currently borrowed. So it is safe to move out `Option<T>`.
|
||||
@@ -233,13 +233,13 @@ impl<T> OnceCell<T> {
|
||||
/// assert_eq!(cell.get(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn take(&mut self) -> Option<T> {
|
||||
mem::take(self).into_inner()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T> Default for OnceCell<T> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
@@ -247,7 +247,7 @@ impl<T> Default for OnceCell<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.get() {
|
||||
@@ -257,7 +257,7 @@ impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: Clone> Clone for OnceCell<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> OnceCell<T> {
|
||||
@@ -272,7 +272,7 @@ impl<T: Clone> Clone for OnceCell<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: PartialEq> PartialEq for OnceCell<T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
@@ -280,10 +280,10 @@ impl<T: PartialEq> PartialEq for OnceCell<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: Eq> Eq for OnceCell<T> {}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<T> for OnceCell<T> {
|
||||
/// Creates a new `OnceCell<T>` which already contains the given `value`.
|
||||
@@ -294,5 +294,5 @@ impl<T> const From<T> for OnceCell<T> {
|
||||
}
|
||||
|
||||
// Just like for `Cell<T>` this isn't needed, but results in nicer error messages.
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T> !Sync for OnceCell<T> {}
|
||||
|
||||
@@ -273,7 +273,7 @@ where
|
||||
{
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<A: Default, B: Default> Default for Chain<A, B> {
|
||||
/// Creates a `Chain` from the default values for `A` and `B`.
|
||||
///
|
||||
|
||||
@@ -154,7 +154,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<I: Default> Default for Cloned<I> {
|
||||
/// Creates a `Cloned` iterator from the default value of `I`
|
||||
/// ```
|
||||
|
||||
@@ -242,7 +242,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<I: Default> Default for Copied<I> {
|
||||
/// Creates a `Copied` iterator from the default value of `I`
|
||||
/// ```
|
||||
|
||||
@@ -263,7 +263,7 @@ where
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<I: Default> Default for Enumerate<I> {
|
||||
/// Creates an `Enumerate` iterator from the default value of `I`
|
||||
/// ```
|
||||
|
||||
@@ -303,7 +303,7 @@ where
|
||||
{
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<I> Default for Flatten<I>
|
||||
where
|
||||
I: Default + Iterator<Item: IntoIterator>,
|
||||
|
||||
@@ -181,7 +181,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<I: Default> Default for Fuse<I> {
|
||||
/// Creates a `Fuse` iterator from the default value of `I`.
|
||||
///
|
||||
|
||||
@@ -137,7 +137,7 @@ impl<I> FusedIterator for Rev<I> where I: FusedIterator + DoubleEndedIterator {}
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<I> TrustedLen for Rev<I> where I: TrustedLen + DoubleEndedIterator {}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<I: Default> Default for Rev<I> {
|
||||
/// Creates a `Rev` iterator from the default value of `I`
|
||||
/// ```
|
||||
|
||||
@@ -1157,7 +1157,7 @@ macro_rules! nonzero_min_max_unsigned {
|
||||
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), 1", stringify!($Int), ");")]
|
||||
/// ```
|
||||
#[stable(feature = "nonzero_min_max", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
|
||||
pub const MIN: Self = Self::new(1).unwrap();
|
||||
|
||||
/// The largest value that can be represented by this non-zero
|
||||
@@ -1170,7 +1170,7 @@ macro_rules! nonzero_min_max_unsigned {
|
||||
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
|
||||
/// ```
|
||||
#[stable(feature = "nonzero_min_max", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
|
||||
pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
|
||||
}
|
||||
)+
|
||||
@@ -1195,7 +1195,7 @@ macro_rules! nonzero_min_max_signed {
|
||||
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), ", stringify!($Int), "::MIN);")]
|
||||
/// ```
|
||||
#[stable(feature = "nonzero_min_max", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
|
||||
pub const MIN: Self = Self::new(<$Int>::MIN).unwrap();
|
||||
|
||||
/// The largest value that can be represented by this non-zero
|
||||
@@ -1212,7 +1212,7 @@ macro_rules! nonzero_min_max_signed {
|
||||
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
|
||||
#[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
|
||||
/// ```
|
||||
#[stable(feature = "nonzero_min_max", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "nonzero_min_max", since = "1.70.0")]
|
||||
pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
|
||||
}
|
||||
)+
|
||||
|
||||
@@ -616,7 +616,7 @@ impl<T> Option<T> {
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[inline]
|
||||
#[stable(feature = "is_some_and", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_some_and", since = "1.70.0")]
|
||||
pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool {
|
||||
match self {
|
||||
None => false,
|
||||
|
||||
@@ -473,7 +473,7 @@ impl<T> NonNull<[T]> {
|
||||
///
|
||||
/// (Note that this example artificially demonstrates a use of this method,
|
||||
/// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.)
|
||||
#[stable(feature = "nonnull_slice_from_raw_parts", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "nonnull_slice_from_raw_parts", since = "1.70.0")]
|
||||
#[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
|
||||
@@ -556,7 +556,7 @@ impl<T, E> Result<T, E> {
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[inline]
|
||||
#[stable(feature = "is_some_and", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_some_and", since = "1.70.0")]
|
||||
pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool {
|
||||
match self {
|
||||
Err(_) => false,
|
||||
@@ -601,7 +601,7 @@ impl<T, E> Result<T, E> {
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[inline]
|
||||
#[stable(feature = "is_some_and", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_some_and", since = "1.70.0")]
|
||||
pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool {
|
||||
match self {
|
||||
Ok(_) => false,
|
||||
|
||||
@@ -394,7 +394,7 @@ macro_rules! iterator {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "default_iters", since = "1.70.0")]
|
||||
impl<T> Default for $name<'_, T> {
|
||||
/// Creates an empty slice iterator.
|
||||
///
|
||||
|
||||
@@ -972,8 +972,8 @@ impl AtomicBool {
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_as_ptr", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "atomic_as_ptr", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "atomic_as_ptr", since = "1.70.0")]
|
||||
#[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
|
||||
pub const fn as_ptr(&self) -> *mut bool {
|
||||
self.v.get().cast()
|
||||
}
|
||||
@@ -1907,8 +1907,8 @@ impl<T> AtomicPtr<T> {
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_as_ptr", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "atomic_as_ptr", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "atomic_as_ptr", since = "1.70.0")]
|
||||
#[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
|
||||
pub const fn as_ptr(&self) -> *mut *mut T {
|
||||
self.p.get()
|
||||
}
|
||||
@@ -2860,8 +2860,8 @@ macro_rules! atomic_int {
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_as_ptr", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "atomic_as_ptr", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "atomic_as_ptr", since = "1.70.0")]
|
||||
#[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
|
||||
pub const fn as_ptr(&self) -> *mut $int_type {
|
||||
self.v.get()
|
||||
}
|
||||
|
||||
@@ -45,6 +45,10 @@ fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] }
|
||||
[target.'cfg(target_os = "hermit")'.dependencies]
|
||||
hermit-abi = { version = "0.3.0", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[target.'cfg(target_os = "yggdrasil")'.dependencies]
|
||||
yggdrasil-rt = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-rt.git", features = ['rustc-dep-of-std'] }
|
||||
libyalloc = { git = "https://git.alnyan.me/yggdrasil/libyalloc.git", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[target.wasm32-wasi.dependencies]
|
||||
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ fn main() {
|
||||
|| target.contains("solid")
|
||||
|| target.contains("nintendo-3ds")
|
||||
|| target.contains("nto")
|
||||
|| target.contains("yggdrasil")
|
||||
{
|
||||
// These platforms don't have any special requirements.
|
||||
} else {
|
||||
|
||||
@@ -268,7 +268,7 @@ pub(crate) use self::stdio::attempt_print_to_stderr;
|
||||
#[unstable(feature = "internal_output_capture", issue = "none")]
|
||||
#[doc(no_inline, hidden)]
|
||||
pub use self::stdio::set_output_capture;
|
||||
#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_terminal", since = "1.70.0")]
|
||||
pub use self::stdio::IsTerminal;
|
||||
#[unstable(feature = "print_internals", issue = "none")]
|
||||
pub use self::stdio::{_eprint, _print};
|
||||
|
||||
@@ -1047,7 +1047,7 @@ pub(crate) fn attempt_print_to_stderr(args: fmt::Arguments<'_>) {
|
||||
}
|
||||
|
||||
/// Trait to determine if a descriptor/handle refers to a terminal/tty.
|
||||
#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_terminal", since = "1.70.0")]
|
||||
pub trait IsTerminal: crate::sealed::Sealed {
|
||||
/// Returns `true` if the descriptor/handle refers to a terminal/tty.
|
||||
///
|
||||
@@ -1063,7 +1063,7 @@ pub trait IsTerminal: crate::sealed::Sealed {
|
||||
/// Note that this [may change in the future][changes].
|
||||
///
|
||||
/// [changes]: io#platform-specific-behavior
|
||||
#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_terminal", since = "1.70.0")]
|
||||
fn is_terminal(&self) -> bool;
|
||||
}
|
||||
|
||||
@@ -1072,7 +1072,7 @@ macro_rules! impl_is_terminal {
|
||||
#[unstable(feature = "sealed", issue = "none")]
|
||||
impl crate::sealed::Sealed for $t {}
|
||||
|
||||
#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_terminal", since = "1.70.0")]
|
||||
impl IsTerminal for $t {
|
||||
#[inline]
|
||||
fn is_terminal(&self) -> bool {
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#[cfg(all(test, not(target_os = "emscripten")))]
|
||||
mod tests;
|
||||
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
use crate::sys::net::netc as c;
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
use crate::sys_common::{FromInner, IntoInner};
|
||||
|
||||
#[stable(feature = "ip_addr", since = "1.7.0")]
|
||||
@@ -14,6 +16,7 @@ pub use core::net::{Ipv4Addr, Ipv6Addr};
|
||||
#[unstable(feature = "ip", issue = "27709")]
|
||||
pub use core::net::Ipv6MulticastScope;
|
||||
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl IntoInner<c::in_addr> for Ipv4Addr {
|
||||
#[inline]
|
||||
fn into_inner(self) -> c::in_addr {
|
||||
@@ -22,17 +25,20 @@ impl IntoInner<c::in_addr> for Ipv4Addr {
|
||||
c::in_addr { s_addr: u32::from_ne_bytes(self.octets()) }
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl FromInner<c::in_addr> for Ipv4Addr {
|
||||
fn from_inner(addr: c::in_addr) -> Ipv4Addr {
|
||||
Ipv4Addr::from(addr.s_addr.to_ne_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl IntoInner<c::in6_addr> for Ipv6Addr {
|
||||
fn into_inner(self) -> c::in6_addr {
|
||||
c::in6_addr { s6_addr: self.octets() }
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl FromInner<c::in6_addr> for Ipv6Addr {
|
||||
#[inline]
|
||||
fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
|
||||
|
||||
@@ -4,24 +4,29 @@ mod tests;
|
||||
|
||||
use crate::io;
|
||||
use crate::iter;
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
use crate::mem;
|
||||
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use crate::option;
|
||||
use crate::slice;
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
use crate::sys::net::netc as c;
|
||||
use crate::sys_common::net::LookupHost;
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
use crate::sys_common::{FromInner, IntoInner};
|
||||
use crate::vec;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl FromInner<c::sockaddr_in> for SocketAddrV4 {
|
||||
fn from_inner(addr: c::sockaddr_in) -> SocketAddrV4 {
|
||||
SocketAddrV4::new(Ipv4Addr::from_inner(addr.sin_addr), u16::from_be(addr.sin_port))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
|
||||
fn from_inner(addr: c::sockaddr_in6) -> SocketAddrV6 {
|
||||
SocketAddrV6::new(
|
||||
@@ -33,6 +38,7 @@ impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl IntoInner<c::sockaddr_in> for SocketAddrV4 {
|
||||
fn into_inner(self) -> c::sockaddr_in {
|
||||
c::sockaddr_in {
|
||||
@@ -44,6 +50,7 @@ impl IntoInner<c::sockaddr_in> for SocketAddrV4 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "yggdrasil"))]
|
||||
impl IntoInner<c::sockaddr_in6> for SocketAddrV6 {
|
||||
fn into_inner(self) -> c::sockaddr_in6 {
|
||||
c::sockaddr_in6 {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! Android-specific networking functionality.
|
||||
|
||||
#![stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#![stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub use crate::os::net::linux_ext::addr::SocketAddrExt;
|
||||
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
|
||||
@@ -201,7 +201,7 @@ macro_rules! impl_is_terminal {
|
||||
#[unstable(feature = "sealed", issue = "none")]
|
||||
impl crate::sealed::Sealed for $t {}
|
||||
|
||||
#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_terminal", since = "1.70.0")]
|
||||
impl crate::io::IsTerminal for $t {
|
||||
#[inline]
|
||||
fn is_terminal(&self) -> bool {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! Linux-specific networking functionality.
|
||||
|
||||
#![stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#![stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub use crate::os::net::linux_ext::addr::SocketAddrExt;
|
||||
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
|
||||
@@ -141,9 +141,15 @@ pub mod solid;
|
||||
pub mod vxworks;
|
||||
#[cfg(target_os = "watchos")]
|
||||
pub(crate) mod watchos;
|
||||
#[cfg(target_os = "yggdrasil")]
|
||||
pub mod yggdrasil;
|
||||
|
||||
#[cfg(any(unix, target_os = "wasi", doc))]
|
||||
pub mod fd;
|
||||
|
||||
#[cfg(target_os = "yggdrasil")]
|
||||
#[unstable(feature = "yggdrasil_raw_fd", issue = "none")]
|
||||
pub use yggdrasil::fd;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", doc))]
|
||||
mod net;
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::os::unix::net::SocketAddr;
|
||||
use crate::sealed::Sealed;
|
||||
|
||||
/// Platform-specific extensions to [`SocketAddr`].
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub trait SocketAddrExt: Sealed {
|
||||
/// Creates a Unix socket address in the abstract namespace.
|
||||
///
|
||||
@@ -37,7 +37,7 @@ pub trait SocketAddrExt: Sealed {
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
fn from_abstract_name<N>(name: N) -> crate::io::Result<SocketAddr>
|
||||
where
|
||||
N: AsRef<[u8]>;
|
||||
@@ -59,6 +59,6 @@ pub trait SocketAddrExt: Sealed {
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
fn as_abstract_name(&self) -> Option<&[u8]>;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#![doc(cfg(any(target_os = "linux", target_os = "android")))]
|
||||
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub(crate) mod addr;
|
||||
|
||||
#[unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
|
||||
@@ -245,12 +245,12 @@ impl SocketAddr {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
impl Sealed for SocketAddr {}
|
||||
|
||||
#[doc(cfg(any(target_os = "android", target_os = "linux")))]
|
||||
#[cfg(any(doc, target_os = "android", target_os = "linux"))]
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
impl linux_ext::addr::SocketAddrExt for SocketAddr {
|
||||
fn as_abstract_name(&self) -> Option<&[u8]> {
|
||||
if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
|
||||
|
||||
@@ -118,7 +118,7 @@ impl UnixDatagram {
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixDatagram> {
|
||||
unsafe {
|
||||
let socket = UnixDatagram::unbound()?;
|
||||
@@ -233,7 +233,7 @@ impl UnixDatagram {
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub fn connect_addr(&self, socket_addr: &SocketAddr) -> io::Result<()> {
|
||||
unsafe {
|
||||
cvt(libc::connect(
|
||||
@@ -532,7 +532,7 @@ impl UnixDatagram {
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub fn send_to_addr(&self, buf: &[u8], socket_addr: &SocketAddr) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let count = cvt(libc::sendto(
|
||||
|
||||
@@ -106,7 +106,7 @@ impl UnixListener {
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixListener> {
|
||||
unsafe {
|
||||
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
||||
|
||||
@@ -122,7 +122,7 @@ impl UnixStream {
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ````
|
||||
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
|
||||
pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
|
||||
unsafe {
|
||||
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
||||
|
||||
@@ -389,7 +389,7 @@ macro_rules! impl_is_terminal {
|
||||
#[unstable(feature = "sealed", issue = "none")]
|
||||
impl crate::sealed::Sealed for $t {}
|
||||
|
||||
#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "is_terminal", since = "1.70.0")]
|
||||
impl crate::io::IsTerminal for $t {
|
||||
#[inline]
|
||||
fn is_terminal(&self) -> bool {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use crate::fmt;
|
||||
use yggdrasil_rt::sys as syscall;
|
||||
|
||||
// This is a safer version of debug_trace! from yggdrasil_rt that uses heap-allocated buffer
|
||||
// instead of a fixed-size chunk.
|
||||
#[macro_export]
|
||||
macro_rules! debug_trace {
|
||||
($($arg:tt)+) => {
|
||||
$crate::os::yggdrasil::debug::_debug_trace(format_args!($($arg)+))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn _debug_trace(args: fmt::Arguments<'_>) {
|
||||
let string = format!("{}", args);
|
||||
unsafe {
|
||||
syscall::debug_trace(string.as_str());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use crate::fs::Metadata;
|
||||
use crate::sys_common::AsInner;
|
||||
use yggdrasil_rt::io::FileMode;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub trait MetadataExt {
|
||||
fn mode_ext(&self) -> FileMode;
|
||||
}
|
||||
|
||||
impl MetadataExt for Metadata {
|
||||
fn mode_ext(&self) -> FileMode {
|
||||
self.as_inner().mode_ext()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use yggdrasil_rt::io::device as rt;
|
||||
use yggdrasil_rt::sys as syscall;
|
||||
|
||||
use crate::io;
|
||||
use crate::os::fd::AsRawFd;
|
||||
use crate::sys::cvt_io;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type DeviceRequest = rt::DeviceRequest;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type MountOptions<'a> = rt::MountOptions<'a>;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type UnmountOptions = rt::UnmountOptions;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub trait FdDeviceRequest {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
unsafe fn device_request(&self, req: &mut DeviceRequest) -> io::Result<()>;
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl<T: AsRawFd> FdDeviceRequest for T {
|
||||
unsafe fn device_request(&self, req: &mut DeviceRequest) -> io::Result<()> {
|
||||
cvt_io(syscall::device_request(self.as_raw_fd(), req))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub unsafe fn mount_raw(options: &MountOptions<'_>) -> crate::io::Result<()> {
|
||||
cvt_io(syscall::mount(options))
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use crate::os::fd::{AsRawFd, OwnedFd};
|
||||
use crate::sys::cvt_io;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct FileMapping<'a> {
|
||||
data: &'a mut [u8],
|
||||
_fd: OwnedFd,
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl<'a> FileMapping<'a> {
|
||||
pub fn new<F: Into<OwnedFd>>(f: F, offset: u64, len: usize) -> crate::io::Result<Self> {
|
||||
use yggdrasil_rt::mem::MappingSource;
|
||||
|
||||
let owned_fd = f.into();
|
||||
let raw_fd = owned_fd.as_raw_fd();
|
||||
let base = cvt_io(unsafe {
|
||||
yggdrasil_rt::sys::map_memory(None, len, &MappingSource::File(raw_fd, offset))
|
||||
})?;
|
||||
|
||||
#[allow(fuzzy_provenance_casts)]
|
||||
let data = unsafe { crate::slice::from_raw_parts_mut(base as *mut u8, len) };
|
||||
|
||||
Ok(Self { data, _fd: owned_fd })
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl crate::ops::Deref for FileMapping<'_> {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl crate::ops::DerefMut for FileMapping<'_> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl Drop for FileMapping<'_> {
|
||||
fn drop(&mut self) {
|
||||
// Unmap the memory
|
||||
let base = self.data.as_ptr() as usize;
|
||||
let len = self.data.len();
|
||||
unsafe {
|
||||
yggdrasil_rt::sys::unmap_memory(base, len).expect("Memory unmap failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use yggdrasil_rt::io::message_channel as rt;
|
||||
use yggdrasil_rt::sys as syscall;
|
||||
|
||||
use crate::io;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
|
||||
use crate::sync::Arc;
|
||||
use crate::sys::cvt_io;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type MessageDestination = rt::MessageDestination;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type ReceivedMessageMetadata = rt::ReceivedMessageMetadata;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type SentMessage<'a> = rt::SentMessage<'a>;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct MessageChannel(OwnedFd);
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct MessageChannelSender(Arc<MessageChannel>);
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct MessageChannelReceiver(Arc<MessageChannel>);
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub trait MessageSender {
|
||||
fn send_raw(&self, msg: &SentMessage<'_>, dst: MessageDestination) -> io::Result<()>;
|
||||
|
||||
fn send_message(&self, msg: &[u8], dst: MessageDestination) -> io::Result<()> {
|
||||
self.send_raw(&SentMessage::Data(msg), dst)
|
||||
}
|
||||
|
||||
fn send_raw_fd(&self, fd: RawFd, dst: MessageDestination) -> io::Result<()> {
|
||||
self.send_raw(&SentMessage::File(fd), dst)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub trait MessageReceiver {
|
||||
fn receive_raw(&self, buf: &mut [u8]) -> io::Result<(u32, ReceivedMessageMetadata)>;
|
||||
|
||||
fn receive_fd(&self) -> io::Result<(u32, OwnedFd)> {
|
||||
let mut buf = [0; 0];
|
||||
let (source, metadata) = self.receive_raw(&mut buf)?;
|
||||
|
||||
match metadata {
|
||||
ReceivedMessageMetadata::File(fd) => Ok((source, unsafe { OwnedFd::from_raw_fd(fd) })),
|
||||
_ => Err(io::Error::from(io::ErrorKind::InvalidData)),
|
||||
}
|
||||
}
|
||||
|
||||
fn receive_message(&self, buf: &mut [u8]) -> io::Result<(u32, usize)> {
|
||||
let (source, metadata) = self.receive_raw(buf)?;
|
||||
|
||||
match metadata {
|
||||
ReceivedMessageMetadata::Data(len) => Ok((source, len)),
|
||||
_ => Err(io::Error::from(io::ErrorKind::InvalidData)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageChannel {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn open<S: AsRef<str>>(name: S, with_sub: bool) -> io::Result<Self> {
|
||||
let raw_fd = cvt_io(unsafe { syscall::open_channel(name.as_ref(), with_sub) })?;
|
||||
|
||||
Ok(Self(unsafe { OwnedFd::from_raw_fd(raw_fd) }))
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn split(self) -> (MessageChannelSender, MessageChannelReceiver) {
|
||||
let sender_fd = Arc::new(self);
|
||||
let receiver_fd = sender_fd.clone();
|
||||
|
||||
(MessageChannelSender(sender_fd), MessageChannelReceiver(receiver_fd))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl MessageSender for MessageChannel {
|
||||
#[inline]
|
||||
fn send_raw(&self, msg: &SentMessage<'_>, dst: MessageDestination) -> io::Result<()> {
|
||||
cvt_io(unsafe { syscall::send_message(self.0.as_raw_fd(), msg, dst) })
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl MessageReceiver for MessageChannel {
|
||||
#[inline]
|
||||
fn receive_raw(&self, buf: &mut [u8]) -> io::Result<(u32, ReceivedMessageMetadata)> {
|
||||
let mut metadata = MaybeUninit::uninit();
|
||||
let mut from = MaybeUninit::uninit();
|
||||
|
||||
cvt_io(unsafe {
|
||||
syscall::receive_message(self.0.as_raw_fd(), &mut metadata, buf, &mut from)
|
||||
})?;
|
||||
|
||||
unsafe { Ok((from.assume_init(), metadata.assume_init())) }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl MessageSender for MessageChannelSender {
|
||||
#[inline]
|
||||
fn send_raw(&self, msg: &SentMessage<'_>, dst: MessageDestination) -> io::Result<()> {
|
||||
self.0.send_raw(msg, dst)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl MessageReceiver for MessageChannelReceiver {
|
||||
#[inline]
|
||||
fn receive_raw(&self, buf: &mut [u8]) -> io::Result<(u32, ReceivedMessageMetadata)> {
|
||||
self.0.receive_raw(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl AsRawFd for MessageChannel {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl AsRawFd for MessageChannelSender {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl AsRawFd for MessageChannelReceiver {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#![stable(feature = "os_fd", since = "1.66.0")]
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub(crate) mod net;
|
||||
pub(crate) mod owned;
|
||||
pub(crate) mod raw;
|
||||
|
||||
pub mod device;
|
||||
pub mod mapping;
|
||||
pub mod message_channel;
|
||||
pub mod pipe;
|
||||
pub mod poll;
|
||||
pub mod shared_memory;
|
||||
pub mod terminal;
|
||||
pub mod timer;
|
||||
|
||||
// Public exports
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub use net::raw_socket;
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub use owned::*;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use raw::*;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub use yggdrasil_rt::io::{FileMetadataUpdate, FileMetadataUpdateMode, FileMode as RawFileMode};
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn update_metadata<P: AsRef<crate::path::Path>>(
|
||||
path: P,
|
||||
update: &FileMetadataUpdate,
|
||||
) -> crate::io::Result<()> {
|
||||
let path = path.as_ref().to_str().unwrap();
|
||||
crate::sys::cvt_io(unsafe { yggdrasil_rt::sys::update_metadata(None, path, &update) })
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod raw_socket;
|
||||
@@ -0,0 +1,56 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use yggdrasil_rt::{
|
||||
net::{MacAddress, SocketInterfaceQuery, SocketOption, SocketType},
|
||||
sys as syscall,
|
||||
};
|
||||
|
||||
use crate::io;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use crate::os::fd::{AsRawFd, FromRawFd, RawFd};
|
||||
use crate::sys::cvt_io;
|
||||
use crate::sys::io::FileDesc;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct RawSocket(FileDesc);
|
||||
|
||||
impl RawSocket {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn bind<'a, Q: Into<SocketInterfaceQuery<'a>>>(interface: Q) -> io::Result<Self> {
|
||||
// TODO this is atrocious
|
||||
let query = interface.into();
|
||||
let bind_address = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0));
|
||||
let raw = cvt_io(unsafe { syscall::bind_socket(&bind_address, SocketType::RawPacket) })?;
|
||||
let inner = unsafe { FileDesc::from_raw_fd(raw) };
|
||||
cvt_io(unsafe {
|
||||
syscall::set_socket_option(inner.as_raw_fd(), &SocketOption::BindInterface(query))
|
||||
})?;
|
||||
Ok(Self(inner))
|
||||
}
|
||||
|
||||
pub fn send(&self, data: &[u8]) -> io::Result<usize> {
|
||||
cvt_io(unsafe { syscall::send_to(self.0.as_raw_fd(), data, &None) })
|
||||
}
|
||||
|
||||
pub fn recv(&self, data: &mut [u8]) -> io::Result<usize> {
|
||||
let mut discard = MaybeUninit::uninit();
|
||||
cvt_io(unsafe { syscall::receive_from(self.0.as_raw_fd(), data, &mut discard) })
|
||||
}
|
||||
|
||||
pub fn hardware_address(&self) -> io::Result<[u8; 6]> {
|
||||
let mut value = SocketOption::BoundHardwareAddress(MacAddress::BROADCAST);
|
||||
cvt_io(unsafe { syscall::get_socket_option(self.0.as_raw_fd(), &mut value) })?;
|
||||
let SocketOption::BoundHardwareAddress(value) = value else {
|
||||
unreachable!();
|
||||
};
|
||||
Ok(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl AsRawFd for RawSocket {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
#![stable(feature = "io_safety", since = "1.63.0")]
|
||||
|
||||
use super::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use crate::marker::PhantomData;
|
||||
use crate::mem::forget;
|
||||
use crate::sys_common::IntoInner;
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct OwnedFd {
|
||||
fd: RawFd,
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct BorrowedFd<'fd> {
|
||||
fd: RawFd,
|
||||
_pd: PhantomData<&'fd OwnedFd>,
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub trait AsFd {
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
fn as_fd(&self) -> BorrowedFd<'_>;
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl<T: AsFd> AsFd for &T {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
T::as_fd(self)
|
||||
}
|
||||
}
|
||||
|
||||
// Borrowed
|
||||
|
||||
impl BorrowedFd<'_> {
|
||||
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
pub const unsafe fn borrow_raw(fd: RawFd) -> Self {
|
||||
// assert_ne!(fd, u32::MAX as RawFd);
|
||||
Self { fd, _pd: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for BorrowedFd<'_> {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawFd for BorrowedFd<'_> {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.fd
|
||||
}
|
||||
}
|
||||
|
||||
// Owned
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsFd for OwnedFd {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl IntoRawFd for OwnedFd {
|
||||
fn into_raw_fd(self) -> RawFd {
|
||||
let fd = self.fd;
|
||||
forget(self);
|
||||
fd
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl FromRawFd for OwnedFd {
|
||||
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
||||
Self { fd }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl AsRawFd for OwnedFd {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.fd
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl Drop for OwnedFd {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
yggdrasil_rt::sys::close(self.fd).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: AsFd for File, From<File> for OwnedFd, From<OwnedFd> for File,
|
||||
#[stable(feature = "io_safety", since = "1.63.0")]
|
||||
impl From<crate::fs::File> for OwnedFd {
|
||||
fn from(value: crate::fs::File) -> OwnedFd {
|
||||
let inner = value.into_inner();
|
||||
Self { fd: inner.into_raw_fd() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use yggdrasil_rt::sys as syscall;
|
||||
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::os::fd::{FromRawFd, OwnedFd};
|
||||
use crate::sys::cvt_io;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn create_pipe_pair() -> crate::io::Result<(OwnedFd, OwnedFd)> {
|
||||
let mut buffer = MaybeUninit::uninit_array();
|
||||
cvt_io(unsafe { syscall::create_pipe(&mut buffer) })?;
|
||||
let read = unsafe { OwnedFd::from_raw_fd(buffer[0].assume_init()) };
|
||||
let write = unsafe { OwnedFd::from_raw_fd(buffer[1].assume_init()) };
|
||||
Ok((read, write))
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use crate::io;
|
||||
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
|
||||
use crate::sys::cvt_io;
|
||||
use crate::time::Duration;
|
||||
|
||||
use yggdrasil_rt::io::poll as rt;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type PollControl = rt::PollControl;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct PollChannel(OwnedFd);
|
||||
|
||||
impl PollChannel {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn new() -> io::Result<Self> {
|
||||
let raw_fd = cvt_io(unsafe { yggdrasil_rt::sys::create_poll_channel() })?;
|
||||
let fd = unsafe { OwnedFd::from_raw_fd(raw_fd) };
|
||||
Ok(Self(fd))
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn add(&mut self, fd: RawFd) -> io::Result<()> {
|
||||
cvt_io(unsafe {
|
||||
yggdrasil_rt::sys::poll_channel_control(self.0.as_raw_fd(), PollControl::AddFd, fd)
|
||||
})
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn wait(
|
||||
&mut self,
|
||||
timeout: Option<Duration>,
|
||||
) -> io::Result<Option<(RawFd, io::Result<()>)>> {
|
||||
let mut output = None;
|
||||
cvt_io(unsafe {
|
||||
yggdrasil_rt::sys::poll_channel_wait(self.0.as_raw_fd(), &timeout, &mut output)
|
||||
})?;
|
||||
Ok(output.map(|(l, r)| (l, cvt_io(r))))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl AsRawFd for PollChannel {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#![stable(feature = "os_fd", since = "1.66.0")]
|
||||
|
||||
use crate::sys_common::{AsInner, FromInner};
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub type RawFd = yggdrasil_rt::io::RawFd;
|
||||
|
||||
macro_rules! stdio_impl_as_raw_fd {
|
||||
($($ty:ty => $n:expr),*) => {$(
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for $ty {
|
||||
#[inline]
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
$n
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asraw_stdio", since = "1.21.0")]
|
||||
impl AsRawFd for &$ty {
|
||||
#[inline]
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
$n
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait AsRawFd {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn as_raw_fd(&self) -> RawFd;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait FromRawFd {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe fn from_raw_fd(fd: RawFd) -> Self;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait IntoRawFd {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn into_raw_fd(self) -> RawFd;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRawFd for RawFd {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl FromRawFd for RawFd {
|
||||
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
||||
fd
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl IntoRawFd for RawFd {
|
||||
fn into_raw_fd(self) -> RawFd {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
stdio_impl_as_raw_fd!(
|
||||
crate::io::Stdin => RawFd::STDIN,
|
||||
crate::io::Stdout => RawFd::STDOUT,
|
||||
crate::io::Stderr => RawFd::STDERR
|
||||
);
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRawFd for crate::fs::File {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.as_inner().as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl FromRawFd for crate::fs::File {
|
||||
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
||||
let inner = crate::sys::fs::File::from_raw_fd(fd);
|
||||
crate::fs::File::from_inner(inner)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> AsRawFd for crate::io::StdinLock<'a> {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use crate::io;
|
||||
use crate::os::yggdrasil::io::mapping::FileMapping;
|
||||
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
|
||||
use crate::sys::cvt_io;
|
||||
|
||||
use yggdrasil_rt::sys as syscall;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct SharedMemory(OwnedFd, usize);
|
||||
|
||||
impl SharedMemory {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn new(size: usize) -> io::Result<Self> {
|
||||
let raw_fd = cvt_io(unsafe { syscall::create_shared_memory(size) })?;
|
||||
let fd = unsafe { OwnedFd::from_raw_fd(raw_fd) };
|
||||
Ok(Self(fd, size))
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn size(&self) -> usize {
|
||||
self.1
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn into_mapping<'a>(self) -> io::Result<FileMapping<'a>> {
|
||||
FileMapping::new(self.0, 0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl AsRawFd for SharedMemory {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use yggdrasil_rt::io::{device::DeviceRequest, terminal as rt_terminal, FileMode, OpenOptions};
|
||||
use yggdrasil_rt::sys as syscall;
|
||||
|
||||
use crate::fs::File;
|
||||
use crate::io;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::os::fd::{AsRawFd, FromRawFd, RawFd};
|
||||
use crate::path::Path;
|
||||
use crate::sys::cvt_io;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type TerminalOptions = rt_terminal::TerminalOptions;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub type TerminalSize = rt_terminal::TerminalSize;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub unsafe fn set_terminal_options<F: AsRawFd>(fd: F, opt: TerminalOptions) -> io::Result<()> {
|
||||
let mut req = DeviceRequest::SetTerminalOptions(opt);
|
||||
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub unsafe fn get_terminal_options<F: AsRawFd>(fd: F) -> io::Result<TerminalOptions> {
|
||||
let mut req = DeviceRequest::GetTerminalOptions(MaybeUninit::uninit());
|
||||
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))?;
|
||||
let DeviceRequest::GetTerminalOptions(opt) = req else {
|
||||
unreachable!();
|
||||
};
|
||||
Ok(opt.assume_init())
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn get_terminal_size<F: AsRawFd>(fd: F) -> io::Result<TerminalSize> {
|
||||
let mut req = DeviceRequest::GetTerminalSize(MaybeUninit::uninit());
|
||||
cvt_io(unsafe { syscall::device_request(fd.as_raw_fd(), &mut req) })?;
|
||||
let DeviceRequest::GetTerminalSize(opt) = req else {
|
||||
unreachable!();
|
||||
};
|
||||
Ok(unsafe { opt.assume_init() })
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub unsafe fn update_terminal_options<F: AsRawFd, M: Fn(TerminalOptions) -> TerminalOptions>(
|
||||
fd: F,
|
||||
mutator: M,
|
||||
) -> io::Result<TerminalOptions> {
|
||||
let fd = fd.as_raw_fd();
|
||||
let old = get_terminal_options(fd)?;
|
||||
let new = mutator(old);
|
||||
set_terminal_options(fd, new)?;
|
||||
Ok(old)
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub unsafe fn start_terminal_session<P: AsRef<Path>>(terminal: P) -> io::Result<()> {
|
||||
let terminal = terminal.as_ref().to_str().unwrap();
|
||||
|
||||
cvt_io(syscall::start_session())?;
|
||||
|
||||
let stdin_fd = cvt_io(syscall::open(None, terminal, OpenOptions::READ, FileMode::empty()))?;
|
||||
let stdout_stderr_fd =
|
||||
cvt_io(syscall::open(None, terminal, OpenOptions::WRITE, FileMode::empty()))?;
|
||||
|
||||
cvt_io(syscall::clone_fd(stdin_fd, Some(RawFd::STDIN)))?;
|
||||
cvt_io(syscall::clone_fd(stdout_stderr_fd, Some(RawFd::STDOUT)))?;
|
||||
cvt_io(syscall::clone_fd(stdout_stderr_fd, Some(RawFd::STDERR)))?;
|
||||
|
||||
cvt_io(syscall::close(stdin_fd))?;
|
||||
cvt_io(syscall::close(stdout_stderr_fd))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn create_pty(
|
||||
options: Option<TerminalOptions>,
|
||||
size: TerminalSize,
|
||||
) -> io::Result<(File, File)> {
|
||||
let options = options.unwrap_or_default();
|
||||
let mut fds = MaybeUninit::uninit();
|
||||
|
||||
cvt_io(unsafe { syscall::create_pty(&options, &size, &mut fds) })?;
|
||||
|
||||
let (master_raw_fd, slave_raw_fd) = unsafe { fds.assume_init() };
|
||||
let master = unsafe { File::from_raw_fd(master_raw_fd) };
|
||||
let slave = unsafe { File::from_raw_fd(slave_raw_fd) };
|
||||
|
||||
Ok((master, slave))
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#![unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
|
||||
use crate::io;
|
||||
use crate::os::fd::{AsRawFd, FromRawFd, RawFd};
|
||||
use crate::sys::cvt_io;
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::time::Duration;
|
||||
|
||||
use yggdrasil_rt::sys as syscall;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub struct TimerFd(FileDesc);
|
||||
|
||||
impl TimerFd {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn new(repeat: bool) -> io::Result<Self> {
|
||||
let raw = cvt_io(unsafe { syscall::create_timer(repeat) })?;
|
||||
let fd = unsafe { FileDesc::from_raw_fd(raw) };
|
||||
Ok(Self(fd))
|
||||
}
|
||||
|
||||
pub fn start(&mut self, timeout: Duration) -> io::Result<()> {
|
||||
let tval = timeout.as_micros();
|
||||
cvt_io(unsafe { syscall::write(self.0.as_raw_fd(), &tval.to_ne_bytes()) })?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl AsRawFd for TimerFd {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#![stable(feature = "os", since = "1.0.0")]
|
||||
|
||||
pub mod debug;
|
||||
pub mod fs;
|
||||
pub mod io;
|
||||
pub mod process;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub fn get_random(buffer: &mut [crate::mem::MaybeUninit<u8>]) {
|
||||
unsafe { yggdrasil_rt::sys::get_random(crate::mem::MaybeUninit::slice_assume_init_mut(buffer)) }
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_raw_fd", issue = "none")]
|
||||
pub mod fd {
|
||||
pub use super::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub mod signal {
|
||||
pub use yggdrasil_rt::process::Signal;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum SignalHandler {
|
||||
Ignore,
|
||||
Terminate,
|
||||
Function(fn(Signal)),
|
||||
}
|
||||
|
||||
pub fn set_signal_handler(signal: Signal, handler: SignalHandler) {
|
||||
unsafe { crate::sys::signal::set_signal_handler(signal, handler) }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_libc", issue = "none")]
|
||||
pub mod libc_runtime {
|
||||
#[unstable(feature = "yggdrasil_libc", issue = "none")]
|
||||
pub unsafe fn start(_arg: usize) -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#![stable(feature = "os", since = "1.0.0")]
|
||||
|
||||
use crate::process::{Command, ExitStatus};
|
||||
use crate::sealed::Sealed;
|
||||
use crate::sys_common::{AsInner, AsInnerMut};
|
||||
use yggdrasil_rt::{io::RawFd, process::Signal};
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub trait CommandExt: Sealed {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
fn process_group(&mut self, pgroup: u32) -> &mut Command;
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
unsafe fn gain_terminal<F: Into<RawFd>>(&mut self, fd: F) -> &mut Command;
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
pub trait ExitStatusExt: Sealed {
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
fn signal(&self) -> Option<Signal>;
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl CommandExt for Command {
|
||||
fn process_group(&mut self, pgroup: u32) -> &mut Command {
|
||||
self.as_inner_mut().pgroup = Some(pgroup);
|
||||
self
|
||||
}
|
||||
|
||||
unsafe fn gain_terminal<F: Into<RawFd>>(&mut self, fd: F) -> &mut Command {
|
||||
self.as_inner_mut().gain_terminal = Some(fd.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
||||
impl ExitStatusExt for ExitStatus {
|
||||
fn signal(&self) -> Option<Signal> {
|
||||
self.as_inner().signal()
|
||||
}
|
||||
}
|
||||
@@ -1509,7 +1509,7 @@ impl PathBuf {
|
||||
/// path.as_mut_os_string().push("baz");
|
||||
/// assert_eq!(path, Path::new("/foo/barbaz"));
|
||||
/// ```
|
||||
#[stable(feature = "path_as_mut_os_str", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "path_as_mut_os_str", since = "1.70.0")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub fn as_mut_os_string(&mut self) -> &mut OsString {
|
||||
@@ -2074,7 +2074,7 @@ impl Path {
|
||||
/// path.as_mut_os_str().make_ascii_lowercase();
|
||||
/// assert_eq!(path, Path::new("foo.txt"));
|
||||
/// ```
|
||||
#[stable(feature = "path_as_mut_os_str", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "path_as_mut_os_str", since = "1.70.0")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub fn as_mut_os_str(&mut self) -> &mut OsStr {
|
||||
|
||||
@@ -177,7 +177,7 @@ pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
#[unstable(feature = "lazy_cell", issue = "109736")]
|
||||
pub use self::lazy_lock::LazyLock;
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub use self::once_lock::OnceLock;
|
||||
|
||||
pub(crate) use self::remutex::{ReentrantMutex, ReentrantMutexGuard};
|
||||
|
||||
@@ -30,7 +30,7 @@ use crate::sync::Once;
|
||||
/// assert!(value.is_some());
|
||||
/// assert_eq!(value.unwrap().as_str(), "Hello, World!");
|
||||
/// ```
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub struct OnceLock<T> {
|
||||
once: Once,
|
||||
// Whether or not the value is initialized is tracked by `once.is_completed()`.
|
||||
@@ -59,8 +59,8 @@ impl<T> OnceLock<T> {
|
||||
/// Creates a new empty cell.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
#[rustc_const_stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub const fn new() -> OnceLock<T> {
|
||||
OnceLock {
|
||||
once: Once::new(),
|
||||
@@ -74,7 +74,7 @@ impl<T> OnceLock<T> {
|
||||
/// Returns `None` if the cell is empty, or being initialized. This
|
||||
/// method never blocks.
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn get(&self) -> Option<&T> {
|
||||
if self.is_initialized() {
|
||||
// Safe b/c checked is_initialized
|
||||
@@ -88,7 +88,7 @@ impl<T> OnceLock<T> {
|
||||
///
|
||||
/// Returns `None` if the cell is empty. This method never blocks.
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn get_mut(&mut self) -> Option<&mut T> {
|
||||
if self.is_initialized() {
|
||||
// Safe b/c checked is_initialized and we have a unique access
|
||||
@@ -124,7 +124,7 @@ impl<T> OnceLock<T> {
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn set(&self, value: T) -> Result<(), T> {
|
||||
let mut value = Some(value);
|
||||
self.get_or_init(|| value.take().unwrap());
|
||||
@@ -162,7 +162,7 @@ impl<T> OnceLock<T> {
|
||||
/// assert_eq!(value, &92);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn get_or_init<F>(&self, f: F) -> &T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
@@ -239,7 +239,7 @@ impl<T> OnceLock<T> {
|
||||
/// assert_eq!(cell.into_inner(), Some("hello".to_string()));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn into_inner(mut self) -> Option<T> {
|
||||
self.take()
|
||||
}
|
||||
@@ -264,7 +264,7 @@ impl<T> OnceLock<T> {
|
||||
/// assert_eq!(cell.get(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
pub fn take(&mut self) -> Option<T> {
|
||||
if self.is_initialized() {
|
||||
self.once = Once::new();
|
||||
@@ -333,17 +333,17 @@ impl<T> OnceLock<T> {
|
||||
// scoped thread B, which fills the cell, which is
|
||||
// then destroyed by A. That is, destructor observes
|
||||
// a sent value.
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
unsafe impl<T: Sync + Send> Sync for OnceLock<T> {}
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
unsafe impl<T: Send> Send for OnceLock<T> {}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T> {}
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
|
||||
impl<T> const Default for OnceLock<T> {
|
||||
/// Creates a new empty cell.
|
||||
@@ -363,7 +363,7 @@ impl<T> const Default for OnceLock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: fmt::Debug> fmt::Debug for OnceLock<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.get() {
|
||||
@@ -373,7 +373,7 @@ impl<T: fmt::Debug> fmt::Debug for OnceLock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: Clone> Clone for OnceLock<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> OnceLock<T> {
|
||||
@@ -388,7 +388,7 @@ impl<T: Clone> Clone for OnceLock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T> From<T> for OnceLock<T> {
|
||||
/// Create a new cell with its contents set to `value`.
|
||||
///
|
||||
@@ -415,7 +415,7 @@ impl<T> From<T> for OnceLock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: PartialEq> PartialEq for OnceLock<T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &OnceLock<T>) -> bool {
|
||||
@@ -423,10 +423,10 @@ impl<T: PartialEq> PartialEq for OnceLock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
impl<T: Eq> Eq for OnceLock<T> {}
|
||||
|
||||
#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[stable(feature = "once_cell", since = "1.70.0")]
|
||||
unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
|
||||
@@ -37,6 +37,9 @@ cfg_if::cfg_if! {
|
||||
} else if #[cfg(target_os = "hermit")] {
|
||||
mod hermit;
|
||||
pub use self::hermit::*;
|
||||
} else if #[cfg(target_os = "yggdrasil")] {
|
||||
mod yggdrasil;
|
||||
pub use self::yggdrasil::*;
|
||||
} else if #[cfg(target_os = "wasi")] {
|
||||
mod wasi;
|
||||
pub use self::wasi::*;
|
||||
|
||||
@@ -210,6 +210,10 @@ impl Slice {
|
||||
}
|
||||
|
||||
pub fn to_owned(&self) -> Buf {
|
||||
#[cfg(target_os = "yggdrasil")]
|
||||
if self.inner.len() == 0 {
|
||||
return Buf { inner: Vec::new() };
|
||||
}
|
||||
Buf { inner: self.inner.to_vec() }
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user