Bug 1750646 - Bulk update of rust crates (f, i and l). r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D136190
This commit is contained in:
Mike Hommey 2022-01-18 09:10:41 +00:00
parent 61b0c02a5b
commit c3a7880211
77 changed files with 21572 additions and 21628 deletions

56
Cargo.lock generated
View File

@ -1586,7 +1586,7 @@ dependencies = [
"async-trait",
"chunky-vec",
"fluent-bundle",
"futures 0.3.18",
"futures 0.3.19",
"once_cell",
"unic-langid",
]
@ -1599,7 +1599,7 @@ dependencies = [
"fluent",
"fluent-fallback",
"fluent-pseudo",
"futures 0.3.18",
"futures 0.3.19",
"intl-memoizer",
"l10nregistry",
"nsstring",
@ -1746,9 +1746,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
[[package]]
name = "futures"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4"
dependencies = [
"futures-channel",
"futures-core",
@ -1761,9 +1761,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"
checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b"
dependencies = [
"futures-core",
"futures-sink",
@ -1771,9 +1771,9 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7"
[[package]]
name = "futures-cpupool"
@ -1787,9 +1787,9 @@ dependencies = [
[[package]]
name = "futures-executor"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"
checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a"
dependencies = [
"futures-core",
"futures-task",
@ -1798,15 +1798,15 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"
checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2"
[[package]]
name = "futures-macro"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"
checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c"
dependencies = [
"proc-macro2",
"quote",
@ -1815,21 +1815,21 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"
checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508"
[[package]]
name = "futures-task"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"
checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72"
[[package]]
name = "futures-util"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164"
dependencies = [
"futures-channel",
"futures-core",
@ -2440,9 +2440,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
checksum = "de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094"
dependencies = [
"matches",
"unicode-bidi",
@ -2723,7 +2723,7 @@ dependencies = [
"async-trait",
"fluent-bundle",
"fluent-fallback",
"futures 0.3.18",
"futures 0.3.19",
"pin-project-lite 0.2.7",
"replace_with",
"rustc-hash",
@ -2739,7 +2739,7 @@ dependencies = [
"fluent",
"fluent-fallback",
"fluent-ffi",
"futures 0.3.18",
"futures 0.3.19",
"futures-channel",
"l10nregistry",
"libc",
@ -2780,9 +2780,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
version = "0.2.109"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]]
name = "libdbus-sys"
@ -2889,7 +2889,7 @@ dependencies = [
"fluent",
"fluent-fallback",
"fluent-ffi",
"futures 0.3.18",
"futures 0.3.19",
"futures-channel",
"l10nregistry",
"l10nregistry-ffi",
@ -5504,7 +5504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54cd1e2b3eb3539284d88b76a9afcf5e20f2ef2fab74db5b21a1c30d7d945e82"
dependencies = [
"bytes 0.5.6",
"futures 0.3.18",
"futures 0.3.19",
"headers",
"http",
"hyper",

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"75af1d6ed2d47d3b59e929953f2fc9d2b8aeaea1f51a1829452626f947e091aa","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"fb9330147e41a15b5e569b8bad7692628be89b5fc219a5323a57fa63024c1684","benches/sync_mpsc.rs":"1019dd027f104f58883f396ff70efc3dd69b3a7d62df17af090e07b2b05eaf66","build.rs":"f6e21c09f18cc405bd7048cb7a2958f92d5414b9ca6b301d137e120a84fa020a","no_atomic_cas.rs":"ff8be002b49a5cd9e4ca0db17b1c9e6b98e55f556319eb6b953dd6ff52c397a6","src/lib.rs":"2955e70d292208747fbb29810ef88f390f0f1b22b112fa59d60f95480d470e75","src/lock.rs":"38655a797456ea4f67d132c42055cf74f18195e875c3b337fc81a12901f79292","src/mpsc/mod.rs":"71c8fb3ac645bc587684a9e115b8859044acbade540299a1f9dd952aa27d6ba5","src/mpsc/queue.rs":"8822f466e7fe5a8d25ba994b7022ad7c14bcfd473d354a6cd0490240d3e170e7","src/mpsc/sink_impl.rs":"c9977b530187e82c912fcd46e08316e48ed246e77bb2419d53020e69e403d086","src/oneshot.rs":"d1170289b39656ea5f0d5f42b905ddbd5fa9c1202aa3297c9f25280a48229910","tests/channel.rs":"88f4a41d82b5c1b01e153d071a2bf48e0697355908c55ca42342ed45e63fdec8","tests/mpsc-close.rs":"456e43d3b4aad317c84da81297b05743609af57b26d10470e478f1677e4bf731","tests/mpsc.rs":"c929860c11be704692e709c10a3f5e046d6c01df2cacf568983419cdf82aab97","tests/oneshot.rs":"c44b90681c577f8d0c88e810e883328eefec1d4346b9aa615fa47cc3a7c25c01"},"package":"7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"}
{"files":{"Cargo.toml":"2843b3fc245065891decdfce5244144f4b8a3e35d0d9499db431073930e9b550","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"fb9330147e41a15b5e569b8bad7692628be89b5fc219a5323a57fa63024c1684","benches/sync_mpsc.rs":"1019dd027f104f58883f396ff70efc3dd69b3a7d62df17af090e07b2b05eaf66","build.rs":"f6e21c09f18cc405bd7048cb7a2958f92d5414b9ca6b301d137e120a84fa020a","no_atomic_cas.rs":"ff8be002b49a5cd9e4ca0db17b1c9e6b98e55f556319eb6b953dd6ff52c397a6","src/lib.rs":"2955e70d292208747fbb29810ef88f390f0f1b22b112fa59d60f95480d470e75","src/lock.rs":"38655a797456ea4f67d132c42055cf74f18195e875c3b337fc81a12901f79292","src/mpsc/mod.rs":"71c8fb3ac645bc587684a9e115b8859044acbade540299a1f9dd952aa27d6ba5","src/mpsc/queue.rs":"8822f466e7fe5a8d25ba994b7022ad7c14bcfd473d354a6cd0490240d3e170e7","src/mpsc/sink_impl.rs":"c9977b530187e82c912fcd46e08316e48ed246e77bb2419d53020e69e403d086","src/oneshot.rs":"d1170289b39656ea5f0d5f42b905ddbd5fa9c1202aa3297c9f25280a48229910","tests/channel.rs":"88f4a41d82b5c1b01e153d071a2bf48e0697355908c55ca42342ed45e63fdec8","tests/mpsc-close.rs":"456e43d3b4aad317c84da81297b05743609af57b26d10470e478f1677e4bf731","tests/mpsc.rs":"c929860c11be704692e709c10a3f5e046d6c01df2cacf568983419cdf82aab97","tests/oneshot.rs":"c44b90681c577f8d0c88e810e883328eefec1d4346b9aa615fa47cc3a7c25c01"},"package":"ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b"}

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.45"
name = "futures-channel"
version = "0.3.18"
version = "0.3.19"
description = "Channels for asynchronous communication using futures-rs.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"
@ -22,11 +22,11 @@ repository = "https://github.com/rust-lang/futures-rs"
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies.futures-core]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-sink]
version = "0.3.18"
version = "0.3.19"
optional = true
default-features = false

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"c72d3883e5ac0b8b719041a29fec1c89bf24508e674f871d3390cb8dc1209d99","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"e8258273fed6f1796485777655118f2369fd3f000191e9d8cdbd10bf052946a9","build.rs":"f6e21c09f18cc405bd7048cb7a2958f92d5414b9ca6b301d137e120a84fa020a","no_atomic_cas.rs":"ff8be002b49a5cd9e4ca0db17b1c9e6b98e55f556319eb6b953dd6ff52c397a6","src/future.rs":"0cb559fad0d43566dab959e929c4631c25cf749e2e29a5444fbcad464c9262ae","src/lib.rs":"eacd5816fbb914ca061d49ff6203723ebbe639eb7c45ebfa8a0613069d174111","src/stream.rs":"f1c7ab84161c5d5b424655b257fc3183eb6f2ed5324ba4006a70f9a4b0dc8872","src/task/__internal/atomic_waker.rs":"4ca94b25d3bcf4db863f008224cc4797dbbe7c93495a1abb232048846694a716","src/task/__internal/mod.rs":"7d0d297f58987b05ffa152605feb78ddc9b6e5168e7d621ec36dfbee558e4bec","src/task/mod.rs":"e213602a2fe5ae78ad5f1ca20e6d32dcbab17aba5b6b072fb927a72da99b4a11","src/task/poll.rs":"74c2717c1f9a37587a367da1b690d1cd2312e95dbaffca42be4755f1cd164bb8"},"package":"629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"}
{"files":{"Cargo.toml":"a167cc2eb28add765dbe69220643c977744f206230321ac071e4bbb39981c8b9","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"e8258273fed6f1796485777655118f2369fd3f000191e9d8cdbd10bf052946a9","build.rs":"f6e21c09f18cc405bd7048cb7a2958f92d5414b9ca6b301d137e120a84fa020a","no_atomic_cas.rs":"ff8be002b49a5cd9e4ca0db17b1c9e6b98e55f556319eb6b953dd6ff52c397a6","src/future.rs":"0cb559fad0d43566dab959e929c4631c25cf749e2e29a5444fbcad464c9262ae","src/lib.rs":"eacd5816fbb914ca061d49ff6203723ebbe639eb7c45ebfa8a0613069d174111","src/stream.rs":"f1c7ab84161c5d5b424655b257fc3183eb6f2ed5324ba4006a70f9a4b0dc8872","src/task/__internal/atomic_waker.rs":"4ca94b25d3bcf4db863f008224cc4797dbbe7c93495a1abb232048846694a716","src/task/__internal/mod.rs":"7d0d297f58987b05ffa152605feb78ddc9b6e5168e7d621ec36dfbee558e4bec","src/task/mod.rs":"e213602a2fe5ae78ad5f1ca20e6d32dcbab17aba5b6b072fb927a72da99b4a11","src/task/poll.rs":"74c2717c1f9a37587a367da1b690d1cd2312e95dbaffca42be4755f1cd164bb8"},"package":"d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7"}

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.36"
name = "futures-core"
version = "0.3.18"
version = "0.3.19"
description = "The core traits and types in for the `futures` library.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"f2bc0157b925769ecff9a742de3a63eacb35331e9b7397876fa7380243b74874","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"151d3753b1ae87a1e1b1604c001ab8b2a5041b0e90ed09ea18d792081c424370","benches/thread_notify.rs":"e601968527bee85766f32d2d11de5ed8f6b4bd5a29989b5c369a52bd3cd3d024","src/enter.rs":"c1a771f373b469d98e2599d8e37da7d7a7083c30332d643f37867f86406ab1e2","src/lib.rs":"08a25594c789cb4ce1c8929a9ddd745e67fee1db373e011a7ebe135933522614","src/local_pool.rs":"1661a58468491d714a358b6382df88bbd7557e19506009763f841cbcf85781f5","src/thread_pool.rs":"206d5c9d16857d6b2cc9aecb63cd1c9859177b2eaea9b1d7055f5c42bd1ce33f","src/unpark_mutex.rs":"e186464d9bdec22a6d1e1d900ed03a1154e6b0d422ede9bd3b768657cdbb6113","tests/local_pool.rs":"c7f870582a29cdb6ebbb3a325ddb8485c61efac80fb96656003162294f4ec923"},"package":"7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"}
{"files":{"Cargo.toml":"c6d60a83b1a88b21d0173ac269f6811d42618d8a216e14bfb32d56347871747a","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"151d3753b1ae87a1e1b1604c001ab8b2a5041b0e90ed09ea18d792081c424370","benches/thread_notify.rs":"e601968527bee85766f32d2d11de5ed8f6b4bd5a29989b5c369a52bd3cd3d024","src/enter.rs":"c1a771f373b469d98e2599d8e37da7d7a7083c30332d643f37867f86406ab1e2","src/lib.rs":"08a25594c789cb4ce1c8929a9ddd745e67fee1db373e011a7ebe135933522614","src/local_pool.rs":"1661a58468491d714a358b6382df88bbd7557e19506009763f841cbcf85781f5","src/thread_pool.rs":"206d5c9d16857d6b2cc9aecb63cd1c9859177b2eaea9b1d7055f5c42bd1ce33f","src/unpark_mutex.rs":"e186464d9bdec22a6d1e1d900ed03a1154e6b0d422ede9bd3b768657cdbb6113","tests/local_pool.rs":"c7f870582a29cdb6ebbb3a325ddb8485c61efac80fb96656003162294f4ec923"},"package":"29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a"}

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.45"
name = "futures-executor"
version = "0.3.18"
version = "0.3.19"
description = "Executors for asynchronous tasks based on the futures-rs library.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"
@ -22,15 +22,15 @@ repository = "https://github.com/rust-lang/futures-rs"
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies.futures-core]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-task]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-util]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.num_cpus]

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"3fe694cf8d976b18177e0d293eed1114dddb6ae8f7a47c4986714dff7dfb9a51","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"575430be5c47352d85f36b44dcc2c2851a6a19e2384593415c4af22c6654cee7","src/lib.rs":"ed7cdabff6c25bf4f917b071055962a88809cc4a23a6fc98395d0d72d1d930fd"},"package":"e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"}
{"files":{"Cargo.toml":"3a6ff8f01952afc090840100031af93a25a429da7baf4d134e559abdfd9c9b2a","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"575430be5c47352d85f36b44dcc2c2851a6a19e2384593415c4af22c6654cee7","src/lib.rs":"526e9700c28250b7512f122952257d57adc38eb001af92ef25bdb48a8c453175"},"package":"b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2"}

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.36"
name = "futures-io"
version = "0.3.18"
version = "0.3.19"
description = "The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"
@ -26,6 +26,5 @@ rustdoc-args = ["--cfg", "docsrs"]
[features]
default = ["std"]
read-initializer = []
std = []
unstable = []

View File

@ -8,7 +8,6 @@
//! All items of this library are only available when the `std` feature of this
//! library is activated, and it is activated by default.
#![cfg_attr(all(feature = "read-initializer", feature = "std"), feature(read_initializer))]
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)]
// It cannot be included in the published code because this lints have false positives in the minimum required version.
@ -22,9 +21,6 @@
))]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(all(feature = "read-initializer", not(feature = "unstable")))]
compile_error!("The `read-initializer` feature requires the `unstable` feature as an explicit opt-in to unstable features");
#[cfg(feature = "std")]
mod if_std {
use std::io;
@ -34,11 +30,6 @@ mod if_std {
// Re-export some types from `std::io` so that users don't have to deal
// with conflicts when `use`ing `futures::io` and `std::io`.
#[cfg(feature = "read-initializer")]
#[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
#[doc(no_inline)]
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use io::Initializer;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
#[doc(no_inline)]
pub use io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
@ -51,27 +42,6 @@ mod if_std {
/// for wakeup and return if data is not yet available, rather than blocking
/// the calling thread.
pub trait AsyncRead {
/// Determines if this `AsyncRead`er can work with buffers of
/// uninitialized memory.
///
/// The default implementation returns an initializer which will zero
/// buffers.
///
/// This method is only available when the `read-initializer` feature of this
/// library is activated.
///
/// # Safety
///
/// This method is `unsafe` because an `AsyncRead`er could otherwise
/// return a non-zeroing `Initializer` from another `AsyncRead` type
/// without an `unsafe` block.
#[cfg(feature = "read-initializer")]
#[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
#[inline]
unsafe fn initializer(&self) -> Initializer {
Initializer::zeroing()
}
/// Attempt to read from the `AsyncRead` into `buf`.
///
/// On success, returns `Poll::Ready(Ok(num_bytes_read))`.
@ -329,11 +299,6 @@ mod if_std {
macro_rules! deref_async_read {
() => {
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
(**self).initializer()
}
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
@ -365,11 +330,6 @@ mod if_std {
P: DerefMut + Unpin,
P::Target: AsyncRead,
{
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
(**self).initializer()
}
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
@ -389,11 +349,6 @@ mod if_std {
macro_rules! delegate_async_read_to_stdio {
() => {
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
io::Read::initializer(self)
}
fn poll_read(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"91e7006ff019782f4ef67b12106d8680236f8a3a084cc1e6764f149bfa145744","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/executor.rs":"2a6c40ebf1fb70ac5bd0dfb991c7b945210c731b558b546f2ecb6d7a8976f3f6","src/join.rs":"e0d286558bd944fd02c1bd2501d13e62de2aa65e6bd3a2e0567488ac1a2374ed","src/lib.rs":"8324c4d5cc4e9e377b2f95afde751168d7e94196c1f2cb35802193c900ca0026","src/select.rs":"a7ed344932225fbe1b070d132a937184250c31385ac6764a8a6e6817413c7538","src/stream_select.rs":"5fb84834a40876ab1fd975c3af67594d0c5a4f8d724cb164db9bee71e70d14b1"},"package":"a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"}
{"files":{"Cargo.toml":"46ecfcda3cd6979538f7543858fcfecb52c319cec94d041ab369139723ffa69d","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/executor.rs":"2a6c40ebf1fb70ac5bd0dfb991c7b945210c731b558b546f2ecb6d7a8976f3f6","src/join.rs":"e0d286558bd944fd02c1bd2501d13e62de2aa65e6bd3a2e0567488ac1a2374ed","src/lib.rs":"8324c4d5cc4e9e377b2f95afde751168d7e94196c1f2cb35802193c900ca0026","src/select.rs":"a7ed344932225fbe1b070d132a937184250c31385ac6764a8a6e6817413c7538","src/stream_select.rs":"5fb84834a40876ab1fd975c3af67594d0c5a4f8d724cb164db9bee71e70d14b1"},"package":"6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c"}

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.45"
name = "futures-macro"
version = "0.3.18"
version = "0.3.19"
description = "The futures-rs procedural macro implementations.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"7632dfc3867d05e50aa520b300be44f1f0b345d5a16a460618b05b510a9051db","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"a509e1ce84f285190130def6d2b9e3861988f9be725f7697f09fba347601d86f","src/lib.rs":"90c41f91e4b6764a218d4f337a9a46fba1e256f59f67b0afa5352ba92bf641c0"},"package":"996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"}
{"files":{"Cargo.toml":"0d41bfc59fc07239fd6c7a084dbfe9379398a2e9a081160476229bf30da16ecd","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"a509e1ce84f285190130def6d2b9e3861988f9be725f7697f09fba347601d86f","src/lib.rs":"90c41f91e4b6764a218d4f337a9a46fba1e256f59f67b0afa5352ba92bf641c0"},"package":"e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508"}

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.36"
name = "futures-sink"
version = "0.3.18"
version = "0.3.19"
description = "The asynchronous `Sink` trait for the futures-rs library.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"428ebb024635d4816406193a092e288c0fd14c54588bf16f56a286252631b222","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"8d029604e66d3fc39468bd937859e642c843ad43f8dddfb4f9cbb467a111f9e6","build.rs":"f6e21c09f18cc405bd7048cb7a2958f92d5414b9ca6b301d137e120a84fa020a","no_atomic_cas.rs":"ff8be002b49a5cd9e4ca0db17b1c9e6b98e55f556319eb6b953dd6ff52c397a6","src/arc_wake.rs":"0e3f7d7883b75337b0b92ff55e477f0bf96f6eb08def7d953676a289fd9696ec","src/future_obj.rs":"10dab39a613d938823f09c3ecdbf7e199ac173a775fd8c5db675c7ecb3b429a2","src/lib.rs":"c55281988768d44d3305b2352c7ebb66e6449797239c07b14257a2d8e612e06b","src/noop_waker.rs":"41246601dab77f69bf09257afc3321031a5a31a7eda51787029870eda9922356","src/spawn.rs":"afcf46b98d62e78d2c974f91df32590bd78fe8c79031e4ae7accf9270e1f6224","src/waker.rs":"748d4a045ea9be605a67f3c20607cc3a5ba20036942c0016cc4299df0446507c","src/waker_ref.rs":"8e3ce1aea4f433ce04c2d15eb065d89582527c1a3a15886c445eb3a78f4fd0d6"},"package":"dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"}
{"files":{"Cargo.toml":"984bf931be396558123b5ebca33f16f0e24468c7b1aea54f7a11271c42f168e0","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"8d029604e66d3fc39468bd937859e642c843ad43f8dddfb4f9cbb467a111f9e6","build.rs":"f6e21c09f18cc405bd7048cb7a2958f92d5414b9ca6b301d137e120a84fa020a","no_atomic_cas.rs":"ff8be002b49a5cd9e4ca0db17b1c9e6b98e55f556319eb6b953dd6ff52c397a6","src/arc_wake.rs":"0e3f7d7883b75337b0b92ff55e477f0bf96f6eb08def7d953676a289fd9696ec","src/future_obj.rs":"10dab39a613d938823f09c3ecdbf7e199ac173a775fd8c5db675c7ecb3b429a2","src/lib.rs":"c55281988768d44d3305b2352c7ebb66e6449797239c07b14257a2d8e612e06b","src/noop_waker.rs":"41246601dab77f69bf09257afc3321031a5a31a7eda51787029870eda9922356","src/spawn.rs":"afcf46b98d62e78d2c974f91df32590bd78fe8c79031e4ae7accf9270e1f6224","src/waker.rs":"748d4a045ea9be605a67f3c20607cc3a5ba20036942c0016cc4299df0446507c","src/waker_ref.rs":"8e3ce1aea4f433ce04c2d15eb065d89582527c1a3a15886c445eb3a78f4fd0d6"},"package":"6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72"}

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.36"
name = "futures-task"
version = "0.3.18"
version = "0.3.19"
description = "Tools for working with tasks.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.45"
name = "futures-util"
version = "0.3.18"
version = "0.3.19"
description = "Common utilities and extension traits for the futures-rs library.\n"
homepage = "https://rust-lang.github.io/futures-rs"
license = "MIT OR Apache-2.0"
@ -22,33 +22,33 @@ repository = "https://github.com/rust-lang/futures-rs"
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies.futures-channel]
version = "0.3.18"
version = "0.3.19"
features = ["std"]
optional = true
default-features = false
[dependencies.futures-core]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-io]
version = "0.3.18"
version = "0.3.19"
features = ["std"]
optional = true
default-features = false
[dependencies.futures-macro]
version = "=0.3.18"
version = "=0.3.19"
optional = true
default-features = false
[dependencies.futures-sink]
version = "0.3.18"
version = "0.3.19"
optional = true
default-features = false
[dependencies.futures-task]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures_01]
@ -87,7 +87,6 @@ compat = ["std", "futures_01"]
default = ["std", "async-await", "async-await-macro"]
io = ["std", "futures-io", "memchr"]
io-compat = ["io", "compat", "tokio-io"]
read-initializer = ["io", "futures-io/read-initializer", "futures-io/unstable"]
sink = ["futures-sink"]
std = ["alloc", "futures-core/std", "futures-task/std", "slab"]
unstable = ["futures-core/unstable", "futures-task/unstable"]

View File

@ -351,8 +351,6 @@ unsafe impl UnsafeNotify01 for NotifyWaker {
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
mod io {
use super::*;
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03};
use std::io::Error;
use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01};
@ -416,16 +414,6 @@ mod io {
impl<W: AsyncWrite01> AsyncWrite01CompatExt for W {}
impl<R: AsyncRead01> AsyncRead03 for Compat01As03<R> {
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
// check if `prepare_uninitialized_buffer` needs zeroing
if self.inner.get_ref().prepare_uninitialized_buffer(&mut [1]) {
Initializer::zeroing()
} else {
Initializer::nop()
}
}
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,

View File

@ -236,17 +236,7 @@ mod io {
}
}
impl<R: AsyncRead03 + Unpin> AsyncRead01 for Compat<R> {
#[cfg(feature = "read-initializer")]
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
let initializer = self.inner.initializer();
let does_init = initializer.should_initialize();
if does_init {
initializer.initialize(buf);
}
does_init
}
}
impl<R: AsyncRead03 + Unpin> AsyncRead01 for Compat<R> {}
impl<W: AsyncWrite03 + Unpin> std::io::Write for Compat<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {

View File

@ -184,8 +184,6 @@ mod if_std {
use core::pin::Pin;
use core::task::{Context, Poll};
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{
AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom,
};
@ -195,14 +193,6 @@ mod if_std {
A: AsyncRead,
B: AsyncRead,
{
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
match self {
Either::Left(x) => x.initializer(),
Either::Right(x) => x.initializer(),
}
}
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,

View File

@ -1,6 +1,4 @@
use futures_core::task::{Context, Poll};
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
use std::pin::Pin;
use std::{fmt, io};
@ -121,10 +119,6 @@ where
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
self.0.read_vectored(bufs)
}
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
self.0.initializer()
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
@ -155,11 +149,6 @@ where
) -> Poll<io::Result<usize>> {
Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs))))
}
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
self.0.initializer()
}
}
impl<T> io::Seek for AllowStdIo<T>

View File

@ -2,8 +2,6 @@ use super::DEFAULT_BUF_SIZE;
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSliceMut, SeekFrom};
use pin_project_lite::pin_project;
use std::io::{self, Read};
@ -144,12 +142,6 @@ impl<R: AsyncRead> AsyncRead for BufReader<R> {
self.consume(nread);
Poll::Ready(Ok(nread))
}
// we can't skip unconditionally because of the large buffer case in read.
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
self.inner.initializer()
}
}
impl<R: AsyncRead> AsyncBufRead for BufReader<R> {

View File

@ -1,7 +1,5 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead, IoSliceMut};
use pin_project_lite::pin_project;
use std::fmt;
@ -111,16 +109,6 @@ where
}
this.second.poll_read_vectored(cx, bufs)
}
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
let initializer = self.first.initializer();
if initializer.should_initialize() {
initializer
} else {
self.second.initializer()
}
}
}
impl<T, U> AsyncBufRead for Chain<T, U>

View File

@ -1,6 +1,4 @@
use futures_core::task::{Context, Poll};
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead};
use std::fmt;
use std::io;
@ -43,12 +41,6 @@ impl AsyncRead for Empty {
) -> Poll<io::Result<usize>> {
Poll::Ready(Ok(0))
}
#[cfg(feature = "read-initializer")]
#[inline]
unsafe fn initializer(&self) -> Initializer {
Initializer::nop()
}
}
impl AsyncBufRead for Empty {

View File

@ -26,10 +26,6 @@ use std::{pin::Pin, ptr};
// Re-export some types from `std::io` so that users don't have to deal
// with conflicts when `use`ing `futures::io` and `std::io`.
#[doc(no_inline)]
#[cfg(feature = "read-initializer")]
#[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
pub use std::io::Initializer;
#[doc(no_inline)]
pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite};
@ -40,15 +36,9 @@ const DEFAULT_BUF_SIZE: usize = 8 * 1024;
/// Initializes a buffer if necessary.
///
/// A buffer is always initialized if `read-initializer` feature is disabled.
/// A buffer is currently always initialized.
#[inline]
unsafe fn initialize<R: AsyncRead>(_reader: &R, buf: &mut [u8]) {
#[cfg(feature = "read-initializer")]
{
if !_reader.initializer().should_initialize() {
return;
}
}
ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len())
}

View File

@ -1,7 +1,5 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{AsyncRead, IoSliceMut};
use std::fmt;
use std::io;
@ -59,12 +57,6 @@ impl AsyncRead for Repeat {
}
Poll::Ready(Ok(nwritten))
}
#[cfg(feature = "read-initializer")]
#[inline]
unsafe fn initializer(&self) -> Initializer {
Initializer::nop()
}
}
impl fmt::Debug for Repeat {

View File

@ -1,7 +1,5 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
#[cfg(feature = "read-initializer")]
use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead};
use pin_project_lite::pin_project;
use std::pin::Pin;
@ -100,11 +98,6 @@ impl<R: AsyncRead> AsyncRead for Take<R> {
*this.limit -= n as u64;
Poll::Ready(Ok(n))
}
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> Initializer {
self.inner.initializer()
}
}
impl<R: AsyncBufRead> AsyncBufRead for Take<R> {

View File

@ -1,7 +1,6 @@
//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s,
//! and the `AsyncRead` and `AsyncWrite` traits.
#![cfg_attr(feature = "read-initializer", feature(read_initializer))]
#![cfg_attr(feature = "write-all-vectored", feature(io_slice_advance))]
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(
@ -23,9 +22,6 @@
#[cfg(all(feature = "bilock", not(feature = "unstable")))]
compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features");
#[cfg(all(feature = "read-initializer", not(feature = "unstable")))]
compile_error!("The `read-initializer` feature requires the `unstable` feature as an explicit opt-in to unstable features");
#[cfg(feature = "alloc")]
extern crate alloc;
@ -148,11 +144,6 @@ macro_rules! delegate_async_write {
#[cfg(feature = "std")]
macro_rules! delegate_async_read {
($field:ident) => {
#[cfg(feature = "read-initializer")]
unsafe fn initializer(&self) -> $crate::io::Initializer {
self.$field.initializer()
}
fn poll_read(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,

View File

@ -6,6 +6,7 @@
use crate::task::AtomicWaker;
use alloc::sync::{Arc, Weak};
use core::cell::UnsafeCell;
use core::cmp;
use core::fmt::{self, Debug};
use core::iter::FromIterator;
use core::marker::PhantomData;
@ -30,6 +31,33 @@ use self::task::Task;
mod ready_to_run_queue;
use self::ready_to_run_queue::{Dequeue, ReadyToRunQueue};
/// Constant used for a `FuturesUnordered` to determine how many times it is
/// allowed to poll underlying futures without yielding.
///
/// A single call to `poll_next` may potentially do a lot of work before
/// yielding. This happens in particular if the underlying futures are awoken
/// frequently but continue to return `Pending`. This is problematic if other
/// tasks are waiting on the executor, since they do not get to run. This value
/// caps the number of calls to `poll` on underlying futures a single call to
/// `poll_next` is allowed to make.
///
/// The value itself is chosen somewhat arbitrarily. It needs to be high enough
/// that amortize wakeup and scheduling costs, but low enough that we do not
/// starve other tasks for long.
///
/// See also https://github.com/rust-lang/futures-rs/issues/2047.
///
/// Note that using the length of the `FuturesUnordered` instead of this value
/// may cause problems if the number of futures is large.
/// See also https://github.com/rust-lang/futures-rs/pull/2527.
///
/// Additionally, polling the same future twice per iteration may cause another
/// problem. So, when using this value, it is necessary to limit the max value
/// based on the length of the `FuturesUnordered`.
/// (e.g., `cmp::min(self.len(), YIELD_EVERY)`)
/// See also https://github.com/rust-lang/futures-rs/pull/2333.
const YIELD_EVERY: usize = 32;
/// A set of futures which may complete in any order.
///
/// This structure is optimized to manage a large number of futures.
@ -383,21 +411,8 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
type Item = Fut::Output;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
// Variable to determine how many times it is allowed to poll underlying
// futures without yielding.
//
// A single call to `poll_next` may potentially do a lot of work before
// yielding. This happens in particular if the underlying futures are awoken
// frequently but continue to return `Pending`. This is problematic if other
// tasks are waiting on the executor, since they do not get to run. This value
// caps the number of calls to `poll` on underlying futures a single call to
// `poll_next` is allowed to make.
//
// The value is the length of FuturesUnordered. This ensures that each
// future is polled only once at most per iteration.
//
// See also https://github.com/rust-lang/futures-rs/issues/2047.
let yield_every = self.len();
// See YIELD_EVERY docs for more.
let yield_every = cmp::min(self.len(), YIELD_EVERY);
// Keep track of how many child futures we have polled,
// in case we want to forcibly yield.
@ -558,7 +573,7 @@ impl<Fut> FuturesUnordered<Fut> {
pub fn clear(&mut self) {
self.clear_head_all();
// SAFETY: we just cleared all the tasks and we have &mut self
// we just cleared all the tasks, and we have &mut self, so this is safe.
unsafe { self.ready_to_run_queue.clear() };
self.is_terminated.store(false, Relaxed);
@ -575,9 +590,24 @@ impl<Fut> FuturesUnordered<Fut> {
impl<Fut> Drop for FuturesUnordered<Fut> {
fn drop(&mut self) {
// When a `FuturesUnordered` is dropped we want to drop all futures
// associated with it. At the same time though there may be tons of
// wakers flying around which contain `Task<Fut>` references
// inside them. We'll let those naturally get deallocated.
self.clear_head_all();
// SAFETY: we just cleared all the tasks and we have &mut self
unsafe { self.ready_to_run_queue.clear() };
// Note that at this point we could still have a bunch of tasks in the
// ready to run queue. None of those tasks, however, have futures
// associated with them so they're safe to destroy on any thread. At
// this point the `FuturesUnordered` struct, the owner of the one strong
// reference to the ready to run queue will drop the strong reference.
// At that point whichever thread releases the strong refcount last (be
// it this thread or some other thread as part of an `upgrade`) will
// clear out the ready to run queue and free all remaining tasks.
//
// While that freeing operation isn't guaranteed to happen here, it's
// guaranteed to happen "promptly" as no more "blocking work" will
// happen while there's a strong refcount held.
}
}

View File

@ -94,7 +94,7 @@ impl<Fut> ReadyToRunQueue<Fut> {
//
// # Safety
//
// - All tasks **must** have had their futures dropped already (by FuturesUnordered::clear_head_all)
// - All tasks **must** have had their futures dropped already (by FuturesUnordered::clear)
// - The caller **must** guarantee unique access to `self`
pub(crate) unsafe fn clear(&self) {
loop {
@ -107,3 +107,16 @@ impl<Fut> ReadyToRunQueue<Fut> {
}
}
}
impl<Fut> Drop for ReadyToRunQueue<Fut> {
fn drop(&mut self) {
// Once we're in the destructor for `Inner<Fut>` we need to clear out
// the ready to run queue of tasks if there's anything left in there.
// All tasks have had their futures dropped already by the `FuturesUnordered`
// destructor above, and we have &mut self, so this is safe.
unsafe {
self.clear();
}
}
}

View File

@ -0,0 +1,53 @@
use core::fmt;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::ready;
use futures_core::stream::{FusedStream, Stream};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
/// Future for the [`count`](super::StreamExt::count) method.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Count<St> {
#[pin]
stream: St,
count: usize
}
}
impl<St> fmt::Debug for Count<St>
where
St: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Count").field("stream", &self.stream).field("count", &self.count).finish()
}
}
impl<St: Stream> Count<St> {
pub(super) fn new(stream: St) -> Self {
Self { stream, count: 0 }
}
}
impl<St: FusedStream> FusedFuture for Count<St> {
fn is_terminated(&self) -> bool {
self.stream.is_terminated()
}
}
impl<St: Stream> Future for Count<St> {
type Output = usize;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project();
Poll::Ready(loop {
match ready!(this.stream.as_mut().poll_next(cx)) {
Some(_) => *this.count += 1,
None => break *this.count,
}
})
}
}

View File

@ -40,6 +40,10 @@ mod concat;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::concat::Concat;
mod count;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::count::Count;
mod cycle;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::cycle::Cycle;
@ -576,6 +580,38 @@ pub trait StreamExt: Stream {
assert_future::<Self::Item, _>(Concat::new(self))
}
/// Drives the stream to completion, counting the number of items.
///
/// # Overflow Behavior
///
/// The method does no guarding against overflows, so counting elements of a
/// stream with more than [`usize::MAX`] elements either produces the wrong
/// result or panics. If debug assertions are enabled, a panic is guaranteed.
///
/// # Panics
///
/// This function might panic if the iterator has more than [`usize::MAX`]
/// elements.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::stream::{self, StreamExt};
///
/// let stream = stream::iter(1..=10);
/// let count = stream.count().await;
///
/// assert_eq!(count, 10);
/// # });
/// ```
fn count(self) -> Count<Self>
where
Self: Sized,
{
assert_future::<usize, _>(Count::new(self))
}
/// Repeats a stream endlessly.
///
/// The stream never terminates. Note that you likely want to avoid

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.45"
name = "futures"
version = "0.3.18"
version = "0.3.19"
description = "An implementation of futures and streams featuring zero allocations,\ncomposability, and iterator-like interfaces.\n"
homepage = "https://rust-lang.github.io/futures-rs"
readme = "../README.md"
@ -28,33 +28,33 @@ rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.playground]
features = ["std", "async-await", "compat", "io-compat", "executor", "thread-pool"]
[dependencies.futures-channel]
version = "0.3.18"
version = "0.3.19"
features = ["sink"]
default-features = false
[dependencies.futures-core]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-executor]
version = "0.3.18"
version = "0.3.19"
optional = true
default-features = false
[dependencies.futures-io]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-sink]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-task]
version = "0.3.18"
version = "0.3.19"
default-features = false
[dependencies.futures-util]
version = "0.3.18"
version = "0.3.19"
features = ["sink"]
default-features = false
[dev-dependencies.assert_matches]
@ -81,7 +81,6 @@ compat = ["std", "futures-util/compat"]
default = ["std", "async-await", "executor"]
executor = ["std", "futures-executor/std"]
io-compat = ["compat", "futures-util/io-compat"]
read-initializer = ["futures-io/read-initializer", "futures-util/read-initializer"]
std = ["alloc", "futures-core/std", "futures-task/std", "futures-io/std", "futures-sink/std", "futures-util/std", "futures-util/io", "futures-util/channel"]
thread-pool = ["executor", "futures-executor/thread-pool"]
unstable = ["futures-core/unstable", "futures-task/unstable", "futures-channel/unstable", "futures-io/unstable", "futures-util/unstable"]

View File

@ -78,7 +78,6 @@
//! The majority of examples and code snippets in this crate assume that they are
//! inside an async block as written above.
#![cfg_attr(feature = "read-initializer", feature(read_initializer))]
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(
missing_debug_implementations,
@ -99,9 +98,6 @@
#[cfg(all(feature = "bilock", not(feature = "unstable")))]
compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features");
#[cfg(all(feature = "read-initializer", not(feature = "unstable")))]
compile_error!("The `read-initializer` feature requires the `unstable` feature as an explicit opt-in to unstable features");
#[doc(no_inline)]
pub use futures_core::future::{Future, TryFuture};
#[doc(no_inline)]

View File

@ -340,7 +340,7 @@ fn polled_only_once_at_most_per_iteration() {
let mut tasks = FuturesUnordered::from_iter(vec![F::default(); 33]);
assert!(tasks.poll_next_unpin(cx).is_pending());
assert_eq!(33, tasks.iter().filter(|f| f.polled).count());
assert_eq!(32, tasks.iter().filter(|f| f.polled).count());
let mut tasks = FuturesUnordered::<F>::new();
assert_eq!(Poll::Ready(None), tasks.poll_next_unpin(cx));

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"af4fe12b69e1354864a33c43eab5f8466d435a216b35c8fb4b6b567d11dfb28a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","src/IdnaMappingTable.txt":"813a8308aeff8bcb9368751e1fd0ad7cc467130965d53ac860f82c4d0d11523f","src/lib.rs":"590280903e929c7eadd5473faf67c48293d734b9a75ea42798264b6b10d3f33f","src/make_uts46_mapping_table.py":"fd4ff62fc27dc8d15d5b61c3504f5f754aded1c3e16c1179506adff5df766d74","src/punycode.rs":"fe078681e4a565615b71a7f8ce92373de59f09cffc1aac074822b0e1630a0cba","src/uts46.rs":"96b47ff8cc1a992bfc2f8b9138eb9a92908dce1de2e6457cc7e6d2a187fe0b5d","src/uts46_mapping_table.rs":"9d0b645182592709ea87c6db7ca1c4e1d9b2826b68efd746f764cafcb0545da2","tests/IdnaTest.txt":"921c68e5d3fbb631b26140d232af90040fc4df612857d1894641ded319e52822","tests/punycode.rs":"5a786d09f2bbedfdbd9ac18c99af25ecaf097710b5760792c328c78c1750a209","tests/punycode_tests.json":"3d4ac0cf25984c37b9ce197f5df680a0136f728fb8ec82bc76624e42139eb3a8","tests/tests.rs":"84d56979840dcbb1100cc5e0a5450be642b1e5dfc76abf853da121035903e5ae","tests/unit.rs":"4a20fded1ac8bc5177f28ae49dcbb25f9a646300de4524ce8ca20258a558d3fc","tests/uts46.rs":"ce896ba3d39f0d8e82975b97d2b9540e37b3928d07eb2dd2fb4a83f4deb4873d"},"package":"02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"}
{"files":{"Cargo.toml":"6f1fd46d4d9575d5a7f46873cb40a93e973e9fb8f574b28a1b21b596df618a89","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","benches/all.rs":"e734b9c9092ed66986725f86cfe90f3756cfddb058af308b796ba494f9beefc2","src/IdnaMappingTable.txt":"87d6553a4b86bc49dcade38bf26b745cd81800eb8af295dc3fb99b4729eaea38","src/lib.rs":"d61b2bfcf4265b9a41eedd1de33ab49ea615e3c06df944321b30c57950a85342","src/make_uts46_mapping_table.py":"d420883d17b44c42109317ffaf1c273e611864eaeb1c5f1b9d93634a5d586835","src/punycode.rs":"dceeb0467197f892d2c777711b3c6647238f52f3976dfca5a8f8957500fd3599","src/uts46.rs":"49aaae3c5a9503bc7ef59b1a2e76ba158154132515e7c85ab670130ed5da318f","src/uts46_mapping_table.rs":"90c4180dd865b919bf1b2f13459c9c5b9de0cbbdff6584f742a7ecc0c14d3cdd","tests/IdnaTestV2.txt":"c6f3778b0545fd150c8063286c7f5adc901e16557eddccc3751213646d07593d","tests/punycode.rs":"8efdaae0902a8ffe483ae69236c9d0a38979cfd2430e69b87f33975e6946d577","tests/punycode_tests.json":"3d4ac0cf25984c37b9ce197f5df680a0136f728fb8ec82bc76624e42139eb3a8","tests/tests.rs":"de7425a3e4e6e871255721107803704d1431246601fa9c87105224d88dfe60d6","tests/unit.rs":"9600ec4f67ae44e8457fb64a9872d190a1a4d807e32d9688c8fa3ef9135c7a5d","tests/uts46.rs":"ca91d48811d366fb9e32d7aa79cfda1261b93c271b6ed7fb5535de9a2500205b"},"package":"de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094"}

View File

@ -11,8 +11,9 @@
# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "idna"
version = "0.2.0"
version = "0.2.1"
authors = ["The rust-url developers"]
autotests = false
description = "IDNA (Internationalizing Domain Names in Applications) and Punycode."
@ -20,7 +21,6 @@ license = "MIT/Apache-2.0"
repository = "https://github.com/servo/rust-url/"
[lib]
test = false
doctest = false
[[test]]
@ -29,6 +29,10 @@ harness = false
[[test]]
name = "unit"
[[bench]]
name = "all"
harness = false
[dependencies.matches]
version = "0.1"
@ -37,6 +41,12 @@ version = "0.3"
[dependencies.unicode-normalization]
version = "0.1.5"
[dev-dependencies.assert_matches]
version = "1.3"
[dev-dependencies.bencher]
version = "0.1"
[dev-dependencies.rustc-test]
version = "0.3"

53
third_party/rust/idna/benches/all.rs vendored Normal file
View File

@ -0,0 +1,53 @@
#[macro_use]
extern crate bencher;
extern crate idna;
use bencher::{black_box, Bencher};
use idna::Config;
fn to_unicode_puny_label(bench: &mut Bencher) {
let encoded = "abc.xn--mgbcm";
let config = Config::default();
bench.iter(|| config.to_unicode(black_box(encoded)));
}
fn to_unicode_ascii(bench: &mut Bencher) {
let encoded = "example.com";
let config = Config::default();
bench.iter(|| config.to_unicode(black_box(encoded)));
}
fn to_unicode_merged_label(bench: &mut Bencher) {
let encoded = "Beispiel.xn--vermgensberater-ctb";
let config = Config::default();
bench.iter(|| config.to_unicode(black_box(encoded)));
}
fn to_ascii_puny_label(bench: &mut Bencher) {
let encoded = "abc.ابج";
let config = Config::default();
bench.iter(|| config.to_ascii(black_box(encoded)));
}
fn to_ascii_simple(bench: &mut Bencher) {
let encoded = "example.com";
let config = Config::default();
bench.iter(|| config.to_ascii(black_box(encoded)));
}
fn to_ascii_merged(bench: &mut Bencher) {
let encoded = "beispiel.vermögensberater";
let config = Config::default();
bench.iter(|| config.to_ascii(black_box(encoded)));
}
benchmark_group!(
benches,
to_unicode_puny_label,
to_unicode_ascii,
to_unicode_merged_label,
to_ascii_puny_label,
to_ascii_simple,
to_ascii_merged,
);
benchmark_main!(benches);

File diff suppressed because it is too large Load Diff

View File

@ -34,13 +34,11 @@
#[macro_use]
extern crate matches;
extern crate unicode_bidi;
extern crate unicode_normalization;
pub mod punycode;
mod uts46;
pub use uts46::{Config, Errors};
pub use crate::uts46::{Config, Errors, Idna};
/// The [domain to ASCII](https://url.spec.whatwg.org/#concept-domain-to-ascii) algorithm.
///

View File

@ -10,12 +10,11 @@
# You can get the latest idna table from
# http://www.unicode.org/Public/idna/latest/IdnaMappingTable.txt
from __future__ import print_function
import collections
import itertools
print('''\
// Copyright 2013-2014 The rust-url developers.
// Copyright 2013-2020 The rust-url developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
@ -32,7 +31,7 @@ def escape_char(c):
return "\\u{%x}" % ord(c[0])
def char(s):
return unichr(int(s, 16))
return chr(int(s, 16))
strtab = collections.OrderedDict()
strtab_offset = 0
@ -107,7 +106,7 @@ for (k, g) in grouped_ranges:
# the codepoint space.
a, b = itertools.tee(group)
next(b, None)
for (g1, g2) in itertools.izip(a, b):
for (g1, g2) in zip(a, b):
last_char = int(g1[1], 16)
next_char = int(g2[0], 16)
if last_char + 1 == next_char:
@ -150,7 +149,7 @@ def merge_single_char_ranges(ranges):
optimized_ranges = list(merge_single_char_ranges(optimized_ranges))
print("static TABLE: &'static [Range] = &[")
print("static TABLE: &[Range] = &[")
for ranges in optimized_ranges:
first = ranges[0][0]
@ -160,7 +159,7 @@ for ranges in optimized_ranges:
print("];\n")
print("static INDEX_TABLE: &'static [u16] = &[")
print("static INDEX_TABLE: &[u16] = &[")
SINGLE_MARKER = 1 << 15
@ -175,7 +174,7 @@ for ranges in optimized_ranges:
print("];\n")
print("static MAPPING_TABLE: &'static [Mapping] = &[")
print("static MAPPING_TABLE: &[Mapping] = &[")
for ranges in optimized_ranges:
for (first, last, mapping, unicode_str) in ranges:
@ -188,5 +187,5 @@ print("];\n")
def escape_str(s):
return [escape_char(c) for c in s]
print("static STRING_TABLE: &'static str = \"%s\";"
% '\\\n '.join(itertools.chain(*[escape_str(s) for s in strtab.iterkeys()])))
print("static STRING_TABLE: &str = \"%s\";"
% '\\\n '.join(itertools.chain(*[escape_str(s) for s in strtab.keys()])))

View File

@ -52,81 +52,157 @@ pub fn decode_to_string(input: &str) -> Option<String> {
/// Overflow can only happen on inputs that take more than
/// 63 encoded bytes, the DNS limit on domain name labels.
pub fn decode(input: &str) -> Option<Vec<char>> {
// Handle "basic" (ASCII) code points.
// They are encoded as-is before the last delimiter, if any.
let (mut output, input) = match input.rfind(DELIMITER) {
None => (Vec::new(), input),
Some(position) => (
input[..position].chars().collect(),
if position > 0 {
&input[position + 1..]
} else {
input
},
),
};
let mut code_point = INITIAL_N;
let mut bias = INITIAL_BIAS;
let mut i = 0;
let mut iter = input.bytes();
loop {
let previous_i = i;
let mut weight = 1;
let mut k = BASE;
let mut byte = match iter.next() {
None => break,
Some(byte) => byte,
Some(Decoder::default().decode(input).ok()?.collect())
}
#[derive(Default)]
pub(crate) struct Decoder {
insertions: Vec<(usize, char)>,
}
impl Decoder {
/// Split the input iterator and return a Vec with insertions of encoded characters
pub(crate) fn decode<'a>(&'a mut self, input: &'a str) -> Result<Decode<'a>, ()> {
self.insertions.clear();
// Handle "basic" (ASCII) code points.
// They are encoded as-is before the last delimiter, if any.
let (base, input) = match input.rfind(DELIMITER) {
None => ("", input),
Some(position) => (
&input[..position],
if position > 0 {
&input[position + 1..]
} else {
input
},
),
};
// Decode a generalized variable-length integer into delta,
// which gets added to i.
let base_len = base.len();
let mut length = base_len as u32;
let mut code_point = INITIAL_N;
let mut bias = INITIAL_BIAS;
let mut i = 0;
let mut iter = input.bytes();
loop {
let digit = match byte {
byte @ b'0'..=b'9' => byte - b'0' + 26,
byte @ b'A'..=b'Z' => byte - b'A',
byte @ b'a'..=b'z' => byte - b'a',
_ => return None,
} as u32;
if digit > (u32::MAX - i) / weight {
return None; // Overflow
}
i += digit * weight;
let t = if k <= bias {
T_MIN
} else if k >= bias + T_MAX {
T_MAX
} else {
k - bias
};
if digit < t {
break;
}
if weight > u32::MAX / (BASE - t) {
return None; // Overflow
}
weight *= BASE - t;
k += BASE;
byte = match iter.next() {
None => return None, // End of input before the end of this delta
let previous_i = i;
let mut weight = 1;
let mut k = BASE;
let mut byte = match iter.next() {
None => break,
Some(byte) => byte,
};
// Decode a generalized variable-length integer into delta,
// which gets added to i.
loop {
let digit = match byte {
byte @ b'0'..=b'9' => byte - b'0' + 26,
byte @ b'A'..=b'Z' => byte - b'A',
byte @ b'a'..=b'z' => byte - b'a',
_ => return Err(()),
} as u32;
if digit > (u32::MAX - i) / weight {
return Err(()); // Overflow
}
i += digit * weight;
let t = if k <= bias {
T_MIN
} else if k >= bias + T_MAX {
T_MAX
} else {
k - bias
};
if digit < t {
break;
}
if weight > u32::MAX / (BASE - t) {
return Err(()); // Overflow
}
weight *= BASE - t;
k += BASE;
byte = match iter.next() {
None => return Err(()), // End of input before the end of this delta
Some(byte) => byte,
};
}
bias = adapt(i - previous_i, length + 1, previous_i == 0);
if i / (length + 1) > u32::MAX - code_point {
return Err(()); // Overflow
}
// i was supposed to wrap around from length+1 to 0,
// incrementing code_point each time.
code_point += i / (length + 1);
i %= length + 1;
let c = match char::from_u32(code_point) {
Some(c) => c,
None => return Err(()),
};
// Move earlier insertions farther out in the string
for (idx, _) in &mut self.insertions {
if *idx >= i as usize {
*idx += 1;
}
}
self.insertions.push((i as usize, c));
length += 1;
i += 1;
}
let length = output.len() as u32;
bias = adapt(i - previous_i, length + 1, previous_i == 0);
if i / (length + 1) > u32::MAX - code_point {
return None; // Overflow
}
// i was supposed to wrap around from length+1 to 0,
// incrementing code_point each time.
code_point += i / (length + 1);
i %= length + 1;
let c = match char::from_u32(code_point) {
Some(c) => c,
None => return None,
};
output.insert(i as usize, c);
i += 1;
self.insertions.sort_by_key(|(i, _)| *i);
Ok(Decode {
base: base.chars(),
insertions: &self.insertions,
inserted: 0,
position: 0,
len: base_len + self.insertions.len(),
})
}
}
pub(crate) struct Decode<'a> {
base: std::str::Chars<'a>,
pub(crate) insertions: &'a [(usize, char)],
inserted: usize,
position: usize,
len: usize,
}
impl<'a> Iterator for Decode<'a> {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.insertions.get(self.inserted) {
Some((pos, c)) if *pos == self.position => {
self.inserted += 1;
self.position += 1;
return Some(*c);
}
_ => {}
}
if let Some(c) = self.base.next() {
self.position += 1;
return Some(c);
} else if self.inserted >= self.insertions.len() {
return None;
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len - self.position;
(len, Some(len))
}
}
impl<'a> ExactSizeIterator for Decode<'a> {
fn len(&self) -> usize {
self.len - self.position
}
Some(output)
}
/// Convert an Unicode `str` to Punycode.
@ -134,7 +210,8 @@ pub fn decode(input: &str) -> Option<Vec<char>> {
/// This is a convenience wrapper around `encode`.
#[inline]
pub fn encode_str(input: &str) -> Option<String> {
encode(&input.chars().collect::<Vec<char>>())
let mut buf = String::with_capacity(input.len());
encode_into(input.chars(), &mut buf).ok().map(|()| buf)
}
/// Convert Unicode to Punycode.
@ -142,42 +219,54 @@ pub fn encode_str(input: &str) -> Option<String> {
/// Return None on overflow, which can only happen on inputs that would take more than
/// 63 encoded bytes, the DNS limit on domain name labels.
pub fn encode(input: &[char]) -> Option<String> {
let mut buf = String::with_capacity(input.len());
encode_into(input.iter().copied(), &mut buf)
.ok()
.map(|()| buf)
}
pub(crate) fn encode_into<I>(input: I, output: &mut String) -> Result<(), ()>
where
I: Iterator<Item = char> + Clone,
{
// Handle "basic" (ASCII) code points. They are encoded as-is.
let output_bytes = input
.iter()
.filter_map(|&c| if c.is_ascii() { Some(c as u8) } else { None })
.collect();
let mut output = unsafe { String::from_utf8_unchecked(output_bytes) };
let basic_length = output.len() as u32;
let (mut input_length, mut basic_length) = (0, 0);
for c in input.clone() {
input_length += 1;
if c.is_ascii() {
output.push(c);
basic_length += 1;
}
}
if basic_length > 0 {
output.push_str("-")
output.push('-')
}
let mut code_point = INITIAL_N;
let mut delta = 0;
let mut bias = INITIAL_BIAS;
let mut processed = basic_length;
let input_length = input.len() as u32;
while processed < input_length {
// All code points < code_point have been handled already.
// Find the next larger one.
let min_code_point = input
.iter()
.map(|&c| c as u32)
.clone()
.map(|c| c as u32)
.filter(|&c| c >= code_point)
.min()
.unwrap();
if min_code_point - code_point > (u32::MAX - delta) / (processed + 1) {
return None; // Overflow
return Err(()); // Overflow
}
// Increase delta to advance the decoders <code_point,i> state to <min_code_point,0>
delta += (min_code_point - code_point) * (processed + 1);
code_point = min_code_point;
for &c in input {
for c in input.clone() {
let c = c as u32;
if c < code_point {
delta += 1;
if delta == 0 {
return None; // Overflow
return Err(()); // Overflow
}
}
if c == code_point {
@ -209,14 +298,14 @@ pub fn encode(input: &[char]) -> Option<String> {
delta += 1;
code_point += 1;
}
Some(output)
Ok(())
}
#[inline]
fn value_to_digit(value: u32) -> char {
match value {
0..=25 => (value as u8 + 'a' as u8) as char, // a..z
26..=35 => (value as u8 - 26 + '0' as u8) as char, // 0..9
0..=25 => (value as u8 + b'a') as char, // a..z
26..=35 => (value as u8 - 26 + b'0') as char, // 0..9
_ => panic!(),
}
}

View File

@ -10,15 +10,16 @@
//! (Unicode Technical Standard #46)](http://www.unicode.org/reports/tr46/)
use self::Mapping::*;
use punycode;
use crate::punycode;
use std::cmp::Ordering::{Equal, Greater, Less};
use std::{error::Error as StdError, fmt};
use unicode_bidi::{bidi_class, BidiClass};
use unicode_normalization::char::is_combining_mark;
use unicode_normalization::UnicodeNormalization;
use unicode_normalization::{is_nfc, UnicodeNormalization};
include!("uts46_mapping_table.rs");
const PUNYCODE_PREFIX: &'static str = "xn--";
const PUNYCODE_PREFIX: &str = "xn--";
#[derive(Debug)]
struct StringTableSlice {
@ -81,33 +82,65 @@ fn find_char(codepoint: char) -> &'static Mapping {
.unwrap()
}
fn map_char(codepoint: char, config: Config, output: &mut String, errors: &mut Vec<Error>) {
match *find_char(codepoint) {
Mapping::Valid => output.push(codepoint),
Mapping::Ignored => {}
Mapping::Mapped(ref slice) => output.push_str(decode_slice(slice)),
Mapping::Deviation(ref slice) => {
if config.transitional_processing {
output.push_str(decode_slice(slice))
} else {
output.push(codepoint)
struct Mapper<'a> {
chars: std::str::Chars<'a>,
config: Config,
errors: &'a mut Errors,
slice: Option<std::str::Chars<'static>>,
}
impl<'a> Iterator for Mapper<'a> {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(s) = &mut self.slice {
match s.next() {
Some(c) => return Some(c),
None => {
self.slice = None;
}
}
}
}
Mapping::Disallowed => {
errors.push(Error::DissallowedCharacter);
output.push(codepoint);
}
Mapping::DisallowedStd3Valid => {
if config.use_std3_ascii_rules {
errors.push(Error::DissallowedByStd3AsciiRules);
let codepoint = self.chars.next()?;
if let '.' | '-' | 'a'..='z' | '0'..='9' = codepoint {
return Some(codepoint);
}
output.push(codepoint)
}
Mapping::DisallowedStd3Mapped(ref slice) => {
if config.use_std3_ascii_rules {
errors.push(Error::DissallowedMappedInStd3);
}
output.push_str(decode_slice(slice))
return Some(match *find_char(codepoint) {
Mapping::Valid => codepoint,
Mapping::Ignored => continue,
Mapping::Mapped(ref slice) => {
self.slice = Some(decode_slice(slice).chars());
continue;
}
Mapping::Deviation(ref slice) => {
if self.config.transitional_processing {
self.slice = Some(decode_slice(slice).chars());
continue;
} else {
codepoint
}
}
Mapping::Disallowed => {
self.errors.disallowed_character = true;
codepoint
}
Mapping::DisallowedStd3Valid => {
if self.config.use_std3_ascii_rules {
self.errors.disallowed_by_std3_ascii_rules = true;
};
codepoint
}
Mapping::DisallowedStd3Mapped(ref slice) => {
if self.config.use_std3_ascii_rules {
self.errors.disallowed_mapped_in_std3 = true;
};
self.slice = Some(decode_slice(slice).chars());
continue;
}
});
}
}
}
@ -130,26 +163,19 @@ fn passes_bidi(label: &str, is_bidi_domain: bool) -> bool {
// LTR label
BidiClass::L => {
// Rule 5
loop {
match chars.next() {
Some(c) => {
if !matches!(
bidi_class(c),
BidiClass::L
| BidiClass::EN
| BidiClass::ES
| BidiClass::CS
| BidiClass::ET
| BidiClass::ON
| BidiClass::BN
| BidiClass::NSM
) {
return false;
}
}
None => {
break;
}
while let Some(c) = chars.next() {
if !matches!(
bidi_class(c),
BidiClass::L
| BidiClass::EN
| BidiClass::ES
| BidiClass::CS
| BidiClass::ET
| BidiClass::ON
| BidiClass::BN
| BidiClass::NSM
) {
return false;
}
}
@ -183,37 +209,28 @@ fn passes_bidi(label: &str, is_bidi_domain: bool) -> bool {
let mut found_an = false;
// Rule 2
loop {
match chars.next() {
Some(c) => {
let char_class = bidi_class(c);
for c in chars {
let char_class = bidi_class(c);
if char_class == BidiClass::EN {
found_en = true;
} else if char_class == BidiClass::AN {
found_an = true;
}
if char_class == BidiClass::EN {
found_en = true;
}
if char_class == BidiClass::AN {
found_an = true;
}
if !matches!(
char_class,
BidiClass::R
| BidiClass::AL
| BidiClass::AN
| BidiClass::EN
| BidiClass::ES
| BidiClass::CS
| BidiClass::ET
| BidiClass::ON
| BidiClass::BN
| BidiClass::NSM
) {
return false;
}
}
None => {
break;
}
if !matches!(
char_class,
BidiClass::R
| BidiClass::AL
| BidiClass::AN
| BidiClass::EN
| BidiClass::ES
| BidiClass::CS
| BidiClass::ET
| BidiClass::ON
| BidiClass::BN
| BidiClass::NSM
) {
return false;
}
}
// Rule 3
@ -254,24 +271,21 @@ fn passes_bidi(label: &str, is_bidi_domain: bool) -> bool {
}
}
return true;
true
}
/// Check the validity criteria for the given label
///
/// V1 (NFC) and V8 (Bidi) are checked inside `processing()` to prevent doing duplicate work.
///
/// http://www.unicode.org/reports/tr46/#Validity_Criteria
fn validate_full(label: &str, is_bidi_domain: bool, config: Config, errors: &mut Vec<Error>) {
// V1: Must be in NFC form.
if label.nfc().ne(label.chars()) {
errors.push(Error::ValidityCriteria);
} else {
validate(label, is_bidi_domain, config, errors);
}
}
fn validate(label: &str, is_bidi_domain: bool, config: Config, errors: &mut Vec<Error>) {
fn check_validity(label: &str, config: Config, errors: &mut Errors) {
let first_char = label.chars().next();
if first_char == None {
// Empty string, pass
return;
}
// V2: No U+002D HYPHEN-MINUS in both third and fourth positions.
//
// NOTE: Spec says that the label must not contain a HYPHEN-MINUS character in both the
@ -279,96 +293,215 @@ fn validate(label: &str, is_bidi_domain: bool, config: Config, errors: &mut Vec<
// https://github.com/whatwg/url/issues/53
// V3: neither begin nor end with a U+002D HYPHEN-MINUS
else if config.check_hyphens && (label.starts_with("-") || label.ends_with("-")) {
errors.push(Error::ValidityCriteria);
if config.check_hyphens && (label.starts_with('-') || label.ends_with('-')) {
errors.check_hyphens = true;
return;
}
// V4: not contain a U+002E FULL STOP
//
// Here, label can't contain '.' since the input is from .split('.')
// V5: not begin with a GC=Mark
else if is_combining_mark(first_char.unwrap()) {
errors.push(Error::ValidityCriteria);
if is_combining_mark(first_char.unwrap()) {
errors.start_combining_mark = true;
return;
}
// V6: Check against Mapping Table
else if label.chars().any(|c| match *find_char(c) {
if label.chars().any(|c| match *find_char(c) {
Mapping::Valid => false,
Mapping::Deviation(_) => config.transitional_processing,
Mapping::DisallowedStd3Valid => config.use_std3_ascii_rules,
_ => true,
}) {
errors.push(Error::ValidityCriteria);
errors.invalid_mapping = true;
return;
}
// V7: ContextJ rules
//
// TODO: Implement rules and add *CheckJoiners* flag.
// V8: Bidi rules
//
// TODO: Add *CheckBidi* flag
else if !passes_bidi(label, is_bidi_domain) {
errors.push(Error::ValidityCriteria);
}
// V8: Bidi rules are checked inside `processing()`
}
/// http://www.unicode.org/reports/tr46/#Processing
fn processing(domain: &str, config: Config, errors: &mut Vec<Error>) -> String {
let mut mapped = String::with_capacity(domain.len());
#[allow(clippy::manual_strip)] // introduced in 1.45, MSRV is 1.36
fn processing(
domain: &str,
config: Config,
normalized: &mut String,
output: &mut String,
) -> Errors {
// Weed out the simple cases: only allow all lowercase ASCII characters and digits where none
// of the labels start with PUNYCODE_PREFIX and labels don't start or end with hyphen.
let (mut prev, mut simple, mut puny_prefix) = ('?', !domain.is_empty(), 0);
for c in domain.chars() {
map_char(c, config, &mut mapped, errors)
}
let mut normalized = String::with_capacity(mapped.len());
normalized.extend(mapped.nfc());
// Find out if it's a Bidi Domain Name
//
// First, check for literal bidi chars
let mut is_bidi_domain = domain
.chars()
.any(|c| matches!(bidi_class(c), BidiClass::R | BidiClass::AL | BidiClass::AN));
if !is_bidi_domain {
// Then check for punycode-encoded bidi chars
for label in normalized.split('.') {
if label.starts_with(PUNYCODE_PREFIX) {
match punycode::decode_to_string(&label[PUNYCODE_PREFIX.len()..]) {
Some(decoded_label) => {
if decoded_label.chars().any(|c| {
matches!(bidi_class(c), BidiClass::R | BidiClass::AL | BidiClass::AN)
}) {
is_bidi_domain = true;
}
}
None => {
is_bidi_domain = true;
}
if c == '.' {
if prev == '-' {
simple = false;
break;
}
puny_prefix = 0;
continue;
} else if puny_prefix == 0 && c == '-' {
simple = false;
break;
} else if puny_prefix < 5 {
if c == ['x', 'n', '-', '-'][puny_prefix] {
puny_prefix += 1;
if puny_prefix == 4 {
simple = false;
break;
}
} else {
puny_prefix = 5;
}
}
if !c.is_ascii_lowercase() && !c.is_ascii_digit() {
simple = false;
break;
}
prev = c;
}
let mut validated = String::new();
let mut first = true;
if simple {
output.push_str(domain);
return Errors::default();
}
normalized.clear();
let mut errors = Errors::default();
let offset = output.len();
let iter = Mapper {
chars: domain.chars(),
config,
errors: &mut errors,
slice: None,
};
normalized.extend(iter.nfc());
let mut decoder = punycode::Decoder::default();
let non_transitional = config.transitional_processing(false);
let (mut first, mut has_bidi_labels) = (true, false);
for label in normalized.split('.') {
if !first {
validated.push('.');
output.push('.');
}
first = false;
if label.starts_with(PUNYCODE_PREFIX) {
match punycode::decode_to_string(&label[PUNYCODE_PREFIX.len()..]) {
Some(decoded_label) => {
let config = config.transitional_processing(false);
validate_full(&decoded_label, is_bidi_domain, config, errors);
validated.push_str(&decoded_label)
match decoder.decode(&label[PUNYCODE_PREFIX.len()..]) {
Ok(decode) => {
let start = output.len();
output.extend(decode);
let decoded_label = &output[start..];
if !has_bidi_labels {
has_bidi_labels |= is_bidi_domain(decoded_label);
}
if !errors.is_err() {
if !is_nfc(&decoded_label) {
errors.nfc = true;
} else {
check_validity(decoded_label, non_transitional, &mut errors);
}
}
}
Err(()) => {
has_bidi_labels = true;
errors.punycode = true;
}
None => errors.push(Error::PunycodeError),
}
} else {
if !has_bidi_labels {
has_bidi_labels |= is_bidi_domain(label);
}
// `normalized` is already `NFC` so we can skip that check
validate(label, is_bidi_domain, config, errors);
validated.push_str(label)
check_validity(label, config, &mut errors);
output.push_str(label)
}
}
validated
for label in output[offset..].split('.') {
// V8: Bidi rules
//
// TODO: Add *CheckBidi* flag
if !passes_bidi(label, has_bidi_labels) {
errors.check_bidi = true;
break;
}
}
errors
}
#[derive(Default)]
pub struct Idna {
config: Config,
normalized: String,
output: String,
}
impl Idna {
pub fn new(config: Config) -> Self {
Self {
config,
normalized: String::new(),
output: String::new(),
}
}
/// http://www.unicode.org/reports/tr46/#ToASCII
#[allow(clippy::wrong_self_convention)]
pub fn to_ascii<'a>(&'a mut self, domain: &str, out: &mut String) -> Result<(), Errors> {
let mut errors = processing(domain, self.config, &mut self.normalized, &mut self.output);
let mut first = true;
for label in self.output.split('.') {
if !first {
out.push('.');
}
first = false;
if label.is_ascii() {
out.push_str(label);
} else {
let offset = out.len();
out.push_str(PUNYCODE_PREFIX);
if let Err(()) = punycode::encode_into(label.chars(), out) {
errors.punycode = true;
out.truncate(offset);
}
}
}
if self.config.verify_dns_length {
let domain = if out.ends_with('.') {
&out[..out.len() - 1]
} else {
&*out
};
if domain.is_empty() || domain.split('.').any(|label| label.is_empty()) {
errors.too_short_for_dns = true;
}
if domain.len() > 253 || domain.split('.').any(|label| label.len() > 63) {
errors.too_long_for_dns = true;
}
}
errors.into()
}
/// http://www.unicode.org/reports/tr46/#ToUnicode
#[allow(clippy::wrong_self_convention)]
pub fn to_unicode<'a>(&'a mut self, domain: &str, out: &mut String) -> Result<(), Errors> {
processing(domain, self.config, &mut self.normalized, out).into()
}
}
#[derive(Clone, Copy)]
@ -422,74 +555,168 @@ impl Config {
/// http://www.unicode.org/reports/tr46/#ToASCII
pub fn to_ascii(self, domain: &str) -> Result<String, Errors> {
let mut errors = Vec::new();
let mut result = String::new();
let mut first = true;
for label in processing(domain, self, &mut errors).split('.') {
if !first {
result.push('.');
}
first = false;
if label.is_ascii() {
result.push_str(label);
} else {
match punycode::encode_str(label) {
Some(x) => {
result.push_str(PUNYCODE_PREFIX);
result.push_str(&x);
}
None => errors.push(Error::PunycodeError),
}
}
}
if self.verify_dns_length {
let domain = if result.ends_with(".") {
&result[..result.len() - 1]
} else {
&*result
};
if domain.len() < 1 || domain.split('.').any(|label| label.len() < 1) {
errors.push(Error::TooShortForDns)
}
if domain.len() > 253 || domain.split('.').any(|label| label.len() > 63) {
errors.push(Error::TooLongForDns)
}
}
if errors.is_empty() {
Ok(result)
} else {
Err(Errors(errors))
}
let mut codec = Idna::new(self);
codec.to_ascii(domain, &mut result).map(|()| result)
}
/// http://www.unicode.org/reports/tr46/#ToUnicode
pub fn to_unicode(self, domain: &str) -> (String, Result<(), Errors>) {
let mut errors = Vec::new();
let domain = processing(domain, self, &mut errors);
let errors = if errors.is_empty() {
Ok(())
} else {
Err(Errors(errors))
};
(domain, errors)
let mut codec = Idna::new(self);
let mut out = String::with_capacity(domain.len());
let result = codec.to_unicode(domain, &mut out);
(out, result)
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
enum Error {
PunycodeError,
ValidityCriteria,
DissallowedByStd3AsciiRules,
DissallowedMappedInStd3,
DissallowedCharacter,
TooLongForDns,
TooShortForDns,
fn is_bidi_domain(s: &str) -> bool {
for c in s.chars() {
if c.is_ascii_graphic() {
continue;
}
match bidi_class(c) {
BidiClass::R | BidiClass::AL | BidiClass::AN => return true,
_ => {}
}
}
false
}
/// Errors recorded during UTS #46 processing.
///
/// This is opaque for now, only indicating the presence of at least one error.
/// This is opaque for now, indicating what types of errors have been encountered at least once.
/// More details may be exposed in the future.
#[derive(Debug)]
pub struct Errors(Vec<Error>);
#[derive(Default)]
pub struct Errors {
punycode: bool,
check_hyphens: bool,
check_bidi: bool,
start_combining_mark: bool,
invalid_mapping: bool,
nfc: bool,
disallowed_by_std3_ascii_rules: bool,
disallowed_mapped_in_std3: bool,
disallowed_character: bool,
too_long_for_dns: bool,
too_short_for_dns: bool,
}
impl Errors {
fn is_err(&self) -> bool {
let Errors {
punycode,
check_hyphens,
check_bidi,
start_combining_mark,
invalid_mapping,
nfc,
disallowed_by_std3_ascii_rules,
disallowed_mapped_in_std3,
disallowed_character,
too_long_for_dns,
too_short_for_dns,
} = *self;
punycode
|| check_hyphens
|| check_bidi
|| start_combining_mark
|| invalid_mapping
|| nfc
|| disallowed_by_std3_ascii_rules
|| disallowed_mapped_in_std3
|| disallowed_character
|| too_long_for_dns
|| too_short_for_dns
}
}
impl fmt::Debug for Errors {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Errors {
punycode,
check_hyphens,
check_bidi,
start_combining_mark,
invalid_mapping,
nfc,
disallowed_by_std3_ascii_rules,
disallowed_mapped_in_std3,
disallowed_character,
too_long_for_dns,
too_short_for_dns,
} = *self;
let fields = [
("punycode", punycode),
("check_hyphens", check_hyphens),
("check_bidi", check_bidi),
("start_combining_mark", start_combining_mark),
("invalid_mapping", invalid_mapping),
("nfc", nfc),
(
"disallowed_by_std3_ascii_rules",
disallowed_by_std3_ascii_rules,
),
("disallowed_mapped_in_std3", disallowed_mapped_in_std3),
("disallowed_character", disallowed_character),
("too_long_for_dns", too_long_for_dns),
("too_short_for_dns", too_short_for_dns),
];
let mut empty = true;
f.write_str("Errors { ")?;
for (name, val) in &fields {
if *val {
if !empty {
f.write_str(", ")?;
}
f.write_str(*name)?;
empty = false;
}
}
if !empty {
f.write_str(" }")
} else {
f.write_str("}")
}
}
}
impl From<Errors> for Result<(), Errors> {
fn from(e: Errors) -> Result<(), Errors> {
if !e.is_err() {
Ok(())
} else {
Err(e)
}
}
}
impl StdError for Errors {}
impl fmt::Display for Errors {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
#[cfg(test)]
mod tests {
use super::{find_char, Mapping};
#[test]
fn mapping_fast_path() {
assert_matches!(find_char('-'), &Mapping::Valid);
assert_matches!(find_char('.'), &Mapping::Valid);
for c in &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] {
assert_matches!(find_char(*c), &Mapping::Valid);
}
for c in &[
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
] {
assert_matches!(find_char(*c), &Mapping::Valid);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6334
third_party/rust/idna/tests/IdnaTestV2.txt vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::test::TestFn;
use idna::punycode::{decode, encode_str};
use serde_json::Value;
use serde_json::map::Map;
use serde_json::Value;
use std::str::FromStr;
use test::TestFn;
fn one_test(decoded: &str, encoded: &str) {
match decode(encoded) {

View File

@ -1,6 +1,4 @@
extern crate idna;
extern crate serde_json;
extern crate rustc_test as test;
use rustc_test as test;
mod punycode;
mod uts46;

View File

@ -1,40 +1,116 @@
extern crate idna;
extern crate unicode_normalization;
use assert_matches::assert_matches;
use unicode_normalization::char::is_combining_mark;
fn _to_ascii(domain: &str) -> Result<String, idna::Errors> {
idna::Config::default()
/// https://github.com/servo/rust-url/issues/373
#[test]
fn test_punycode_prefix_with_length_check() {
let config = idna::Config::default()
.verify_dns_length(true)
.use_std3_ascii_rules(true)
.to_ascii(domain)
.check_hyphens(true)
.use_std3_ascii_rules(true);
assert!(config.to_ascii("xn--").is_err());
assert!(config.to_ascii("xn---").is_err());
assert!(config.to_ascii("xn-----").is_err());
assert!(config.to_ascii("xn--.").is_err());
assert!(config.to_ascii("xn--...").is_err());
assert!(config.to_ascii(".xn--").is_err());
assert!(config.to_ascii("...xn--").is_err());
assert!(config.to_ascii("xn--.xn--").is_err());
assert!(config.to_ascii("xn--.example.org").is_err());
}
/// https://github.com/servo/rust-url/issues/373
#[test]
fn test_punycode_prefix_without_length_check() {
let config = idna::Config::default()
.verify_dns_length(false)
.check_hyphens(true)
.use_std3_ascii_rules(true);
assert_eq!(config.to_ascii("xn--").unwrap(), "");
assert!(config.to_ascii("xn---").is_err());
assert!(config.to_ascii("xn-----").is_err());
assert_eq!(config.to_ascii("xn--.").unwrap(), ".");
assert_eq!(config.to_ascii("xn--...").unwrap(), "...");
assert_eq!(config.to_ascii(".xn--").unwrap(), ".");
assert_eq!(config.to_ascii("...xn--").unwrap(), "...");
assert_eq!(config.to_ascii("xn--.xn--").unwrap(), ".");
assert_eq!(config.to_ascii("xn--.example.org").unwrap(), ".example.org");
}
// http://www.unicode.org/reports/tr46/#Table_Example_Processing
#[test]
fn test_examples() {
let mut codec = idna::Idna::default();
let mut out = String::new();
assert_matches!(codec.to_unicode("Bloß.de", &mut out), Ok(()));
assert_eq!(out, "bloß.de");
out.clear();
assert_matches!(codec.to_unicode("xn--blo-7ka.de", &mut out), Ok(()));
assert_eq!(out, "bloß.de");
out.clear();
assert_matches!(codec.to_unicode("u\u{308}.com", &mut out), Ok(()));
assert_eq!(out, "ü.com");
out.clear();
assert_matches!(codec.to_unicode("xn--tda.com", &mut out), Ok(()));
assert_eq!(out, "ü.com");
out.clear();
assert_matches!(codec.to_unicode("xn--u-ccb.com", &mut out), Err(_));
out.clear();
assert_matches!(codec.to_unicode("a⒈com", &mut out), Err(_));
out.clear();
assert_matches!(codec.to_unicode("xn--a-ecp.ru", &mut out), Err(_));
out.clear();
assert_matches!(codec.to_unicode("xn--0.pt", &mut out), Err(_));
out.clear();
assert_matches!(codec.to_unicode("日本語。JP", &mut out), Ok(()));
assert_eq!(out, "日本語.jp");
out.clear();
assert_matches!(codec.to_unicode("☕.us", &mut out), Ok(()));
assert_eq!(out, "☕.us");
}
#[test]
fn test_v5() {
let config = idna::Config::default()
.verify_dns_length(true)
.use_std3_ascii_rules(true);
// IdnaTest:784 蔏。𑰺
assert!(is_combining_mark('\u{11C3A}'));
assert!(_to_ascii("\u{11C3A}").is_err());
assert!(_to_ascii("\u{850f}.\u{11C3A}").is_err());
assert!(_to_ascii("\u{850f}\u{ff61}\u{11C3A}").is_err());
assert!(config.to_ascii("\u{11C3A}").is_err());
assert!(config.to_ascii("\u{850f}.\u{11C3A}").is_err());
assert!(config.to_ascii("\u{850f}\u{ff61}\u{11C3A}").is_err());
}
#[test]
fn test_v8_bidi_rules() {
assert_eq!(_to_ascii("abc").unwrap(), "abc");
assert_eq!(_to_ascii("123").unwrap(), "123");
assert_eq!(_to_ascii("אבּג").unwrap(), "xn--kdb3bdf");
assert_eq!(_to_ascii("ابج").unwrap(), "xn--mgbcm");
assert_eq!(_to_ascii("abc.ابج").unwrap(), "abc.xn--mgbcm");
assert_eq!(
_to_ascii("אבּג.ابج").unwrap(),
"xn--kdb3bdf.xn--mgbcm"
);
let config = idna::Config::default()
.verify_dns_length(true)
.use_std3_ascii_rules(true);
assert_eq!(config.to_ascii("abc").unwrap(), "abc");
assert_eq!(config.to_ascii("123").unwrap(), "123");
assert_eq!(config.to_ascii("אבּג").unwrap(), "xn--kdb3bdf");
assert_eq!(config.to_ascii("ابج").unwrap(), "xn--mgbcm");
assert_eq!(config.to_ascii("abc.ابج").unwrap(), "abc.xn--mgbcm");
assert_eq!(config.to_ascii("אבּג.ابج").unwrap(), "xn--kdb3bdf.xn--mgbcm");
// Bidi domain names cannot start with digits
assert!(_to_ascii("0a.\u{05D0}").is_err());
assert!(_to_ascii("0à.\u{05D0}").is_err());
assert!(config.to_ascii("0a.\u{05D0}").is_err());
assert!(config.to_ascii("0à.\u{05D0}").is_err());
// Bidi chars may be punycode-encoded
assert!(_to_ascii("xn--0ca24w").is_err());
assert!(config.to_ascii("xn--0ca24w").is_err());
}

View File

@ -6,116 +6,142 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::test::TestFn;
use std::char;
use test::TestFn;
use idna::Errors;
pub fn collect_tests<F: FnMut(String, TestFn)>(add_test: &mut F) {
// http://www.unicode.org/Public/idna/latest/IdnaTest.txt
for (i, line) in include_str!("IdnaTest.txt").lines().enumerate() {
if line == "" || line.starts_with("#") {
// https://www.unicode.org/Public/idna/13.0.0/IdnaTestV2.txt
for (i, line) in include_str!("IdnaTestV2.txt").lines().enumerate() {
if line.is_empty() || line.starts_with('#') {
continue;
}
// Remove comments
let mut line = match line.find("#") {
let line = match line.find('#') {
Some(index) => &line[0..index],
None => line,
};
let mut expected_failure = false;
if line.starts_with("XFAIL") {
expected_failure = true;
line = &line[5..line.len()];
};
let mut pieces = line.split(';').map(|x| x.trim()).collect::<Vec<&str>>();
let source = unescape(&pieces.remove(0));
let test_type = pieces.remove(0);
let original = pieces.remove(0);
let source = unescape(original);
let to_unicode = pieces.remove(0);
let to_ascii = pieces.remove(0);
let nv8 = if pieces.len() > 0 {
pieces.remove(0)
// ToUnicode
let mut to_unicode = unescape(&pieces.remove(0));
if to_unicode.is_empty() {
to_unicode = source.clone();
}
let to_unicode_status = status(pieces.remove(0));
// ToAsciiN
let to_ascii_n = pieces.remove(0);
let to_ascii_n = if to_ascii_n.is_empty() {
to_unicode.clone()
} else {
""
to_ascii_n.to_owned()
};
let to_ascii_n_status = pieces.remove(0);
let to_ascii_n_status = if to_ascii_n_status.is_empty() {
to_unicode_status.clone()
} else {
status(to_ascii_n_status)
};
if expected_failure {
continue;
}
// ToAsciiT
let to_ascii_t = pieces.remove(0);
let to_ascii_t = if to_ascii_t.is_empty() {
to_ascii_n.clone()
} else {
to_ascii_t.to_owned()
};
let to_ascii_t_status = pieces.remove(0);
let to_ascii_t_status = if to_ascii_t_status.is_empty() {
to_ascii_n_status.clone()
} else {
status(to_ascii_t_status)
};
let test_name = format!("UTS #46 line {}", i + 1);
add_test(
test_name,
TestFn::dyn_test_fn(move || {
let result = idna::Config::default()
let config = idna::Config::default()
.use_std3_ascii_rules(true)
.verify_dns_length(true)
.check_hyphens(true)
.transitional_processing(test_type == "T")
.to_ascii(&source);
.check_hyphens(true);
if to_ascii.starts_with("[") {
if to_ascii.starts_with("[C") {
// http://unicode.org/reports/tr46/#Deviations
// applications that perform IDNA2008 lookup are not required to check
// for these contexts
return;
}
if to_ascii == "[V2]" {
// Everybody ignores V2
// https://github.com/servo/rust-url/pull/240
// https://github.com/whatwg/url/issues/53#issuecomment-181528158
// http://www.unicode.org/review/pri317/
return;
}
let res = result.ok();
assert!(
res == None,
"Expected error. result: {} | original: {} | source: {}",
res.unwrap(),
original,
source
);
return;
}
// http://unicode.org/reports/tr46/#Deviations
// applications that perform IDNA2008 lookup are not required to check
// for these contexts, so we skip all tests annotated with C*
let to_ascii = if to_ascii.len() > 0 {
to_ascii.to_string()
} else {
if to_unicode.len() > 0 {
to_unicode.to_string()
} else {
source.clone()
}
};
// Everybody ignores V2
// https://github.com/servo/rust-url/pull/240
// https://github.com/whatwg/url/issues/53#issuecomment-181528158
// http://www.unicode.org/review/pri317/
if nv8 == "NV8" {
// This result isn't valid under IDNA2008. Skip it
return;
}
// "The special error codes X3 and X4_2 are now returned where a toASCII error code
// was formerly being generated in toUnicode due to an empty label."
// This is not implemented yet, so we skip toUnicode X4_2 tests for now, too.
assert!(
result.is_ok(),
"Couldn't parse {} | original: {} | error: {:?}",
source,
original,
result.err()
let (to_unicode_value, to_unicode_result) =
config.transitional_processing(false).to_unicode(&source);
let to_unicode_result = to_unicode_result.map(|()| to_unicode_value);
check(
&source,
(&to_unicode, &to_unicode_status),
to_unicode_result,
|e| e.starts_with('C') || e == "V2" || e == "X4_2",
);
let output = result.ok().unwrap();
assert!(
output == to_ascii,
"result: {} | expected: {} | original: {} | source: {}",
output,
to_ascii,
original,
source
let to_ascii_n_result = config.transitional_processing(false).to_ascii(&source);
check(
&source,
(&to_ascii_n, &to_ascii_n_status),
to_ascii_n_result,
|e| e.starts_with('C') || e == "V2",
);
let to_ascii_t_result = config.transitional_processing(true).to_ascii(&source);
check(
&source,
(&to_ascii_t, &to_ascii_t_status),
to_ascii_t_result,
|e| e.starts_with('C') || e == "V2",
);
}),
)
}
}
#[allow(clippy::redundant_clone)]
fn check<F>(source: &str, expected: (&str, &[&str]), actual: Result<String, Errors>, ignore: F)
where
F: Fn(&str) -> bool,
{
if !expected.1.is_empty() {
if !expected.1.iter().copied().any(ignore) {
let res = actual.ok();
assert_eq!(
res.clone(),
None,
"Expected error {:?}. result: {} | source: {}",
expected.1,
res.unwrap(),
source,
);
}
} else {
assert!(
actual.is_ok(),
"Couldn't parse {} | error: {:?}",
source,
actual.err().unwrap(),
);
assert_eq!(actual.unwrap(), expected.0, "source: {}", source);
}
}
fn unescape(input: &str) -> String {
let mut output = String::new();
let mut chars = input.chars();
@ -148,3 +174,20 @@ fn unescape(input: &str) -> String {
}
}
}
fn status(status: &str) -> Vec<&str> {
if status.is_empty() || status == "[]" {
return Vec::new();
}
let mut result = status.split(", ").collect::<Vec<_>>();
assert!(result[0].starts_with('['));
result[0] = &result[0][1..];
let idx = result.len() - 1;
let last = &mut result[idx];
assert!(last.ends_with(']'));
*last = &last[..last.len() - 1];
result
}

File diff suppressed because one or more lines are too long

View File

@ -11,7 +11,7 @@
[package]
name = "libc"
version = "0.2.109"
version = "0.2.112"
authors = ["The Rust Project Developers"]
build = "build.rs"
exclude = ["/ci/*", "/.github/*", "/.cirrus.yml", "/triagebot.toml"]

View File

@ -106,11 +106,6 @@ s! {
pub f_uid_uuid: ::uuid_t,
}
#[deprecated(
since = "0.2.107",
note = "stat.st_blksize is an i64 and stat.st_qspare1 is replaced with \
stat.st_blksize in DragonFly 5.8"
)]
pub struct stat {
pub st_ino: ::ino_t,
pub st_nlink: ::nlink_t,
@ -128,11 +123,11 @@ s! {
pub st_ctime_nsec: ::c_long,
pub st_size: ::off_t,
pub st_blocks: i64,
pub st_blksize: u32,
pub __old_st_blksize: u32,
pub st_flags: u32,
pub st_gen: u32,
pub st_lspare: i32,
pub st_qspare1: i64,
pub st_blksize: i64,
pub st_qspare2: i64,
}
@ -772,9 +767,6 @@ pub const RLIMIT_POSIXLOCKS: ::c_int = 11;
#[deprecated(since = "0.2.64", note = "Not stable across OS versions")]
pub const RLIM_NLIMITS: ::rlim_t = 12;
#[deprecated(since = "0.2.105", note = "Only exists on FreeBSD, not DragonFly BSD")]
pub const XU_NGROUPS: ::c_int = 16;
pub const Q_GETQUOTA: ::c_int = 0x300;
pub const Q_SETQUOTA: ::c_int = 0x400;
@ -944,11 +936,6 @@ pub const EV_EOF: u16 = 0x8000;
pub const EV_SYSFLAGS: u16 = 0xf000;
pub const FIODNAME: ::c_ulong = 0x80106678;
#[deprecated(
since = "0.2.106",
note = "FIODGNAME is not defined on DragonFly BSD. See FIODNAME."
)]
pub const FIODGNAME: ::c_ulong = 0x80106678;
pub const NOTE_TRIGGER: u32 = 0x01000000;
pub const NOTE_FFNOP: u32 = 0x00000000;
@ -1433,12 +1420,11 @@ extern "C" {
pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, timeout: *mut ::timespec) -> ::c_int;
#[deprecated(since = "0.2.107", note = "len should be of type size_t")]
pub fn devname_r(
dev: ::dev_t,
mode: ::mode_t,
buf: *mut ::c_char,
len: ::c_int,
len: ::size_t,
) -> *mut ::c_char;
pub fn waitid(

View File

@ -459,7 +459,8 @@ extern "C" {
cfg_if! {
if #[cfg(any(target_arch = "x86_64",
target_arch = "aarch64"))] {
target_arch = "aarch64",
target_arch = "riscv64"))] {
mod b64;
pub use self::b64::*;
}

View File

@ -478,7 +478,8 @@ extern "C" {
cfg_if! {
if #[cfg(any(target_arch = "x86_64",
target_arch = "aarch64"))] {
target_arch = "aarch64",
target_arch = "riscv64"))] {
mod b64;
pub use self::b64::*;
}

View File

@ -30,17 +30,6 @@ s! {
pub ext: [u64; 4],
}
pub struct sockcred2 {
pub sc_version: ::c_int,
pub sc_pid: ::pid_t,
pub sc_uid: ::uid_t,
pub sc_euid: ::uid_t,
pub sc_gid: ::gid_t,
pub sc_egid: ::gid_t,
pub sc_ngroups: ::c_int,
pub sc_groups: [::gid_t; 1],
}
pub struct kvm_page {
pub kp_version: ::u_int,
pub kp_paddr: ::kpaddr_t,
@ -479,17 +468,6 @@ pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4;
pub const MINCORE_SUPER: ::c_int = 0x20;
f! {
pub fn SOCKCRED2SIZE(ngrps: usize) -> usize {
let ngrps = if ngrps > 0 {
ngrps - 1
} else {
0
};
::mem::size_of::<sockcred2>() + ::mem::size_of::<::gid_t>() * ngrps
}
}
extern "C" {
pub fn aio_readv(aiocbp: *mut ::aiocb) -> ::c_int;
pub fn aio_writev(aiocbp: *mut ::aiocb) -> ::c_int;
@ -555,7 +533,8 @@ extern "C" {
cfg_if! {
if #[cfg(any(target_arch = "x86_64",
target_arch = "aarch64"))] {
target_arch = "aarch64",
target_arch = "riscv64"))] {
mod b64;
pub use self::b64::*;
}

View File

@ -30,17 +30,6 @@ s! {
pub ext: [u64; 4],
}
pub struct sockcred2 {
pub sc_version: ::c_int,
pub sc_pid: ::pid_t,
pub sc_uid: ::uid_t,
pub sc_euid: ::uid_t,
pub sc_gid: ::gid_t,
pub sc_egid: ::gid_t,
pub sc_ngroups: ::c_int,
pub sc_groups: [::gid_t; 1],
}
pub struct kvm_page {
pub kp_version: ::u_int,
pub kp_paddr: ::kpaddr_t,
@ -479,17 +468,6 @@ pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4;
pub const MINCORE_SUPER: ::c_int = 0x60;
f! {
pub fn SOCKCRED2SIZE(ngrps: usize) -> usize {
let ngrps = if ngrps > 0 {
ngrps - 1
} else {
0
};
::mem::size_of::<sockcred2>() + ::mem::size_of::<::gid_t>() * ngrps
}
}
extern "C" {
pub fn aio_readv(aiocbp: *mut ::aiocb) -> ::c_int;
pub fn aio_writev(aiocbp: *mut ::aiocb) -> ::c_int;
@ -555,7 +533,8 @@ extern "C" {
cfg_if! {
if #[cfg(any(target_arch = "x86_64",
target_arch = "aarch64"))] {
target_arch = "aarch64",
target_arch = "riscv64"))] {
mod b64;
pub use self::b64::*;
}

View File

@ -459,33 +459,37 @@ s! {
pub kve_path: [[::c_char; 32]; 32],
}
pub struct __c_anonymous_filestat {
pub stqe_next: *mut filestat,
}
pub struct filestat {
fs_type: ::c_int,
fs_flags: ::c_int,
fs_fflags: ::c_int,
fs_uflags: ::c_int,
fs_fd: ::c_int,
fs_ref_count: ::c_int,
fs_offset: ::off_t,
fs_typedep: *mut ::c_void,
fs_path: *mut ::c_char,
next: *mut filestat,
fs_cap_rights: cap_rights_t,
pub fs_type: ::c_int,
pub fs_flags: ::c_int,
pub fs_fflags: ::c_int,
pub fs_uflags: ::c_int,
pub fs_fd: ::c_int,
pub fs_ref_count: ::c_int,
pub fs_offset: ::off_t,
pub fs_typedep: *mut ::c_void,
pub fs_path: *mut ::c_char,
pub next: __c_anonymous_filestat,
pub fs_cap_rights: cap_rights_t,
}
pub struct filestat_list {
stqh_first: *mut filestat,
stqh_last: *mut *mut filestat,
pub stqh_first: *mut filestat,
pub stqh_last: *mut *mut filestat,
}
pub struct procstat {
tpe: ::c_int,
kd: ::uintptr_t,
vmentries: *mut ::c_void,
files: *mut ::c_void,
argv: *mut ::c_void,
envv: *mut ::c_void,
core: ::uintptr_t,
pub tpe: ::c_int,
pub kd: ::uintptr_t,
pub vmentries: *mut ::c_void,
pub files: *mut ::c_void,
pub argv: *mut ::c_void,
pub envv: *mut ::c_void,
pub core: ::uintptr_t,
}
pub struct itimerspec {
@ -945,6 +949,17 @@ s! {
pub generation: ::c_long,
pub numdevs: ::c_int,
}
pub struct sockcred2 {
pub sc_version: ::c_int,
pub sc_pid: ::pid_t,
pub sc_uid: ::uid_t,
pub sc_euid: ::uid_t,
pub sc_gid: ::gid_t,
pub sc_egid: ::gid_t,
pub sc_ngroups: ::c_int,
pub sc_groups: [::gid_t; 1],
}
}
s_no_extra_traits! {
@ -3701,6 +3716,15 @@ f! {
let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits);
0 != cpuset.__bits[idx] & (1 << offset)
}
pub fn SOCKCRED2SIZE(ngrps: usize) -> usize {
let ngrps = if ngrps > 0 {
ngrps - 1
} else {
0
};
::mem::size_of::<sockcred2>() + ::mem::size_of::<::gid_t>() * ngrps
}
}
safe_f! {
@ -3840,8 +3864,6 @@ extern "C" {
sevp: *mut sigevent,
) -> ::c_int;
pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int;
pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int;
pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int;
@ -3976,6 +3998,16 @@ extern "C" {
cpusetp: *const cpuset_t,
) -> ::c_int;
// sched.h linux compatibility api
pub fn sched_getaffinity(pid: ::pid_t, cpusetsz: ::size_t, cpuset: *mut ::cpuset_t) -> ::c_int;
// FIXME: the first argument's type might not be correct, fix later if that changes.
pub fn sched_setaffinity(
pid: ::c_int,
cpusetsz: ::size_t,
cpuset: *const ::cpuset_t,
) -> ::c_int;
pub fn sched_getcpu() -> ::c_int;
pub fn pthread_mutex_consistent(mutex: *mut ::pthread_mutex_t) -> ::c_int;
pub fn pthread_mutexattr_getrobust(
@ -4027,6 +4059,10 @@ extern "C" {
pub fn getfh(path: *const ::c_char, fhp: *mut fhandle_t) -> ::c_int;
pub fn lgetfh(path: *const ::c_char, fhp: *mut fhandle_t) -> ::c_int;
pub fn getfsstat(buf: *mut ::statfs, bufsize: ::c_long, mode: ::c_int) -> ::c_int;
#[cfg_attr(
all(target_os = "freebsd", freebsd11),
link_name = "getmntinfo@FBSD_1.0"
)]
pub fn getmntinfo(mntbufp: *mut *mut ::statfs, mode: ::c_int) -> ::c_int;
pub fn mount(
type_: *const ::c_char,
@ -4392,6 +4428,9 @@ cfg_if! {
} else if #[cfg(target_arch = "powerpc")] {
mod powerpc;
pub use self::powerpc::*;
} else if #[cfg(target_arch = "riscv64")] {
mod riscv64;
pub use self::riscv64::*;
} else {
// Unknown target_arch
}

View File

@ -0,0 +1,154 @@
pub type c_char = u8;
pub type c_long = i64;
pub type c_ulong = u64;
pub type wchar_t = ::c_int;
pub type time_t = i64;
pub type suseconds_t = ::c_long;
pub type register_t = i64;
// should be pub(crate), but that requires Rust 1.18.0
cfg_if! {
if #[cfg(libc_const_size_of)] {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1;
} else {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = 8 - 1;
}
}
s_no_extra_traits! {
pub struct gpregs {
pub gp_ra: ::register_t,
pub gp_sp: ::register_t,
pub gp_gp: ::register_t,
pub gp_tp: ::register_t,
pub gp_t: [::register_t; 7],
pub gp_s: [::register_t; 12],
pub gp_a: [::register_t; 8],
pub gp_sepc: ::register_t,
pub gp_sstatus: ::register_t,
}
pub struct fpregs {
pub fp_x: [[::register_t; 2]; 32],
pub fp_fcsr: ::register_t,
pub fp_flags: ::c_int,
pub fp_pad: ::c_int,
}
pub struct mcontext_t {
pub mc_gpregs: gpregs,
pub mc_fpregs: fpregs,
pub mc_flags: ::c_int,
pub mc_pad: ::c_int,
pub mc_spare: [u64; 8],
}
}
cfg_if! {
if #[cfg(feature = "extra_traits")] {
impl PartialEq for gpregs {
fn eq(&self, other: &gpregs) -> bool {
self.gp_ra == other.gp_ra &&
self.gp_sp == other.gp_sp &&
self.gp_gp == other.gp_gp &&
self.gp_tp == other.gp_tp &&
self.gp_t.iter().zip(other.gp_t.iter()).all(|(a, b)| a == b) &&
self.gp_s.iter().zip(other.gp_s.iter()).all(|(a, b)| a == b) &&
self.gp_a.iter().zip(other.gp_a.iter()).all(|(a, b)| a == b) &&
self.gp_sepc == other.gp_sepc &&
self.gp_sstatus == other.gp_sstatus
}
}
impl Eq for gpregs {}
impl ::fmt::Debug for gpregs {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("gpregs")
.field("gp_ra", &self.gp_ra)
.field("gp_sp", &self.gp_sp)
.field("gp_gp", &self.gp_gp)
.field("gp_tp", &self.gp_tp)
.field("gp_t", &self.gp_t)
.field("gp_s", &self.gp_s)
.field("gp_a", &self.gp_a)
.field("gp_sepc", &self.gp_sepc)
.field("gp_sstatus", &self.gp_sstatus)
.finish()
}
}
impl ::hash::Hash for gpregs {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.gp_ra.hash(state);
self.gp_sp.hash(state);
self.gp_gp.hash(state);
self.gp_tp.hash(state);
self.gp_t.hash(state);
self.gp_s.hash(state);
self.gp_a.hash(state);
self.gp_sepc.hash(state);
self.gp_sstatus.hash(state);
}
}
impl PartialEq for fpregs {
fn eq(&self, other: &fpregs) -> bool {
self.fp_x == other.fp_x &&
self.fp_fcsr == other.fp_fcsr &&
self.fp_flags == other.fp_flags &&
self.fp_pad == other.fp_pad
}
}
impl Eq for fpregs {}
impl ::fmt::Debug for fpregs {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("fpregs")
.field("fp_x", &self.fp_x)
.field("fp_fcsr", &self.fp_fcsr)
.field("fp_flags", &self.fp_flags)
.field("fp_pad", &self.fp_pad)
.finish()
}
}
impl ::hash::Hash for fpregs {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.fp_x.hash(state);
self.fp_fcsr.hash(state);
self.fp_flags.hash(state);
self.fp_pad.hash(state);
}
}
impl PartialEq for mcontext_t {
fn eq(&self, other: &mcontext_t) -> bool {
self.mc_gpregs == other.mc_gpregs &&
self.mc_fpregs == other.mc_fpregs &&
self.mc_flags == other.mc_flags &&
self.mc_pad == other.mc_pad &&
self.mc_spare.iter().zip(other.mc_spare.iter()).all(|(a, b)| a == b)
}
}
impl Eq for mcontext_t {}
impl ::fmt::Debug for mcontext_t {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("mcontext_t")
.field("mc_gpregs", &self.mc_gpregs)
.field("mc_fpregs", &self.mc_fpregs)
.field("mc_flags", &self.mc_flags)
.field("mc_pad", &self.mc_pad)
.field("mc_spare", &self.mc_spare)
.finish()
}
}
impl ::hash::Hash for mcontext_t {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.mc_gpregs.hash(state);
self.mc_fpregs.hash(state);
self.mc_flags.hash(state);
self.mc_pad.hash(state);
self.mc_spare.hash(state);
}
}
}
}
pub const MAP_32BIT: ::c_int = 0x00080000;
pub const MINSIGSTKSZ: ::size_t = 4096; // 1024 * 4

View File

@ -1512,6 +1512,8 @@ extern "C" {
pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t;
pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char;
pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int;
pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int;
pub fn ppoll(
fds: *mut ::pollfd,
nfds: ::nfds_t,

View File

@ -552,11 +552,23 @@ s! {
pub pl_event: ::c_int,
}
pub struct ptrace_lwpstatus {
pub pl_lwpid: lwpid_t,
pub pl_sigpend: sigset_t,
pub pl_sigmask: sigset_t,
pub pl_name: [::c_char; 20],
pub pl_private: *mut ::c_void,
}
pub struct ptrace_siginfo {
pub psi_siginfo: siginfo_t,
pub psi_lwpid: lwpid_t,
}
pub struct ptrace_event {
pub pe_set_event: ::c_int,
}
pub struct sysctldesc {
pub descr_num: i32,
pub descr_ver: u32,
@ -2000,6 +2012,15 @@ pub const PT_SYSCALLEMU: ::c_int = 15;
pub const PT_SET_EVENT_MASK: ::c_int = 16;
pub const PT_GET_EVENT_MASK: ::c_int = 17;
pub const PT_GET_PROCESS_STATE: ::c_int = 18;
pub const PT_SET_SIGINFO: ::c_int = 19;
pub const PT_GET_SIGINFO: ::c_int = 20;
pub const PT_RESUME: ::c_int = 21;
pub const PT_SUSPEND: ::c_int = 23;
pub const PT_STOP: ::c_int = 23;
pub const PT_LWPSTATUS: ::c_int = 24;
pub const PT_LWPNEXT: ::c_int = 25;
pub const PT_SET_SIGPASS: ::c_int = 26;
pub const PT_GET_SIGPASS: ::c_int = 27;
pub const PT_FIRSTMACH: ::c_int = 32;
pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01;

View File

@ -0,0 +1,16 @@
pub type c_long = i32;
pub type c_ulong = u32;
pub type c_char = u8;
// should be pub(crate), but that requires Rust 1.18.0
cfg_if! {
if #[cfg(libc_const_size_of)] {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1;
} else {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = 8 - 1;
}
}
pub const _MAX_PAGE_SHIFT: u32 = 12;

View File

@ -0,0 +1,8 @@
pub type c_long = i64;
pub type c_ulong = u64;
pub type c_char = i8;
#[doc(hidden)]
pub const _ALIGNBYTES: usize = 7;
pub const _MAX_PAGE_SHIFT: u32 = 14;

View File

@ -1648,18 +1648,33 @@ cfg_if! {
}
cfg_if! {
if #[cfg(target_arch = "x86")] {
if #[cfg(target_arch = "aarch64")] {
mod aarch64;
pub use self::aarch64::*;
} else if #[cfg(target_arch = "arm")] {
mod arm;
pub use self::arm::*;
} else if #[cfg(target_arch = "mips64")] {
mod mips64;
pub use self::mips64::*;
} else if #[cfg(target_arch = "powerpc")] {
mod powerpc;
pub use self::powerpc::*;
} else if #[cfg(target_arch = "powerpc64")] {
mod powerpc64;
pub use self::powerpc64::*;
} else if #[cfg(target_arch = "riscv64")] {
mod riscv64;
pub use self::riscv64::*;
} else if #[cfg(target_arch = "sparc64")] {
mod sparc64;
pub use self::sparc64::*;
} else if #[cfg(target_arch = "x86")] {
mod x86;
pub use self::x86::*;
} else if #[cfg(target_arch = "x86_64")] {
mod x86_64;
pub use self::x86_64::*;
} else if #[cfg(target_arch = "aarch64")] {
mod aarch64;
pub use self::aarch64::*;
} else if #[cfg(target_arch = "sparc64")] {
mod sparc64;
pub use self::sparc64::*;
} else {
// Unknown target_arch
}

View File

@ -0,0 +1,16 @@
pub type c_long = i32;
pub type c_ulong = u32;
pub type c_char = u8;
// should be pub(crate), but that requires Rust 1.18.0
cfg_if! {
if #[cfg(libc_const_size_of)] {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1;
} else {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = 8 - 1;
}
}
pub const _MAX_PAGE_SHIFT: u32 = 12;

View File

@ -0,0 +1,16 @@
pub type c_long = i64;
pub type c_ulong = u64;
pub type c_char = u8;
// should be pub(crate), but that requires Rust 1.18.0
cfg_if! {
if #[cfg(libc_const_size_of)] {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
} else {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = 8 - 1;
}
}
pub const _MAX_PAGE_SHIFT: u32 = 12;

View File

@ -0,0 +1,16 @@
pub type c_long = i64;
pub type c_ulong = u64;
pub type c_char = u8;
// should be pub(crate), but that requires Rust 1.18.0
cfg_if! {
if #[cfg(libc_const_size_of)] {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
} else {
#[doc(hidden)]
pub const _ALIGNBYTES: usize = 8 - 1;
}
}
pub const _MAX_PAGE_SHIFT: u32 = 12;

View File

@ -2328,6 +2328,9 @@ pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5;
pub const ALG_OP_DECRYPT: ::c_int = 0;
pub const ALG_OP_ENCRYPT: ::c_int = 1;
// sys/mman.h
pub const MLOCK_ONFAULT: ::c_int = 0x01;
// uapi/linux/vm_sockets.h
pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF;
pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0;
@ -2582,6 +2585,7 @@ extern "C" {
pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int;
pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int;
pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int;
pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int;
pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int;
pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int;

View File

@ -135,3 +135,6 @@ pub const TIOCM_DSR: ::c_int = 0x100;
pub const BOTHER: ::speed_t = 0o010000;
pub const IBSHIFT: ::tcflag_t = 16;
pub const BLKSSZGET: ::c_int = 0x1268;
pub const BLKPBSZGET: ::c_int = 0x127B;

View File

@ -131,3 +131,6 @@ pub const TIOCM_DSR: ::c_int = 0x400;
pub const BOTHER: ::speed_t = 0o010000;
pub const IBSHIFT: ::tcflag_t = 16;
pub const BLKSSZGET: ::c_int = 0x20001268;
pub const BLKPBSZGET: ::c_int = 0x2000127B;

View File

@ -109,3 +109,6 @@ pub const TIOCM_DSR: ::c_int = 0x100;
pub const BOTHER: ::speed_t = 0o0037;
pub const IBSHIFT: ::tcflag_t = 16;
pub const BLKSSZGET: ::c_int = 0x20001268;
pub const BLKPBSZGET: ::c_int = 0x2000127B;

View File

@ -123,3 +123,6 @@ pub const TIOCM_DSR: ::c_int = 0x100;
pub const BOTHER: ::speed_t = 0x1000;
pub const IBSHIFT: ::tcflag_t = 16;
pub const BLKSSZGET: ::c_int = 0x20001268;
pub const BLKPBSZGET: ::c_int = 0x2000127B;

View File

@ -597,6 +597,7 @@ pub const RTLD_DI_TLS_MODID: ::c_int = 9;
pub const RTLD_DI_TLS_DATA: ::c_int = 10;
pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK;
pub const PIDFD_NONBLOCK: ::c_uint = O_NONBLOCK as ::c_uint;
pub const SOL_RXRPC: ::c_int = 272;
pub const SOL_PPPOL2TP: ::c_int = 273;

View File

@ -2583,6 +2583,7 @@ pub const MAP_SHARED_VALIDATE: ::c_int = 0x3;
// include/uapi/asm-generic/mman-common.h
pub const MAP_FIXED_NOREPLACE: ::c_int = 0x100000;
pub const MLOCK_ONFAULT: ::c_uint = 0x01;
// uapi/linux/vm_sockets.h
pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF;
@ -3533,6 +3534,7 @@ extern "C" {
pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long);
pub fn telldir(dirp: *mut ::DIR) -> ::c_long;
pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int;
pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int;
pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int;

View File

@ -699,7 +699,6 @@ extern "C" {
all(target_os = "freebsd", any(freebsd11, freebsd10)),
link_name = "fstat@FBSD_1.0"
)]
#[cfg_attr(target_os = "dragonfly", allow(deprecated))]
pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int;
pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int;
@ -713,7 +712,6 @@ extern "C" {
all(target_os = "freebsd", any(freebsd11, freebsd10)),
link_name = "stat@FBSD_1.0"
)]
#[cfg_attr(target_os = "dragonfly", allow(deprecated))]
pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int;
pub fn pclose(stream: *mut ::FILE) -> ::c_int;
@ -798,7 +796,6 @@ extern "C" {
all(target_os = "freebsd", any(freebsd11, freebsd10)),
link_name = "fstatat@FBSD_1.1"
)]
#[cfg_attr(target_os = "dragonfly", allow(deprecated))]
pub fn fstatat(
dirfd: ::c_int,
pathname: *const ::c_char,
@ -990,7 +987,6 @@ extern "C" {
all(target_os = "freebsd", any(freebsd11, freebsd10)),
link_name = "lstat@FBSD_1.0"
)]
#[cfg_attr(target_os = "dragonfly", allow(deprecated))]
pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int;
#[cfg_attr(