mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Auto merge of #50769 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 11 pull requests Successful merges: - #49767 (Rewrite docs for `std::ptr`) - #50399 (save-analysis: handle aliasing imports a bit more nicely) - #50594 (Update the man page with additional --print options) - #50613 (Migrate the toolstate update bot to rust-highfive) - #50632 (Add minification process) - #50685 (ci: Add Dockerfile for dist-sparc64-linux) - #50691 (rustdoc: Add support for pub(restricted)) - #50712 (Improve eager type resolution error message) - #50720 (Add “Examples” section header in f32/f64 doc comments.) - #50733 (Hyperlink DOI against preferred resolver) - #50745 (Uncapitalize "You") Failed merges:
This commit is contained in:
commit
27acb9b3c0
@ -197,7 +197,7 @@ env:
|
||||
# AWS_SECRET_ACCESS_KEY=...
|
||||
- secure: "j96XxTVOSUf4s4r4htIxn/fvIa5DWbMgLqWl7r8z2QfgUwscmkMXAwXuFNc7s7bGTpV/+CgDiMFFM6BAFLGKutytIF6oA02s9b+usQYnM0th7YQ2AIgm9GtMTJCJp4AoyfFmh8F2faUICBZlfVLUJ34udHEe35vOklix+0k4WDo="
|
||||
# TOOLSTATE_REPO_ACCESS_TOKEN=...
|
||||
- secure: "cFh8thThqEJLC98XKI5pfqflUzOlxsYPRW20AWRaYOOgYHPTiGWypTXiPbGSKaeAXTZoOA+DpQtEmefc0U6lt9dHc7a/MIaK6isFurjlnKYiLOeTruzyu1z7PWCeZ/jKXsU2RK/88DBtlNwfMdaMIeuKj14IVfpepPPL71ETbuk="
|
||||
- secure: "ESfcXqv4N2VMhqi2iIyw6da9VrsA78I4iR1asouCaq4hzTTrkB4WNRrfURy6xg72gQ4nMhtRJbB0/2jmc9Cu1+g2CzXtyiL223aJ5CKrXdcvbitopQSDfp07dMWm+UED+hNFEanpErKAeU/6FM3A+J+60PMk8MCF1h9tqNRISJw="
|
||||
|
||||
before_install:
|
||||
# We'll use the AWS cli to download/upload cached docker layers, so install
|
||||
|
@ -6,7 +6,7 @@ environment:
|
||||
secure: 7Y+JiquYedOAgnUU26uL0DPzrxmTtR+qIwG6rNKSuWDffqU3vVZxbGXim9QpTO80
|
||||
SCCACHE_DIGEST: f808afabb4a4eb1d7112bcb3fa6be03b61e93412890c88e177c667eb37f46353d7ec294e559b16f9f4b5e894f2185fe7670a0df15fd064889ecbd80f0c34166c
|
||||
TOOLSTATE_REPO_ACCESS_TOKEN:
|
||||
secure: PTZiSxJMVUZ0VnMR5i13E4OagbXfglj7pcskDQiKufVrDm13mLoI0vDJAEM35+bY
|
||||
secure: gKGlVktr7iuqCoYSxHxDE9ltLOKU0nYDEuQxvWbNxUIW7ri5ppn8L06jQzN0GGzN
|
||||
|
||||
# By default schannel checks revocation of certificates unlike some other SSL
|
||||
# backends, but we've historically had problems on CI where a revocation
|
||||
|
64
src/Cargo.lock
generated
64
src/Cargo.lock
generated
@ -79,15 +79,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "assert_cli"
|
||||
version = "0.5.6"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"skeptic 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -183,6 +183,11 @@ dependencies = [
|
||||
name = "build_helper"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.2.2"
|
||||
@ -570,6 +575,11 @@ name = "diff"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "difference"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "difference"
|
||||
version = "2.0.0"
|
||||
@ -1188,6 +1198,14 @@ name = "memoffset"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "minifier"
|
||||
version = "0.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz-sys"
|
||||
version = "0.1.10"
|
||||
@ -1550,7 +1568,7 @@ dependencies = [
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1689,6 +1707,15 @@ dependencies = [
|
||||
"serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls-data"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls-rustc"
|
||||
version = "0.2.2"
|
||||
@ -2140,7 +2167,7 @@ name = "rustc_save_analysis"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rls-data 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc 0.0.0",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2260,6 +2287,7 @@ dependencies = [
|
||||
name = "rustdoc"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"minifier 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2290,7 +2318,7 @@ dependencies = [
|
||||
name = "rustfmt-nightly"
|
||||
version = "0.6.1"
|
||||
dependencies = [
|
||||
"assert_cli 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2417,6 +2445,21 @@ name = "siphasher"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "skeptic"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.0"
|
||||
@ -2988,7 +3031,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31"
|
||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||
"checksum assert_cli 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8ca6beaa44a3520407b28a4a779a19b1364fcadcb2f258c41a7baf3102ced0"
|
||||
"checksum assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72342c21057a3cb5f7c2d849bf7999a83795434dd36d74fa8c24680581bd1930"
|
||||
"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
|
||||
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||
@ -2996,6 +3039,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
|
||||
"checksum bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "882585cd7ec84e902472df34a5e01891202db3bf62614e1f0afe459c1afcf744"
|
||||
"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
|
||||
"checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3"
|
||||
"checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba"
|
||||
@ -3020,6 +3064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3"
|
||||
"checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a"
|
||||
"checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
|
||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
||||
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
|
||||
@ -3083,6 +3128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f"
|
||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum minifier 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "26f3e36a4db1981b16567e4abfd6ddc3641bc9b950bdc868701f656bf9b74bdd"
|
||||
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
|
||||
"checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
|
||||
"checksum nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c8d77f3db4bce033f4d04db08079b2ef1c3d02b44e86f25d08886fafa7756ffa"
|
||||
@ -3132,6 +3178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum rls-analysis 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a41488cf5dc99d6ce383319d2978756567b70d4ed0539eb0d9ce07763e732e46"
|
||||
"checksum rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a9cc2545ccb7e05b355bfe047b8039a6ec12270d5f3c996b766b340a50f7d2"
|
||||
"checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510"
|
||||
"checksum rls-data 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd20763e1c60ae8945384c8a8fa4ac44f8afa7b0a817511f5e8927e5d24f988"
|
||||
"checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea"
|
||||
"checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
|
||||
"checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb"
|
||||
@ -3162,6 +3209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9"
|
||||
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
|
||||
"checksum skeptic 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4474d6da9593171bcb086890fc344a3a12783cb24e5b141f8a5d0e43561f4b6"
|
||||
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
|
||||
"checksum socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ff606e0486e88f5fc6cfeb3966e434fb409abbc7a3ab495238f70a1ca97f789d"
|
||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||
|
26
src/ci/docker/disabled/dist-sparc64-linux/Dockerfile
Normal file
26
src/ci/docker/disabled/dist-sparc64-linux/Dockerfile
Normal file
@ -0,0 +1,26 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
make \
|
||||
file \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python2.7 \
|
||||
git \
|
||||
cmake \
|
||||
sudo \
|
||||
gdb \
|
||||
xz-utils \
|
||||
g++-sparc64-linux-gnu \
|
||||
libssl-dev \
|
||||
pkg-config
|
||||
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
ENV HOSTS=sparc64-unknown-linux-gnu
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
|
||||
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
|
@ -60,7 +60,7 @@ commit_toolstate_change() {
|
||||
OLDFLAGS="$-"
|
||||
set -eu
|
||||
|
||||
git config --global user.email '34210020+rust-toolstate-update@users.noreply.github.com'
|
||||
git config --global user.email '7378925+rust-toolstate-update@users.noreply.github.com'
|
||||
git config --global user.name 'Rust Toolstate Update'
|
||||
git config --global credential.helper store
|
||||
printf 'https://%s:x-oauth-basic@github.com\n' "$TOOLSTATE_REPO_ACCESS_TOKEN" \
|
||||
|
@ -55,7 +55,7 @@ Configure the output that \fBrustc\fR will produce. Each emission may also have
|
||||
an optional explicit output \fIPATH\fR specified for that particular emission
|
||||
kind. This path takes precedence over the \fB-o\fR option.
|
||||
.TP
|
||||
\fB\-\-print\fR [crate\-name|file\-names|sysroot]
|
||||
\fB\-\-print\fR [crate\-name|\:file\-names|\:sysroot|\:cfg|\:target\-list|\:target\-cpus|\:target\-features|\:relocation\-models|\:code\-models|\:tls\-models|\:target\-spec\-json|\:native\-static\-libs]
|
||||
Comma separated list of compiler information to print on stdout.
|
||||
.TP
|
||||
\fB\-g\fR
|
||||
|
@ -962,59 +962,122 @@ extern "rust-intrinsic" {
|
||||
/// value is not necessarily valid to be used to actually access memory.
|
||||
pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
|
||||
|
||||
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
|
||||
/// and destination may *not* overlap.
|
||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||
/// and destination must *not* overlap.
|
||||
///
|
||||
/// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
|
||||
/// For regions of memory which might overlap, use [`copy`] instead.
|
||||
///
|
||||
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`].
|
||||
///
|
||||
/// [`copy`]: ./fn.copy.html
|
||||
/// [`memcpy`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memcpy
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Beyond requiring that the program must be allowed to access both regions
|
||||
/// of memory, it is Undefined Behavior for source and destination to
|
||||
/// overlap. Care must also be taken with the ownership of `src` and
|
||||
/// `dst`. This method semantically moves the values of `src` into `dst`.
|
||||
/// However it does not drop the contents of `dst`, or prevent the contents
|
||||
/// of `src` from being dropped or used.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * The region of memory which begins at `src` and has a length of
|
||||
/// `count * size_of::<T>()` bytes must be *both* valid and initialized.
|
||||
///
|
||||
/// * The region of memory which begins at `dst` and has a length of
|
||||
/// `count * size_of::<T>()` bytes must be valid (but may or may not be
|
||||
/// initialized).
|
||||
///
|
||||
/// * The two regions of memory must *not* overlap.
|
||||
///
|
||||
/// * `src` must be properly aligned.
|
||||
///
|
||||
/// * `dst` must be properly aligned.
|
||||
///
|
||||
/// Additionally, if `T` is not [`Copy`], only the region at `src` *or* the
|
||||
/// region at `dst` can be used or dropped after calling
|
||||
/// `copy_nonoverlapping`. `copy_nonoverlapping` creates bitwise copies of
|
||||
/// `T`, regardless of whether `T: Copy`, which can result in undefined
|
||||
/// behavior if both copies are used.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A safe swap function:
|
||||
/// Manually implement [`Vec::append`]:
|
||||
///
|
||||
/// ```
|
||||
/// use std::mem;
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// # #[allow(dead_code)]
|
||||
/// fn swap<T>(x: &mut T, y: &mut T) {
|
||||
/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
|
||||
/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
|
||||
/// let src_len = src.len();
|
||||
/// let dst_len = dst.len();
|
||||
///
|
||||
/// // Ensure that `dst` has enough capacity to hold all of `src`.
|
||||
/// dst.reserve(src_len);
|
||||
///
|
||||
/// unsafe {
|
||||
/// // Give ourselves some scratch space to work with
|
||||
/// let mut t: T = mem::uninitialized();
|
||||
/// // The call to offset is always safe because `Vec` will never
|
||||
/// // allocate more than `isize::MAX` bytes.
|
||||
/// let dst = dst.as_mut_ptr().offset(dst_len as isize);
|
||||
/// let src = src.as_ptr();
|
||||
///
|
||||
/// // Perform the swap, `&mut` pointers never alias
|
||||
/// ptr::copy_nonoverlapping(x, &mut t, 1);
|
||||
/// ptr::copy_nonoverlapping(y, x, 1);
|
||||
/// ptr::copy_nonoverlapping(&t, y, 1);
|
||||
/// // The two regions cannot overlap becuase mutable references do
|
||||
/// // not alias, and two different vectors cannot own the same
|
||||
/// // memory.
|
||||
/// ptr::copy_nonoverlapping(src, dst, src_len);
|
||||
/// }
|
||||
///
|
||||
/// // y and t now point to the same thing, but we need to completely forget `t`
|
||||
/// // because it's no longer relevant.
|
||||
/// mem::forget(t);
|
||||
/// unsafe {
|
||||
/// // Truncate `src` without dropping its contents.
|
||||
/// src.set_len(0);
|
||||
///
|
||||
/// // Notify `dst` that it now holds the contents of `src`.
|
||||
/// dst.set_len(dst_len + src_len);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let mut a = vec!['r'];
|
||||
/// let mut b = vec!['u', 's', 't'];
|
||||
///
|
||||
/// append(&mut a, &mut b);
|
||||
///
|
||||
/// assert_eq!(a, &['r', 'u', 's', 't']);
|
||||
/// assert!(b.is_empty());
|
||||
/// ```
|
||||
///
|
||||
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||
|
||||
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
|
||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||
/// and destination may overlap.
|
||||
///
|
||||
/// `copy` is semantically equivalent to C's `memmove`.
|
||||
/// If the source and destination will *never* overlap,
|
||||
/// [`copy_nonoverlapping`] can be used instead.
|
||||
///
|
||||
/// `copy` is semantically equivalent to C's [`memmove`].
|
||||
///
|
||||
/// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
|
||||
/// [`memmove`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memmove
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Care must be taken with the ownership of `src` and `dst`.
|
||||
/// This method semantically moves the values of `src` into `dst`.
|
||||
/// However it does not drop the contents of `dst`, or prevent the contents of `src`
|
||||
/// from being dropped or used.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * The region of memory which begins at `src` and has a length of
|
||||
/// `count * size_of::<T>()` bytes must be *both* valid and initialized.
|
||||
///
|
||||
/// * The region of memory which begins at `dst` and has a length of
|
||||
/// `count * size_of::<T>()` bytes must be valid (but may or may not be
|
||||
/// initialized).
|
||||
///
|
||||
/// * `src` must be properly aligned.
|
||||
///
|
||||
/// * `dst` must be properly aligned.
|
||||
///
|
||||
/// Additionally, if `T` is not [`Copy`], only the region at `src` *or* the
|
||||
/// region at `dst` can be used or dropped after calling `copy`. `copy`
|
||||
/// creates bitwise copies of `T`, regardless of whether `T: Copy`, which
|
||||
/// can result in undefined behavior if both copies are used.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -1031,15 +1094,34 @@ extern "rust-intrinsic" {
|
||||
/// dst
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||
|
||||
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
|
||||
/// bytes of memory starting at `dst` to `val`.
|
||||
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
|
||||
/// `val`.
|
||||
///
|
||||
/// `write_bytes` is semantically equivalent to C's [`memset`].
|
||||
///
|
||||
/// [`memset`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memset
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * The region of memory which begins at `dst` and has a length of
|
||||
/// `count` bytes must be valid.
|
||||
///
|
||||
/// * `dst` must be properly aligned.
|
||||
///
|
||||
/// Additionally, the caller must ensure that writing `count` bytes to the
|
||||
/// given region of memory results in a valid value of `T`. Creating an
|
||||
/// invalid value of `T` can result in undefined behavior. An example is
|
||||
/// provided below.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
@ -1050,6 +1132,23 @@ extern "rust-intrinsic" {
|
||||
/// }
|
||||
/// assert_eq!(vec, [b'a', b'a', 0, 0]);
|
||||
/// ```
|
||||
///
|
||||
/// Creating an invalid value:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::{mem, ptr};
|
||||
///
|
||||
/// let mut v = Box::new(0i32);
|
||||
///
|
||||
/// unsafe {
|
||||
/// // Leaks the previously held value by overwriting the `Box<T>` with
|
||||
/// // a null pointer.
|
||||
/// ptr::write_bytes(&mut v, 0, mem::size_of::<Box<i32>>());
|
||||
/// }
|
||||
///
|
||||
/// // At this point, using or dropping `v` results in undefined behavior.
|
||||
/// // v = Box::new(0i32); // ERROR
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
||||
|
||||
|
@ -587,7 +587,7 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
|
||||
/// that information can be useful. For example, if you want to iterate
|
||||
/// backwards, a good start is to know where the end is.
|
||||
///
|
||||
/// When implementing an `ExactSizeIterator`, You must also implement
|
||||
/// When implementing an `ExactSizeIterator`, you must also implement
|
||||
/// [`Iterator`]. When doing so, the implementation of [`size_hint`] *must*
|
||||
/// return the exact size of the iterator.
|
||||
///
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
|
||||
|
||||
//! Raw, unsafe pointers, `*const T`, and `*mut T`.
|
||||
//! Manually manage memory through raw pointers.
|
||||
//!
|
||||
//! *[See also the pointer primitive types](../../std/primitive.pointer.html).*
|
||||
|
||||
@ -38,21 +38,62 @@ pub use intrinsics::write_bytes;
|
||||
|
||||
/// Executes the destructor (if any) of the pointed-to value.
|
||||
///
|
||||
/// This has two use cases:
|
||||
/// This is semantically equivalent to calling [`ptr::read`] and discarding
|
||||
/// the result, but has the following advantages:
|
||||
///
|
||||
/// * It is *required* to use `drop_in_place` to drop unsized types like
|
||||
/// trait objects, because they can't be read out onto the stack and
|
||||
/// dropped normally.
|
||||
///
|
||||
/// * It is friendlier to the optimizer to do this over `ptr::read` when
|
||||
/// * It is friendlier to the optimizer to do this over [`ptr::read`] when
|
||||
/// dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
|
||||
/// as the compiler doesn't need to prove that it's sound to elide the
|
||||
/// copy.
|
||||
///
|
||||
/// [`ptr::read`]: ../ptr/fn.read.html
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This has all the same safety problems as `ptr::read` with respect to
|
||||
/// invalid pointers, types, and double drops.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `to_drop` must point to valid memory.
|
||||
///
|
||||
/// * `to_drop` must be properly aligned.
|
||||
///
|
||||
/// Additionally, if `T` is not [`Copy`], using the pointed-to value after
|
||||
/// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
|
||||
/// foo` counts as a use because it will cause the the value to be dropped
|
||||
/// again. [`write`] can be used to overwrite data without causing it to be
|
||||
/// dropped.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`write`]: ../ptr/fn.write.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Manually remove the last item from a vector:
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
/// use std::rc::Rc;
|
||||
///
|
||||
/// let last = Rc::new(1);
|
||||
/// let weak = Rc::downgrade(&last);
|
||||
///
|
||||
/// let mut v = vec![Rc::new(0), last];
|
||||
///
|
||||
/// unsafe {
|
||||
/// // Without a call `drop_in_place`, the last item would never be dropped,
|
||||
/// // and the memory it manages would be leaked.
|
||||
/// ptr::drop_in_place(&mut v[1]);
|
||||
/// v.set_len(1);
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(v, &[0.into()]);
|
||||
///
|
||||
/// // Ensure that the last item was dropped.
|
||||
/// assert!(weak.upgrade().is_none());
|
||||
/// ```
|
||||
#[stable(feature = "drop_in_place", since = "1.8.0")]
|
||||
#[lang = "drop_in_place"]
|
||||
#[allow(unconditional_recursion)]
|
||||
@ -93,17 +134,25 @@ pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
|
||||
/// Swaps the values at two mutable locations of the same type, without
|
||||
/// deinitializing either.
|
||||
///
|
||||
/// The values pointed at by `x` and `y` may overlap, unlike `mem::swap` which
|
||||
/// is otherwise equivalent. If the values do overlap, then the overlapping
|
||||
/// region of memory from `x` will be used. This is demonstrated in the
|
||||
/// examples section below.
|
||||
/// But for the following two exceptions, this function is semantically
|
||||
/// equivalent to [`mem::swap`]:
|
||||
///
|
||||
/// * It operates on raw pointers instead of references. When references are
|
||||
/// available, [`mem::swap`] should be preferred.
|
||||
///
|
||||
/// * The two pointed-to values may overlap. If the values do overlap, then the
|
||||
/// overlapping region of memory from `x` will be used. This is demonstrated
|
||||
/// in the examples below.
|
||||
///
|
||||
/// [`mem::swap`]: ../mem/fn.swap.html
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function copies the memory through the raw pointers passed to it
|
||||
/// as arguments.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// Ensure that these pointers are valid before calling `swap`.
|
||||
/// * `x` and `y` must point to valid, initialized memory.
|
||||
///
|
||||
/// * `x` and `y` must be properly aligned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -239,13 +288,39 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Replaces the value at `dest` with `src`, returning the old
|
||||
/// value, without dropping either.
|
||||
/// Replaces the value at `dest` with `src`, returning the old value, without
|
||||
/// dropping either.
|
||||
///
|
||||
/// This function is semantically equivalent to [`mem::replace`] except that it
|
||||
/// operates on raw pointers instead of references. When references are
|
||||
/// available, [`mem::replace`] should be preferred.
|
||||
///
|
||||
/// [`mem::replace`]: ../mem/fn.replace.html
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This is only unsafe because it accepts a raw pointer.
|
||||
/// Otherwise, this operation is identical to `mem::replace`.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `dest` must point to valid, initialized memory.
|
||||
///
|
||||
/// * `dest` must be properly aligned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let mut rust = vec!['b', 'u', 's', 't'];
|
||||
///
|
||||
/// // `mem::replace` would have the same effect without requiring the unsafe
|
||||
/// // block.
|
||||
/// let b = unsafe {
|
||||
/// ptr::replace(&mut rust[0], 'r')
|
||||
/// };
|
||||
///
|
||||
/// assert_eq!(b, 'b');
|
||||
/// assert_eq!(rust, &['r', 'u', 's', 't']);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||
@ -258,14 +333,23 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Beyond accepting a raw pointer, this is unsafe because it semantically
|
||||
/// moves the value out of `src` without preventing further usage of `src`.
|
||||
/// If `T` is not `Copy`, then care must be taken to ensure that the value at
|
||||
/// `src` is not used before the data is overwritten again (e.g. with `write`,
|
||||
/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
|
||||
/// because it will attempt to drop the value previously at `*src`.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// The pointer must be aligned; use `read_unaligned` if that is not the case.
|
||||
/// * `src` must point to valid, initialized memory.
|
||||
///
|
||||
/// * `src` must be properly aligned. Use [`read_unaligned`] if this is not the
|
||||
/// case.
|
||||
///
|
||||
/// Additionally, if `T` is not [`Copy`], only the returned value *or* the
|
||||
/// pointed-to value can be used or dropped after calling `read`. `read` creates
|
||||
/// a bitwise copy of `T`, regardless of whether `T: Copy`, which can result
|
||||
/// in undefined behavior if both copies are used. Note that `*src = foo` counts
|
||||
/// as a use because it will attempt to drop the value previously at `*src`.
|
||||
/// [`write`] can be used to overwrite data without causing it to be dropped.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`read_unaligned`]: ./fn.read_unaligned.html
|
||||
/// [`write`]: ./fn.write.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -279,6 +363,44 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||
/// assert_eq!(std::ptr::read(y), 12);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Manually implement [`mem::swap`]:
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// fn swap<T>(a: &mut T, b: &mut T) {
|
||||
/// unsafe {
|
||||
/// // Create a bitwise copy of the value at `a` in `tmp`.
|
||||
/// let tmp = ptr::read(a);
|
||||
///
|
||||
/// // Exiting at this point (either by explicitly returning or by
|
||||
/// // calling a function which panics) would cause the value in `tmp` to
|
||||
/// // be dropped while the same value is still referenced by `a`. This
|
||||
/// // could trigger undefined behavior if `T` is not `Copy`.
|
||||
///
|
||||
/// // Create a bitwise copy of the value at `b` in `a`.
|
||||
/// // This is safe because mutable references cannot alias.
|
||||
/// ptr::copy_nonoverlapping(b, a, 1);
|
||||
///
|
||||
/// // As above, exiting here could trigger undefined behavior because
|
||||
/// // the same value is referenced by `a` and `b`.
|
||||
///
|
||||
/// // Move `tmp` into `b`.
|
||||
/// ptr::write(b, tmp);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let mut foo = "foo".to_owned();
|
||||
/// let mut bar = "bar".to_owned();
|
||||
///
|
||||
/// swap(&mut foo, &mut bar);
|
||||
///
|
||||
/// assert_eq!(foo, "bar");
|
||||
/// assert_eq!(bar, "foo");
|
||||
/// ```
|
||||
///
|
||||
/// [`mem::swap`]: ../mem/fn.swap.html
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn read<T>(src: *const T) -> T {
|
||||
@ -290,28 +412,62 @@ pub unsafe fn read<T>(src: *const T) -> T {
|
||||
/// Reads the value from `src` without moving it. This leaves the
|
||||
/// memory in `src` unchanged.
|
||||
///
|
||||
/// Unlike `read`, the pointer may be unaligned.
|
||||
/// Unlike [`read`], `read_unaligned` works with unaligned pointers.
|
||||
///
|
||||
/// [`read`]: ./fn.read.html
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Beyond accepting a raw pointer, this is unsafe because it semantically
|
||||
/// moves the value out of `src` without preventing further usage of `src`.
|
||||
/// If `T` is not `Copy`, then care must be taken to ensure that the value at
|
||||
/// `src` is not used before the data is overwritten again (e.g. with `write`,
|
||||
/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
|
||||
/// because it will attempt to drop the value previously at `*src`.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `src` must point to valid, initialized memory.
|
||||
///
|
||||
/// Additionally, if `T` is not [`Copy`], only the returned value *or* the
|
||||
/// pointed-to value can be used or dropped after calling `read_unaligned`.
|
||||
/// `read_unaligned` creates a bitwise copy of `T`, regardless of whether `T:
|
||||
/// Copy`, and this can result in undefined behavior if both copies are used.
|
||||
/// Note that `*src = foo` counts as a use because it will attempt to drop the
|
||||
/// value previously at `*src`. [`write_unaligned`] can be used to overwrite
|
||||
/// data without causing it to be dropped.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`write_unaligned`]: ./fn.write_unaligned.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
/// Access members of a packed struct by reference:
|
||||
///
|
||||
/// ```
|
||||
/// let x = 12;
|
||||
/// let y = &x as *const i32;
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!(std::ptr::read_unaligned(y), 12);
|
||||
/// #[repr(packed, C)]
|
||||
/// #[derive(Default)]
|
||||
/// struct Packed {
|
||||
/// _padding: u8,
|
||||
/// unaligned: u32,
|
||||
/// }
|
||||
///
|
||||
/// let x = Packed {
|
||||
/// _padding: 0x00,
|
||||
/// unaligned: 0x01020304,
|
||||
/// };
|
||||
///
|
||||
/// let v = unsafe {
|
||||
/// // Take a reference to a 32-bit integer which is not aligned.
|
||||
/// let unaligned = &x.unaligned;
|
||||
///
|
||||
/// // Dereferencing normally will emit an unaligned load instruction,
|
||||
/// // causing undefined behavior.
|
||||
/// // let v = *unaligned; // ERROR
|
||||
///
|
||||
/// // Instead, use `read_unaligned` to read improperly aligned values.
|
||||
/// let v = ptr::read_unaligned(unaligned);
|
||||
///
|
||||
/// v
|
||||
/// };
|
||||
///
|
||||
/// // Accessing unaligned values directly is safe.
|
||||
/// assert!(x.unaligned == v);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
||||
@ -326,11 +482,7 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||
/// Overwrites a memory location with the given value without reading or
|
||||
/// dropping the old value.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This operation is marked unsafe because it accepts a raw pointer.
|
||||
///
|
||||
/// It does not drop the contents of `dst`. This is safe, but it could leak
|
||||
/// `write` does not drop the contents of `dst`. This is safe, but it could leak
|
||||
/// allocations or resources, so care must be taken not to overwrite an object
|
||||
/// that should be dropped.
|
||||
///
|
||||
@ -338,9 +490,20 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||
/// location pointed to by `dst`.
|
||||
///
|
||||
/// This is appropriate for initializing uninitialized memory, or overwriting
|
||||
/// memory that has previously been `read` from.
|
||||
/// memory that has previously been [`read`] from.
|
||||
///
|
||||
/// The pointer must be aligned; use `write_unaligned` if that is not the case.
|
||||
/// [`read`]: ./fn.read.html
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `dst` must point to valid memory.
|
||||
///
|
||||
/// * `dst` must be properly aligned. Use [`write_unaligned`] if this is not the
|
||||
/// case.
|
||||
///
|
||||
/// [`write_unaligned`]: ./fn.write_unaligned.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -356,6 +519,30 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||
/// assert_eq!(std::ptr::read(y), 12);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Manually implement [`mem::swap`]:
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// fn swap<T>(a: &mut T, b: &mut T) {
|
||||
/// unsafe {
|
||||
/// let tmp = ptr::read(a);
|
||||
/// ptr::copy_nonoverlapping(b, a, 1);
|
||||
/// ptr::write(b, tmp);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let mut foo = "foo".to_owned();
|
||||
/// let mut bar = "bar".to_owned();
|
||||
///
|
||||
/// swap(&mut foo, &mut bar);
|
||||
///
|
||||
/// assert_eq!(foo, "bar");
|
||||
/// assert_eq!(bar, "foo");
|
||||
/// ```
|
||||
///
|
||||
/// [`mem::swap`]: ../mem/fn.swap.html
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn write<T>(dst: *mut T, src: T) {
|
||||
@ -365,36 +552,58 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
|
||||
/// Overwrites a memory location with the given value without reading or
|
||||
/// dropping the old value.
|
||||
///
|
||||
/// Unlike `write`, the pointer may be unaligned.
|
||||
/// Unlike [`write`], the pointer may be unaligned.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This operation is marked unsafe because it accepts a raw pointer.
|
||||
///
|
||||
/// It does not drop the contents of `dst`. This is safe, but it could leak
|
||||
/// allocations or resources, so care must be taken not to overwrite an object
|
||||
/// that should be dropped.
|
||||
/// `write_unaligned` does not drop the contents of `dst`. This is safe, but it
|
||||
/// could leak allocations or resources, so care must be taken not to overwrite
|
||||
/// an object that should be dropped.
|
||||
///
|
||||
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
|
||||
/// location pointed to by `dst`.
|
||||
///
|
||||
/// This is appropriate for initializing uninitialized memory, or overwriting
|
||||
/// memory that has previously been `read` from.
|
||||
/// memory that has previously been read with [`read_unaligned`].
|
||||
///
|
||||
/// [`write`]: ./fn.write.html
|
||||
/// [`read_unaligned`]: ./fn.read_unaligned.html
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `dst` must point to valid memory.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
/// Access fields in a packed struct:
|
||||
///
|
||||
/// ```
|
||||
/// let mut x = 0;
|
||||
/// let y = &mut x as *mut i32;
|
||||
/// let z = 12;
|
||||
/// use std::{mem, ptr};
|
||||
///
|
||||
/// #[repr(packed, C)]
|
||||
/// #[derive(Default)]
|
||||
/// struct Packed {
|
||||
/// _padding: u8,
|
||||
/// unaligned: u32,
|
||||
/// }
|
||||
///
|
||||
/// let v = 0x01020304;
|
||||
/// let mut x: Packed = unsafe { mem::zeroed() };
|
||||
///
|
||||
/// unsafe {
|
||||
/// std::ptr::write_unaligned(y, z);
|
||||
/// assert_eq!(std::ptr::read_unaligned(y), 12);
|
||||
/// // Take a reference to a 32-bit integer which is not aligned.
|
||||
/// let unaligned = &mut x.unaligned;
|
||||
///
|
||||
/// // Dereferencing normally will emit an unaligned store instruction,
|
||||
/// // causing undefined behavior.
|
||||
/// // *unaligned = v; // ERROR
|
||||
///
|
||||
/// // Instead, use `write_unaligned` to write improperly aligned values.
|
||||
/// ptr::write_unaligned(unaligned, v);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// // Accessing unaligned values directly is safe.
|
||||
/// assert!(x.unaligned == v);
|
||||
#[inline]
|
||||
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
||||
pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
||||
@ -411,6 +620,11 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
||||
/// to not be elided or reordered by the compiler across other volatile
|
||||
/// operations.
|
||||
///
|
||||
/// Memory read with `read_volatile` should almost always be written to using
|
||||
/// [`write_volatile`].
|
||||
///
|
||||
/// [`write_volatile`]: ./fn.write_volatile.html
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// Rust does not currently have a rigorously and formally defined memory model,
|
||||
@ -427,12 +641,19 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Beyond accepting a raw pointer, this is unsafe because it semantically
|
||||
/// moves the value out of `src` without preventing further usage of `src`.
|
||||
/// If `T` is not `Copy`, then care must be taken to ensure that the value at
|
||||
/// `src` is not used before the data is overwritten again (e.g. with `write`,
|
||||
/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
|
||||
/// because it will attempt to drop the value previously at `*src`.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `src` must point to valid, initialized memory.
|
||||
///
|
||||
/// * `src` must be properly aligned.
|
||||
///
|
||||
/// Like [`read`], `read_volatile` creates a bitwise copy of the pointed-to
|
||||
/// object, regardless of whether `T` is [`Copy`]. Using both values can cause
|
||||
/// undefined behavior. However, storing non-[`Copy`] data in I/O memory is
|
||||
/// almost certainly incorrect.
|
||||
///
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`read`]: ./fn.read.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -459,6 +680,18 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
|
||||
/// to not be elided or reordered by the compiler across other volatile
|
||||
/// operations.
|
||||
///
|
||||
/// Memory written with `write_volatile` should almost always be read from using
|
||||
/// [`read_volatile`].
|
||||
///
|
||||
/// `write_volatile` does not drop the contents of `dst`. This is safe, but it
|
||||
/// could leak allocations or resources, so care must be taken not to overwrite
|
||||
/// an object that should be dropped.
|
||||
///
|
||||
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
|
||||
/// location pointed to by `dst`.
|
||||
///
|
||||
/// [`read_volatile`]: ./fn.read_volatile.html
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// Rust does not currently have a rigorously and formally defined memory model,
|
||||
@ -475,14 +708,11 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This operation is marked unsafe because it accepts a raw pointer.
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// It does not drop the contents of `dst`. This is safe, but it could leak
|
||||
/// allocations or resources, so care must be taken not to overwrite an object
|
||||
/// that should be dropped.
|
||||
/// * `dst` must point to valid memory.
|
||||
///
|
||||
/// This is appropriate for initializing uninitialized memory, or overwriting
|
||||
/// memory that has previously been `read` from.
|
||||
/// * `dst` must be properly aligned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -14,6 +14,7 @@ use infer::InferCtxt;
|
||||
use infer::type_variable::TypeVariableOrigin;
|
||||
use ty::{self, Ty, TyInfer, TyVar};
|
||||
use syntax_pos::Span;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
@ -86,7 +87,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn need_type_info(&self, body_id: Option<hir::BodyId>, span: Span, ty: Ty<'tcx>) {
|
||||
pub fn need_type_info_err(&self,
|
||||
body_id: Option<hir::BodyId>,
|
||||
span: Span,
|
||||
ty: Ty<'tcx>)
|
||||
-> DiagnosticBuilder<'gcx> {
|
||||
let ty = self.resolve_type_vars_if_possible(&ty);
|
||||
let name = self.extract_type_name(&ty);
|
||||
|
||||
@ -142,6 +147,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
err.span_label(target_span, label_message);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
err
|
||||
}
|
||||
}
|
||||
|
@ -1234,7 +1234,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.tcx.lang_items().sized_trait()
|
||||
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
|
||||
{
|
||||
self.need_type_info(body_id, span, self_ty);
|
||||
self.need_type_info_err(body_id, span, self_ty).emit();
|
||||
} else {
|
||||
let mut err = struct_span_err!(self.tcx.sess,
|
||||
span, E0283,
|
||||
@ -1251,7 +1251,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
// Same hacky approach as above to avoid deluging user
|
||||
// with error messages.
|
||||
if !ty.references_error() && !self.tcx.sess.has_errors() {
|
||||
self.need_type_info(body_id, span, ty);
|
||||
self.need_type_info_err(body_id, span, ty).emit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1262,9 +1262,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
|
||||
// both must be type variables, or the other would've been instantiated
|
||||
assert!(a.is_ty_var() && b.is_ty_var());
|
||||
self.need_type_info(body_id,
|
||||
obligation.cause.span,
|
||||
a);
|
||||
self.need_type_info_err(body_id,
|
||||
obligation.cause.span,
|
||||
a).emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ rustc_target = { path = "../librustc_target" }
|
||||
rustc_typeck = { path = "../librustc_typeck" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
rls-data = "0.15"
|
||||
rls-data = "0.16"
|
||||
rls-span = "0.4"
|
||||
# FIXME(#40527) should move rustc serialize out of tree
|
||||
rustc-serialize = "0.3"
|
||||
|
@ -268,80 +268,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
}
|
||||
}
|
||||
|
||||
fn process_def_kind(
|
||||
&mut self,
|
||||
ref_id: NodeId,
|
||||
span: Span,
|
||||
sub_span: Option<Span>,
|
||||
def_id: DefId,
|
||||
) {
|
||||
if self.span.filter_generated(sub_span, span) {
|
||||
return;
|
||||
}
|
||||
|
||||
let def = self.save_ctxt.get_path_def(ref_id);
|
||||
match def {
|
||||
HirDef::Mod(_) => {
|
||||
let span = self.span_from_span(sub_span.expect("No span found for mod ref"));
|
||||
self.dumper.dump_ref(Ref {
|
||||
kind: RefKind::Mod,
|
||||
span,
|
||||
ref_id: ::id_from_def_id(def_id),
|
||||
});
|
||||
}
|
||||
HirDef::Struct(..) |
|
||||
HirDef::Variant(..) |
|
||||
HirDef::Union(..) |
|
||||
HirDef::Enum(..) |
|
||||
HirDef::TyAlias(..) |
|
||||
HirDef::TyForeign(..) |
|
||||
HirDef::TraitAlias(..) |
|
||||
HirDef::Trait(_) => {
|
||||
let span = self.span_from_span(sub_span.expect("No span found for type ref"));
|
||||
self.dumper.dump_ref(Ref {
|
||||
kind: RefKind::Type,
|
||||
span,
|
||||
ref_id: ::id_from_def_id(def_id),
|
||||
});
|
||||
}
|
||||
HirDef::Static(..) |
|
||||
HirDef::Const(..) |
|
||||
HirDef::StructCtor(..) |
|
||||
HirDef::VariantCtor(..) => {
|
||||
let span = self.span_from_span(sub_span.expect("No span found for var ref"));
|
||||
self.dumper.dump_ref(Ref {
|
||||
kind: RefKind::Variable,
|
||||
span,
|
||||
ref_id: ::id_from_def_id(def_id),
|
||||
});
|
||||
}
|
||||
HirDef::Fn(..) => {
|
||||
let span = self.span_from_span(sub_span.expect("No span found for fn ref"));
|
||||
self.dumper.dump_ref(Ref {
|
||||
kind: RefKind::Function,
|
||||
span,
|
||||
ref_id: ::id_from_def_id(def_id),
|
||||
});
|
||||
}
|
||||
// With macros 2.0, we can legitimately get a ref to a macro, but
|
||||
// we don't handle it properly for now (FIXME).
|
||||
HirDef::Macro(..) => {}
|
||||
HirDef::Local(..) |
|
||||
HirDef::Upvar(..) |
|
||||
HirDef::SelfTy(..) |
|
||||
HirDef::Label(_) |
|
||||
HirDef::TyParam(..) |
|
||||
HirDef::Method(..) |
|
||||
HirDef::AssociatedTy(..) |
|
||||
HirDef::AssociatedConst(..) |
|
||||
HirDef::PrimTy(_) |
|
||||
HirDef::GlobalAsm(_) |
|
||||
HirDef::Err => {
|
||||
span_bug!(span, "process_def_kind for unexpected item: {:?}", def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn process_formals(&mut self, formals: &'l [ast::Arg], qualname: &str) {
|
||||
for arg in formals {
|
||||
self.visit_pat(&arg.pat);
|
||||
@ -1348,29 +1274,17 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
};
|
||||
|
||||
let sub_span = self.span.span_for_last_ident(path.span);
|
||||
let mod_id = match self.lookup_def_id(id) {
|
||||
Some(def_id) => {
|
||||
self.process_def_kind(id, path.span, sub_span, def_id);
|
||||
Some(def_id)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// 'use' always introduces an alias, if there is not an explicit
|
||||
// one, there is an implicit one.
|
||||
let sub_span = match self.span.sub_span_after_keyword(use_tree.span,
|
||||
keywords::As) {
|
||||
Some(sub_span) => Some(sub_span),
|
||||
None => sub_span,
|
||||
};
|
||||
let alias_span = self.span.sub_span_after_keyword(use_tree.span, keywords::As);
|
||||
let ref_id = self.lookup_def_id(id);
|
||||
|
||||
if !self.span.filter_generated(sub_span, path.span) {
|
||||
let span =
|
||||
self.span_from_span(sub_span.expect("No span found for use"));
|
||||
let span = self.span_from_span(sub_span.expect("No span found for use"));
|
||||
let alias_span = alias_span.map(|sp| self.span_from_span(sp));
|
||||
self.dumper.import(&access, Import {
|
||||
kind: ImportKind::Use,
|
||||
ref_id: mod_id.map(|id| ::id_from_def_id(id)),
|
||||
ref_id: ref_id.map(|id| ::id_from_def_id(id)),
|
||||
span,
|
||||
alias_span,
|
||||
name: ident.to_string(),
|
||||
value: String::new(),
|
||||
parent,
|
||||
@ -1407,6 +1321,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
kind: ImportKind::GlobUse,
|
||||
ref_id: None,
|
||||
span,
|
||||
alias_span: None,
|
||||
name: "*".to_owned(),
|
||||
value: names.join(", "),
|
||||
parent,
|
||||
@ -1500,6 +1415,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
||||
kind: ImportKind::ExternCrate,
|
||||
ref_id: None,
|
||||
span,
|
||||
alias_span: None,
|
||||
name: item.ident.to_string(),
|
||||
value: String::new(),
|
||||
parent,
|
||||
|
@ -3058,7 +3058,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
base: &'gcx hir::Expr,
|
||||
field: &Spanned<ast::Name>) -> Ty<'tcx> {
|
||||
let expr_t = self.check_expr_with_needs(base, needs);
|
||||
let expr_t = self.structurally_resolved_type(expr.span,
|
||||
let expr_t = self.structurally_resolved_type(base.span,
|
||||
expr_t);
|
||||
let mut private_candidate = None;
|
||||
let mut autoderef = self.autoderef(expr.span, expr_t);
|
||||
@ -4077,7 +4077,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
} else if idx_t.references_error() {
|
||||
idx_t
|
||||
} else {
|
||||
let base_t = self.structurally_resolved_type(expr.span, base_t);
|
||||
let base_t = self.structurally_resolved_type(base.span, base_t);
|
||||
match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
|
||||
Some((index_ty, element_ty)) => {
|
||||
// two-phase not needed because index_ty is never mutable
|
||||
@ -5049,7 +5049,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
ty
|
||||
} else {
|
||||
if !self.is_tainted_by_errors() {
|
||||
self.need_type_info((**self).body_id, sp, ty);
|
||||
self.need_type_info_err((**self).body_id, sp, ty)
|
||||
.note("type must be known at this point")
|
||||
.emit();
|
||||
}
|
||||
self.demand_suptype(sp, self.tcx.types.err, ty);
|
||||
self.tcx.types.err
|
||||
|
@ -593,7 +593,7 @@ impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> {
|
||||
fn report_error(&self, t: Ty<'tcx>) {
|
||||
if !self.tcx.sess.has_errors() {
|
||||
self.infcx
|
||||
.need_type_info(Some(self.body.id()), self.span.to_span(&self.tcx), t);
|
||||
.need_type_info_err(Some(self.body.id()), self.span.to_span(&self.tcx), t).emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,3 +10,4 @@ path = "lib.rs"
|
||||
[dependencies]
|
||||
pulldown-cmark = { version = "0.1.2", default-features = false }
|
||||
tempdir = "0.3"
|
||||
minifier = "0.0.11"
|
||||
|
@ -17,7 +17,7 @@ pub use self::ItemEnum::*;
|
||||
pub use self::TyParamBound::*;
|
||||
pub use self::SelfTy::*;
|
||||
pub use self::FunctionRetTy::*;
|
||||
pub use self::Visibility::*;
|
||||
pub use self::Visibility::{Public, Inherited};
|
||||
|
||||
use syntax;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
@ -2973,11 +2973,22 @@ impl<'tcx> Clean<Item> for ty::FieldDef {
|
||||
pub enum Visibility {
|
||||
Public,
|
||||
Inherited,
|
||||
Crate,
|
||||
Restricted(DefId, Path),
|
||||
}
|
||||
|
||||
impl Clean<Option<Visibility>> for hir::Visibility {
|
||||
fn clean(&self, _: &DocContext) -> Option<Visibility> {
|
||||
Some(if *self == hir::Visibility::Public { Public } else { Inherited })
|
||||
fn clean(&self, cx: &DocContext) -> Option<Visibility> {
|
||||
Some(match *self {
|
||||
hir::Visibility::Public => Visibility::Public,
|
||||
hir::Visibility::Inherited => Visibility::Inherited,
|
||||
hir::Visibility::Crate => Visibility::Crate,
|
||||
hir::Visibility::Restricted { ref path, .. } => {
|
||||
let path = path.clean(cx);
|
||||
let did = register_def(cx, path.def);
|
||||
Visibility::Restricted(did, path)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -927,8 +927,19 @@ impl<'a> fmt::Display for Method<'a> {
|
||||
impl<'a> fmt::Display for VisSpace<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self.get() {
|
||||
Some(clean::Public) => write!(f, "pub "),
|
||||
Some(clean::Inherited) | None => Ok(())
|
||||
Some(clean::Public) => f.write_str("pub "),
|
||||
Some(clean::Inherited) | None => Ok(()),
|
||||
Some(clean::Visibility::Crate) => write!(f, "pub(crate) "),
|
||||
Some(clean::Visibility::Restricted(did, ref path)) => {
|
||||
f.write_str("pub(")?;
|
||||
if path.segments.len() != 1
|
||||
|| (path.segments[0].name != "self" && path.segments[0].name != "super")
|
||||
{
|
||||
f.write_str("in ")?;
|
||||
}
|
||||
resolved_path(f, did, path, true, false)?;
|
||||
f.write_str(") ")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,8 @@ use html::item_type::ItemType;
|
||||
use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine};
|
||||
use html::{highlight, layout};
|
||||
|
||||
use minifier;
|
||||
|
||||
/// A pair of name and its optional document.
|
||||
pub type NameDoc = (String, Option<String>);
|
||||
|
||||
@ -513,7 +515,8 @@ pub fn run(mut krate: clean::Crate,
|
||||
css_file_extension: Option<PathBuf>,
|
||||
renderinfo: RenderInfo,
|
||||
sort_modules_alphabetically: bool,
|
||||
themes: Vec<PathBuf>) -> Result<(), Error> {
|
||||
themes: Vec<PathBuf>,
|
||||
enable_minification: bool) -> Result<(), Error> {
|
||||
let src_root = match krate.src {
|
||||
FileName::Real(ref p) => match p.parent() {
|
||||
Some(p) => p.to_path_buf(),
|
||||
@ -665,7 +668,7 @@ pub fn run(mut krate: clean::Crate,
|
||||
CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
|
||||
CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear());
|
||||
|
||||
write_shared(&cx, &krate, &*cache, index)?;
|
||||
write_shared(&cx, &krate, &*cache, index, enable_minification)?;
|
||||
|
||||
// And finally render the whole crate's documentation
|
||||
cx.krate(krate)
|
||||
@ -744,7 +747,8 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
|
||||
fn write_shared(cx: &Context,
|
||||
krate: &clean::Crate,
|
||||
cache: &Cache,
|
||||
search_index: String) -> Result<(), Error> {
|
||||
search_index: String,
|
||||
enable_minification: bool) -> Result<(), Error> {
|
||||
// Write out the shared files. Note that these are shared among all rustdoc
|
||||
// docs placed in the output directory, so this needs to be a synchronized
|
||||
// operation with respect to all other rustdocs running around.
|
||||
@ -836,16 +840,20 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
.join(",")).as_bytes(),
|
||||
)?;
|
||||
|
||||
write(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
|
||||
include_bytes!("static/main.js"))?;
|
||||
write(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
|
||||
include_bytes!("static/settings.js"))?;
|
||||
write_minify(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
|
||||
include_str!("static/main.js"),
|
||||
enable_minification)?;
|
||||
write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
|
||||
include_str!("static/settings.js"),
|
||||
enable_minification)?;
|
||||
|
||||
{
|
||||
let mut data = format!("var resourcesSuffix = \"{}\";\n",
|
||||
cx.shared.resource_suffix).into_bytes();
|
||||
data.extend_from_slice(include_bytes!("static/storage.js"));
|
||||
write(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)), &data)?;
|
||||
cx.shared.resource_suffix);
|
||||
data.push_str(include_str!("static/storage.js"));
|
||||
write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
|
||||
&data,
|
||||
enable_minification)?;
|
||||
}
|
||||
|
||||
if let Some(ref css) = cx.shared.css_file_extension {
|
||||
@ -1042,6 +1050,14 @@ fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> {
|
||||
Ok(try_err!(fs::write(&dst, contents), &dst))
|
||||
}
|
||||
|
||||
fn write_minify(dst: PathBuf, contents: &str, enable_minification: bool) -> Result<(), Error> {
|
||||
if enable_minification {
|
||||
write(dst, minifier::js::minify(contents).as_bytes())
|
||||
} else {
|
||||
write(dst, contents.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Takes a path to a source file and cleans the path to it. This canonicalizes
|
||||
/// things like ".." to components which preserve the "top down" hierarchy of a
|
||||
/// static HTML tree. Each component in the cleaned path will be passed as an
|
||||
|
@ -202,7 +202,7 @@
|
||||
onEach(e.getElementsByTagName('span'), function(i_e) {
|
||||
removeClass(i_e, 'line-highlighted');
|
||||
});
|
||||
})
|
||||
});
|
||||
for (i = from; i <= to; ++i) {
|
||||
addClass(document.getElementById(i), 'line-highlighted');
|
||||
}
|
||||
@ -1972,7 +1972,7 @@
|
||||
hasClass(next.nextElementSibling, 'docblock')))) {
|
||||
insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
|
||||
}
|
||||
}
|
||||
};
|
||||
onEach(document.getElementsByClassName('method'), func);
|
||||
onEach(document.getElementsByClassName('impl'), func);
|
||||
onEach(document.getElementsByClassName('impl-items'), function(e) {
|
||||
|
@ -48,6 +48,7 @@ extern crate test as testing;
|
||||
extern crate rustc_errors as errors;
|
||||
extern crate pulldown_cmark;
|
||||
extern crate tempdir;
|
||||
extern crate minifier;
|
||||
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
|
||||
@ -299,6 +300,11 @@ pub fn opts() -> Vec<RustcOptGroup> {
|
||||
"How errors and other messages are produced",
|
||||
"human|json|short")
|
||||
}),
|
||||
unstable("disable-minification", |o| {
|
||||
o.optflag("",
|
||||
"disable-minification",
|
||||
"Disable minification applied on JS files")
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
@ -480,6 +486,7 @@ pub fn main_args(args: &[String]) -> isize {
|
||||
let linker = matches.opt_str("linker").map(PathBuf::from);
|
||||
let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
|
||||
let resource_suffix = matches.opt_str("resource-suffix");
|
||||
let enable_minification = !matches.opt_present("disable-minification");
|
||||
|
||||
let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
|
||||
let edition = match edition.parse() {
|
||||
@ -523,7 +530,8 @@ pub fn main_args(args: &[String]) -> isize {
|
||||
css_file_extension,
|
||||
renderinfo,
|
||||
sort_modules_alphabetically,
|
||||
themes)
|
||||
themes,
|
||||
enable_minification)
|
||||
.expect("failed to generate documentation");
|
||||
0
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ impl f32 {
|
||||
|
||||
/// Returns the largest integer less than or equal to a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.99_f32;
|
||||
/// let g = 3.0_f32;
|
||||
@ -80,6 +82,8 @@ impl f32 {
|
||||
|
||||
/// Returns the smallest integer greater than or equal to a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.01_f32;
|
||||
/// let g = 4.0_f32;
|
||||
@ -100,6 +104,8 @@ impl f32 {
|
||||
/// Returns the nearest integer to a number. Round half-way cases away from
|
||||
/// `0.0`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.3_f32;
|
||||
/// let g = -3.3_f32;
|
||||
@ -115,6 +121,8 @@ impl f32 {
|
||||
|
||||
/// Returns the integer part of a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.3_f32;
|
||||
/// let g = -3.7_f32;
|
||||
@ -130,6 +138,8 @@ impl f32 {
|
||||
|
||||
/// Returns the fractional part of a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -148,6 +158,8 @@ impl f32 {
|
||||
/// Computes the absolute value of `self`. Returns `NAN` if the
|
||||
/// number is `NAN`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -174,6 +186,8 @@ impl f32 {
|
||||
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
|
||||
/// - `NAN` if the number is `NAN`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -200,6 +214,8 @@ impl f32 {
|
||||
/// Using `mul_add` can be more performant than an unfused multiply-add if
|
||||
/// the target architecture has a dedicated `fma` CPU instruction.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -225,6 +241,8 @@ impl f32 {
|
||||
/// In other words, the result is `self / rhs` rounded to the integer `n`
|
||||
/// such that `self >= n * rhs`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f32 = 7.0;
|
||||
@ -248,6 +266,8 @@ impl f32 {
|
||||
///
|
||||
/// In particular, the result `n` satisfies `0 <= n < rhs.abs()`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f32 = 7.0;
|
||||
@ -273,6 +293,8 @@ impl f32 {
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -289,6 +311,8 @@ impl f32 {
|
||||
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -311,6 +335,8 @@ impl f32 {
|
||||
///
|
||||
/// Returns NaN if `self` is a negative number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -334,6 +360,8 @@ impl f32 {
|
||||
|
||||
/// Returns `e^(self)`, (the exponential function).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -358,6 +386,8 @@ impl f32 {
|
||||
|
||||
/// Returns `2^(self)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -376,6 +406,8 @@ impl f32 {
|
||||
|
||||
/// Returns the natural logarithm of the number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -404,6 +436,8 @@ impl f32 {
|
||||
/// `self.log2()` can produce more accurate results for base 2, and
|
||||
/// `self.log10()` can produce more accurate results for base 10.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -420,6 +454,8 @@ impl f32 {
|
||||
|
||||
/// Returns the base 2 logarithm of the number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -441,6 +477,8 @@ impl f32 {
|
||||
|
||||
/// Returns the base 10 logarithm of the number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -466,6 +504,8 @@ impl f32 {
|
||||
/// * If `self <= other`: `0:0`
|
||||
/// * Else: `self - other`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -493,6 +533,8 @@ impl f32 {
|
||||
|
||||
/// Takes the cubic root of a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -512,6 +554,8 @@ impl f32 {
|
||||
/// Calculates the length of the hypotenuse of a right-angle triangle given
|
||||
/// legs of length `x` and `y`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -531,6 +575,8 @@ impl f32 {
|
||||
|
||||
/// Computes the sine of a number (in radians).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -552,6 +598,8 @@ impl f32 {
|
||||
|
||||
/// Computes the cosine of a number (in radians).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -573,6 +621,8 @@ impl f32 {
|
||||
|
||||
/// Computes the tangent of a number (in radians).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -591,6 +641,8 @@ impl f32 {
|
||||
/// the range [-pi/2, pi/2] or NaN if the number is outside the range
|
||||
/// [-1, 1].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -611,6 +663,8 @@ impl f32 {
|
||||
/// the range [0, pi] or NaN if the number is outside the range
|
||||
/// [-1, 1].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -630,6 +684,8 @@ impl f32 {
|
||||
/// Computes the arctangent of a number. Return value is in radians in the
|
||||
/// range [-pi/2, pi/2];
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -653,6 +709,8 @@ impl f32 {
|
||||
/// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
|
||||
/// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -682,6 +740,8 @@ impl f32 {
|
||||
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
|
||||
/// `(sin(x), cos(x))`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -703,6 +763,8 @@ impl f32 {
|
||||
/// Returns `e^(self) - 1` in a way that is accurate even if the
|
||||
/// number is close to zero.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -722,6 +784,8 @@ impl f32 {
|
||||
/// Returns `ln(1+n)` (natural logarithm) more accurately than if
|
||||
/// the operations were performed separately.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -740,6 +804,8 @@ impl f32 {
|
||||
|
||||
/// Hyperbolic sine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -761,6 +827,8 @@ impl f32 {
|
||||
|
||||
/// Hyperbolic cosine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -782,6 +850,8 @@ impl f32 {
|
||||
|
||||
/// Hyperbolic tangent function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -803,6 +873,8 @@ impl f32 {
|
||||
|
||||
/// Inverse hyperbolic sine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -825,6 +897,8 @@ impl f32 {
|
||||
|
||||
/// Inverse hyperbolic cosine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
@ -846,6 +920,8 @@ impl f32 {
|
||||
|
||||
/// Inverse hyperbolic tangent function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
|
@ -49,6 +49,8 @@ impl f64 {
|
||||
|
||||
/// Returns the largest integer less than or equal to a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.99_f64;
|
||||
/// let g = 3.0_f64;
|
||||
@ -64,6 +66,8 @@ impl f64 {
|
||||
|
||||
/// Returns the smallest integer greater than or equal to a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.01_f64;
|
||||
/// let g = 4.0_f64;
|
||||
@ -80,6 +84,8 @@ impl f64 {
|
||||
/// Returns the nearest integer to a number. Round half-way cases away from
|
||||
/// `0.0`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.3_f64;
|
||||
/// let g = -3.3_f64;
|
||||
@ -95,6 +101,8 @@ impl f64 {
|
||||
|
||||
/// Returns the integer part of a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.3_f64;
|
||||
/// let g = -3.7_f64;
|
||||
@ -110,6 +118,8 @@ impl f64 {
|
||||
|
||||
/// Returns the fractional part of a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 3.5_f64;
|
||||
/// let y = -3.5_f64;
|
||||
@ -126,6 +136,8 @@ impl f64 {
|
||||
/// Computes the absolute value of `self`. Returns `NAN` if the
|
||||
/// number is `NAN`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -152,6 +164,8 @@ impl f64 {
|
||||
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
|
||||
/// - `NAN` if the number is `NAN`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -178,6 +192,8 @@ impl f64 {
|
||||
/// Using `mul_add` can be more performant than an unfused multiply-add if
|
||||
/// the target architecture has a dedicated `fma` CPU instruction.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let m = 10.0_f64;
|
||||
/// let x = 4.0_f64;
|
||||
@ -201,6 +217,8 @@ impl f64 {
|
||||
/// In other words, the result is `self / rhs` rounded to the integer `n`
|
||||
/// such that `self >= n * rhs`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f64 = 7.0;
|
||||
@ -224,6 +242,8 @@ impl f64 {
|
||||
///
|
||||
/// In particular, the result `n` satisfies `0 <= n < rhs.abs()`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f64 = 7.0;
|
||||
@ -248,6 +268,8 @@ impl f64 {
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
/// let abs_difference = (x.powi(2) - x*x).abs();
|
||||
@ -262,6 +284,8 @@ impl f64 {
|
||||
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
/// let abs_difference = (x.powf(2.0) - x*x).abs();
|
||||
@ -278,6 +302,8 @@ impl f64 {
|
||||
///
|
||||
/// Returns NaN if `self` is a negative number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let positive = 4.0_f64;
|
||||
/// let negative = -4.0_f64;
|
||||
@ -299,6 +325,8 @@ impl f64 {
|
||||
|
||||
/// Returns `e^(self)`, (the exponential function).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let one = 1.0_f64;
|
||||
/// // e^1
|
||||
@ -317,6 +345,8 @@ impl f64 {
|
||||
|
||||
/// Returns `2^(self)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 2.0_f64;
|
||||
///
|
||||
@ -333,6 +363,8 @@ impl f64 {
|
||||
|
||||
/// Returns the natural logarithm of the number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let one = 1.0_f64;
|
||||
/// // e^1
|
||||
@ -355,6 +387,8 @@ impl f64 {
|
||||
/// `self.log2()` can produce more accurate results for base 2, and
|
||||
/// `self.log10()` can produce more accurate results for base 10.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let five = 5.0_f64;
|
||||
///
|
||||
@ -369,6 +403,8 @@ impl f64 {
|
||||
|
||||
/// Returns the base 2 logarithm of the number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let two = 2.0_f64;
|
||||
///
|
||||
@ -390,6 +426,8 @@ impl f64 {
|
||||
|
||||
/// Returns the base 10 logarithm of the number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let ten = 10.0_f64;
|
||||
///
|
||||
@ -409,6 +447,8 @@ impl f64 {
|
||||
/// * If `self <= other`: `0:0`
|
||||
/// * Else: `self - other`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 3.0_f64;
|
||||
/// let y = -3.0_f64;
|
||||
@ -434,6 +474,8 @@ impl f64 {
|
||||
|
||||
/// Takes the cubic root of a number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 8.0_f64;
|
||||
///
|
||||
@ -451,6 +493,8 @@ impl f64 {
|
||||
/// Calculates the length of the hypotenuse of a right-angle triangle given
|
||||
/// legs of length `x` and `y`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
/// let y = 3.0_f64;
|
||||
@ -468,6 +512,8 @@ impl f64 {
|
||||
|
||||
/// Computes the sine of a number (in radians).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -485,6 +531,8 @@ impl f64 {
|
||||
|
||||
/// Computes the cosine of a number (in radians).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -502,6 +550,8 @@ impl f64 {
|
||||
|
||||
/// Computes the tangent of a number (in radians).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -520,6 +570,8 @@ impl f64 {
|
||||
/// the range [-pi/2, pi/2] or NaN if the number is outside the range
|
||||
/// [-1, 1].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -540,6 +592,8 @@ impl f64 {
|
||||
/// the range [0, pi] or NaN if the number is outside the range
|
||||
/// [-1, 1].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -559,6 +613,8 @@ impl f64 {
|
||||
/// Computes the arctangent of a number. Return value is in radians in the
|
||||
/// range [-pi/2, pi/2];
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let f = 1.0_f64;
|
||||
///
|
||||
@ -580,6 +636,8 @@ impl f64 {
|
||||
/// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
|
||||
/// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -609,6 +667,8 @@ impl f64 {
|
||||
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
|
||||
/// `(sin(x), cos(x))`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -630,6 +690,8 @@ impl f64 {
|
||||
/// Returns `e^(self) - 1` in a way that is accurate even if the
|
||||
/// number is close to zero.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 7.0_f64;
|
||||
///
|
||||
@ -647,6 +709,8 @@ impl f64 {
|
||||
/// Returns `ln(1+n)` (natural logarithm) more accurately than if
|
||||
/// the operations were performed separately.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -665,6 +729,8 @@ impl f64 {
|
||||
|
||||
/// Hyperbolic sine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -686,6 +752,8 @@ impl f64 {
|
||||
|
||||
/// Hyperbolic cosine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -707,6 +775,8 @@ impl f64 {
|
||||
|
||||
/// Hyperbolic tangent function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
@ -728,6 +798,8 @@ impl f64 {
|
||||
|
||||
/// Inverse hyperbolic sine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0_f64;
|
||||
/// let f = x.sinh().asinh();
|
||||
@ -748,6 +820,8 @@ impl f64 {
|
||||
|
||||
/// Inverse hyperbolic cosine function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0_f64;
|
||||
/// let f = x.cosh().acosh();
|
||||
@ -767,6 +841,8 @@ impl f64 {
|
||||
|
||||
/// Inverse hyperbolic tangent function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
|
@ -13,7 +13,7 @@
|
||||
//! `[1]` Matthew Flatt, Ryan Culpepper, David Darais, and Robert Bruce Findler. 2012.
|
||||
//! *Macros that work together: Compile-time bindings, partial expansion,
|
||||
//! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216.
|
||||
//! DOI=10.1017/S0956796812000093 <http://dx.doi.org/10.1017/S0956796812000093>
|
||||
//! DOI=10.1017/S0956796812000093 <https://doi.org/10.1017/S0956796812000093>
|
||||
|
||||
use GLOBALS;
|
||||
use Span;
|
||||
|
44
src/test/rustdoc/pub-restricted.rs
Normal file
44
src/test/rustdoc/pub-restricted.rs
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
// compile-flags: --document-private-items
|
||||
|
||||
#![feature(crate_visibility_modifier)]
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic'
|
||||
pub struct FooPublic;
|
||||
// @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate'
|
||||
crate struct FooJustCrate;
|
||||
// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
|
||||
pub(crate) struct FooPubCrate;
|
||||
// @has 'foo/struct.FooSelf.html' '//pre' 'pub(self) struct FooSelf'
|
||||
pub(self) struct FooSelf;
|
||||
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(self) struct FooInSelf'
|
||||
pub(in self) struct FooInSelf;
|
||||
mod a {
|
||||
// @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(super) struct FooSuper'
|
||||
pub(super) struct FooSuper;
|
||||
// @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(super) struct FooInSuper'
|
||||
pub(in super) struct FooInSuper;
|
||||
// @has 'foo/a/struct.FooInA.html' '//pre' 'pub(in a) struct FooInA'
|
||||
pub(in a) struct FooInA;
|
||||
mod b {
|
||||
// @has 'foo/a/b/struct.FooInSelfSuperB.html' '//pre' 'pub(in self::super::b) struct FooInSelfSuperB'
|
||||
pub(in self::super::b) struct FooInSelfSuperB;
|
||||
// @has 'foo/a/b/struct.FooInSuperSuper.html' '//pre' 'pub(in super::super) struct FooInSuperSuper'
|
||||
pub(in super::super) struct FooInSuperSuper;
|
||||
// @has 'foo/a/b/struct.FooInAB.html' '//pre' 'pub(in a::b) struct FooInAB'
|
||||
pub(in a::b) struct FooInAB;
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ LL | let x: Option<_> = None;
|
||||
| - consider giving `x` a type
|
||||
LL | x.unwrap().method_that_could_exist_on_some_type();
|
||||
| ^^^^^^^^^^ cannot infer type for `T`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:22:5
|
||||
@ -12,6 +14,8 @@ error[E0282]: type annotations needed
|
||||
LL | / data.iter() //~ ERROR 22:5: 23:20: type annotations needed
|
||||
LL | | .sum::<_>()
|
||||
| |___________________^ cannot infer type for `_`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
25
src/test/ui/span/method-and-field-eager-resolution.rs
Normal file
25
src/test/ui/span/method-and-field-eager-resolution.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that spans get only base in eager type resolution (structurally_resolve_type).
|
||||
|
||||
fn main() {
|
||||
let mut x = Default::default();
|
||||
x.0;
|
||||
//~^ ERROR type annotations needed
|
||||
x = 1;
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let mut x = Default::default();
|
||||
x[0];
|
||||
//~^ ERROR type annotations needed
|
||||
x = 1;
|
||||
}
|
23
src/test/ui/span/method-and-field-eager-resolution.stderr
Normal file
23
src/test/ui/span/method-and-field-eager-resolution.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/method-and-field-eager-resolution.rs:15:5
|
||||
|
|
||||
LL | let mut x = Default::default();
|
||||
| ----- consider giving `x` a type
|
||||
LL | x.0;
|
||||
| ^ cannot infer type for `_`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/method-and-field-eager-resolution.rs:22:5
|
||||
|
|
||||
LL | let mut x = Default::default();
|
||||
| ----- consider giving `x` a type
|
||||
LL | x[0];
|
||||
| ^ cannot infer type for `_`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
@ -12,73 +12,148 @@ const fs = require('fs');
|
||||
|
||||
const TEST_FOLDER = 'src/test/rustdoc-js/';
|
||||
|
||||
function getNextStep(content, pos, stop) {
|
||||
while (pos < content.length && content[pos] !== stop &&
|
||||
(content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) {
|
||||
pos += 1;
|
||||
}
|
||||
if (pos >= content.length) {
|
||||
return null;
|
||||
}
|
||||
if (content[pos] !== stop) {
|
||||
return pos * -1;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Stupid function extractor based on indent.
|
||||
function extractFunction(content, functionName) {
|
||||
var x = content.split('\n');
|
||||
var in_func = false;
|
||||
var indent = 0;
|
||||
var lines = [];
|
||||
var splitter = "function " + functionName + "(";
|
||||
|
||||
for (var i = 0; i < x.length; ++i) {
|
||||
if (in_func === false) {
|
||||
var splitter = "function " + functionName + "(";
|
||||
if (x[i].trim().startsWith(splitter)) {
|
||||
in_func = true;
|
||||
indent = x[i].split(splitter)[0].length;
|
||||
lines.push(x[i]);
|
||||
}
|
||||
} else {
|
||||
lines.push(x[i]);
|
||||
if (x[i].trim() === "}" && x[i].split("}")[0].length === indent) {
|
||||
return lines.join("\n");
|
||||
}
|
||||
while (true) {
|
||||
var start = content.indexOf(splitter);
|
||||
if (start === -1) {
|
||||
break;
|
||||
}
|
||||
var pos = start;
|
||||
while (pos < content.length && content[pos] !== ')') {
|
||||
pos += 1;
|
||||
}
|
||||
if (pos >= content.length) {
|
||||
break;
|
||||
}
|
||||
pos = getNextStep(content, pos + 1, '{');
|
||||
if (pos === null) {
|
||||
break;
|
||||
} else if (pos < 0) {
|
||||
content = content.slice(-pos);
|
||||
continue;
|
||||
}
|
||||
while (pos < content.length) {
|
||||
if (content[pos] === '"' || content[pos] === "'") {
|
||||
var stop = content[pos];
|
||||
var is_escaped = false;
|
||||
do {
|
||||
if (content[pos] === '\\') {
|
||||
pos += 2;
|
||||
} else {
|
||||
pos += 1;
|
||||
}
|
||||
} while (pos < content.length &&
|
||||
(content[pos] !== stop || content[pos - 1] === '\\'));
|
||||
} else if (content[pos] === '{') {
|
||||
indent += 1;
|
||||
} else if (content[pos] === '}') {
|
||||
indent -= 1;
|
||||
if (indent === 0) {
|
||||
return content.slice(start, pos + 1);
|
||||
}
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
content = content.slice(start + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Stupid function extractor for array.
|
||||
function extractArrayVariable(content, arrayName) {
|
||||
var x = content.split('\n');
|
||||
var found_var = false;
|
||||
var lines = [];
|
||||
|
||||
for (var i = 0; i < x.length; ++i) {
|
||||
if (found_var === false) {
|
||||
var splitter = "var " + arrayName + " = [";
|
||||
if (x[i].trim().startsWith(splitter)) {
|
||||
found_var = true;
|
||||
i -= 1;
|
||||
}
|
||||
} else {
|
||||
lines.push(x[i]);
|
||||
if (x[i].endsWith('];')) {
|
||||
return lines.join("\n");
|
||||
}
|
||||
var splitter = "var " + arrayName;
|
||||
while (true) {
|
||||
var start = content.indexOf(splitter);
|
||||
if (start === -1) {
|
||||
break;
|
||||
}
|
||||
var pos = getNextStep(content, start, '=');
|
||||
if (pos === null) {
|
||||
break;
|
||||
} else if (pos < 0) {
|
||||
content = content.slice(-pos);
|
||||
continue;
|
||||
}
|
||||
pos = getNextStep(content, pos, '[');
|
||||
if (pos === null) {
|
||||
break;
|
||||
} else if (pos < 0) {
|
||||
content = content.slice(-pos);
|
||||
continue;
|
||||
}
|
||||
while (pos < content.length) {
|
||||
if (content[pos] === '"' || content[pos] === "'") {
|
||||
var stop = content[pos];
|
||||
do {
|
||||
if (content[pos] === '\\') {
|
||||
pos += 2;
|
||||
} else {
|
||||
pos += 1;
|
||||
}
|
||||
} while (pos < content.length &&
|
||||
(content[pos] !== stop || content[pos - 1] === '\\'));
|
||||
} else if (content[pos] === ']' &&
|
||||
pos + 1 < content.length &&
|
||||
content[pos + 1] === ';') {
|
||||
return content.slice(start, pos + 2);
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
content = content.slice(start + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Stupid function extractor for variable.
|
||||
function extractVariable(content, varName) {
|
||||
var x = content.split('\n');
|
||||
var found_var = false;
|
||||
var lines = [];
|
||||
|
||||
for (var i = 0; i < x.length; ++i) {
|
||||
if (found_var === false) {
|
||||
var splitter = "var " + varName + " = ";
|
||||
if (x[i].trim().startsWith(splitter)) {
|
||||
found_var = true;
|
||||
i -= 1;
|
||||
}
|
||||
} else {
|
||||
lines.push(x[i]);
|
||||
if (x[i].endsWith(';')) {
|
||||
return lines.join("\n");
|
||||
}
|
||||
var splitter = "var " + varName;
|
||||
while (true) {
|
||||
var start = content.indexOf(splitter);
|
||||
if (start === -1) {
|
||||
break;
|
||||
}
|
||||
var pos = getNextStep(content, start, '=');
|
||||
if (pos === null) {
|
||||
break;
|
||||
} else if (pos < 0) {
|
||||
content = content.slice(-pos);
|
||||
continue;
|
||||
}
|
||||
while (pos < content.length) {
|
||||
if (content[pos] === '"' || content[pos] === "'") {
|
||||
var stop = content[pos];
|
||||
do {
|
||||
if (content[pos] === '\\') {
|
||||
pos += 2;
|
||||
} else {
|
||||
pos += 1;
|
||||
}
|
||||
} while (pos < content.length &&
|
||||
(content[pos] !== stop || content[pos - 1] === '\\'));
|
||||
} else if (content[pos] === ';') {
|
||||
return content.slice(start, pos + 1);
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
content = content.slice(start + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -101,7 +176,7 @@ function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
|
||||
for (var i = 0; i < thingsToLoad.length; ++i) {
|
||||
var tmp = funcToCall(fileContent, thingsToLoad[i]);
|
||||
if (tmp === null) {
|
||||
console.error('enable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
|
||||
console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
|
||||
process.exit(1);
|
||||
}
|
||||
content += tmp;
|
||||
|
Loading…
Reference in New Issue
Block a user