1
Fork 0

Auto merge of #2974 - RalfJung:rustup, r=RalfJung

Rustup
This commit is contained in:
bors 2023-07-10 08:29:33 +00:00
commit 3ea096a28d
287 changed files with 4470 additions and 2294 deletions

View file

@ -31,7 +31,7 @@ defaults:
run:
shell: bash
concurrency:
group: "${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}"
group: "${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}"
cancel-in-progress: true
jobs:
pr:
@ -408,7 +408,7 @@ jobs:
- name: dist-x86_64-msvc
env:
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc --enable-full-tools --enable-profiler"
SCRIPT: PGO_HOST=x86_64-pc-windows-msvc python src/ci/stage-build.py python x.py dist bootstrap --include-default-paths
SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist python x.py dist bootstrap --include-default-paths
DIST_REQUIRE_ALL_TOOLS: 1
os: windows-2019-8core-32gb
- name: dist-i686-msvc

View file

@ -172,6 +172,9 @@ name = "anyhow"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
dependencies = [
"backtrace",
]
[[package]]
name = "ar_archive_writer"
@ -258,6 +261,12 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
[[package]]
name = "basic-toml"
version = "0.1.2"
@ -328,6 +337,10 @@ dependencies = [
[[package]]
name = "build_helper"
version = "0.1.0"
dependencies = [
"serde",
"serde_derive",
]
[[package]]
name = "bump-stage0"
@ -685,6 +698,16 @@ dependencies = [
"rand_xorshift",
]
[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
@ -985,6 +1008,15 @@ dependencies = [
"log",
]
[[package]]
name = "encoding_rs"
version = "0.8.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
dependencies = [
"cfg-if",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@ -1174,6 +1206,21 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.0"
@ -1199,6 +1246,12 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "futf"
version = "0.1.5"
@ -1396,6 +1449,25 @@ dependencies = [
"serde",
]
[[package]]
name = "h2"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http",
"indexmap 1.9.3",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "handlebars"
version = "4.3.7"
@ -1494,6 +1566,49 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "http"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
[[package]]
name = "httpdate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
dependencies = [
"libm 0.2.7",
]
[[package]]
name = "humantime"
version = "1.3.0"
@ -1509,6 +1624,43 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
version = "0.14.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "iana-time-zone"
version = "0.1.57"
@ -1717,6 +1869,12 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "ipnet"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
[[package]]
name = "is-terminal"
version = "0.4.8"
@ -1724,7 +1882,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb"
dependencies = [
"hermit-abi 0.3.1",
"rustix 0.38.1",
"rustix 0.38.2",
"windows-sys 0.48.0",
]
@ -1866,6 +2024,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
[[package]]
name = "libm"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
[[package]]
name = "libz-sys"
version = "1.1.9"
@ -2104,6 +2268,17 @@ dependencies = [
"rustc-std-workspace-core",
]
[[package]]
name = "mio"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
dependencies = [
"libc",
"wasi",
"windows-sys 0.48.0",
]
[[package]]
name = "miow"
version = "0.5.0"
@ -2141,6 +2316,24 @@ dependencies = [
"regex",
]
[[package]]
name = "native-tls"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
@ -2169,6 +2362,15 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "ntapi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
dependencies = [
"winapi",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
@ -2240,6 +2442,32 @@ dependencies = [
"winapi",
]
[[package]]
name = "openssl"
version = "0.10.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.8",
]
[[package]]
name = "openssl-probe"
version = "0.1.5"
@ -2258,6 +2486,28 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "opt-dist"
version = "0.1.0"
dependencies = [
"anyhow",
"build_helper",
"camino",
"env_logger 0.10.0",
"fs_extra",
"glob",
"humansize",
"humantime 2.1.0",
"log",
"reqwest",
"serde",
"serde_json",
"sysinfo",
"tar",
"xz",
"zip",
]
[[package]]
name = "overload"
version = "0.1.1"
@ -2277,7 +2527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282"
dependencies = [
"cfg-if",
"libm",
"libm 0.1.4",
]
[[package]]
@ -2730,6 +2980,43 @@ dependencies = [
"walkdir",
]
[[package]]
name = "reqwest"
version = "0.11.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"hyper-tls",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
[[package]]
name = "rls"
version = "2.0.0"
@ -3159,7 +3446,6 @@ name = "rustc_driver"
version = "0.0.0"
dependencies = [
"rustc_driver_impl",
"rustix 0.37.11",
]
[[package]]
@ -4218,9 +4504,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.37.11"
version = "0.37.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77"
checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
dependencies = [
"bitflags 1.3.2",
"errno",
@ -4232,9 +4518,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.1"
version = "0.38.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3"
checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4"
dependencies = [
"bitflags 2.3.3",
"errno",
@ -4296,6 +4582,29 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "security-framework"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "self_cell"
version = "0.10.2"
@ -4352,6 +4661,18 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha1"
version = "0.10.5"
@ -4630,6 +4951,20 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "sysinfo"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9557d0845b86eea8182f7b10dff120214fb6cd9fd937b6f4917714e546a38695"
dependencies = [
"cfg-if",
"core-foundation-sys",
"libc",
"ntapi",
"once_cell",
"winapi",
]
[[package]]
name = "sysroot"
version = "0.0.0"
@ -4660,7 +4995,7 @@ dependencies = [
"cfg-if",
"fastrand",
"redox_syscall 0.3.5",
"rustix 0.37.11",
"rustix 0.37.22",
"windows-sys 0.48.0",
]
@ -4701,7 +5036,7 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
dependencies = [
"rustix 0.37.11",
"rustix 0.37.22",
"windows-sys 0.48.0",
]
@ -4849,7 +5184,36 @@ dependencies = [
"autocfg",
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"pin-project-lite",
"socket2",
"windows-sys 0.48.0",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
"tracing",
]
[[package]]
@ -4901,6 +5265,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d"
[[package]]
name = "tower-service"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
version = "0.1.37"
@ -4986,6 +5356,12 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "try-lock"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "twox-hash"
version = "1.6.3"
@ -5304,6 +5680,15 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@ -5340,6 +5725,18 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.87"
@ -5369,6 +5766,16 @@ version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "web-sys"
version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
@ -5563,6 +5970,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]
[[package]]
name = "writeable"
version = "0.5.2"
@ -5578,6 +5994,15 @@ dependencies = [
"libc",
]
[[package]]
name = "xz"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c887690ff2a2e233e8e49633461521f98ec57fbff9d59a884c9a4f04ec1da34"
dependencies = [
"xz2",
]
[[package]]
name = "xz2"
version = "0.1.7"
@ -5683,3 +6108,15 @@ dependencies = [
"syn 1.0.109",
"synstructure 0.12.6",
]
[[package]]
name = "zip"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
dependencies = [
"byteorder",
"crc32fast",
"crossbeam-utils",
"flate2",
]

View file

@ -43,6 +43,7 @@ members = [
"src/tools/suggest-tests",
"src/tools/generate-windows-sys",
"src/tools/rustdoc-gui-test",
"src/tools/opt-dist",
]
exclude = [

View file

@ -22,8 +22,9 @@ Read ["Installation"] from [The Book].
The Rust build system uses a Python script called `x.py` to build the compiler,
which manages the bootstrapping process. It lives at the root of the project.
It also uses a file named `config.toml` to determine various configuration settings for the build.
You can see a full list of options in `config.example.toml`.
It also uses a file named `config.toml` to determine various configuration
settings for the build. You can see a full list of options in
`config.example.toml`.
The `x.py` command can be run directly on most Unix systems in the following
format:
@ -33,7 +34,8 @@ format:
```
This is how the documentation and examples assume you are running `x.py`.
See the [rustc dev guide][rustcguidebuild] if this does not work on your platform.
See the [rustc dev guide][rustcguidebuild] if this does not work on your
platform.
More information about `x.py` can be found by running it with the `--help` flag
or reading the [rustc dev guide][rustcguidebuild].
@ -105,24 +107,26 @@ See [the rustc-dev-guide for more info][sysllvm].
When complete, `./x.py install` will place several programs into
`$PREFIX/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
API-documentation tool. By default, it will also include [Cargo], Rust's package manager.
You can disable this behavior by passing `--set build.extended=false` to `./configure`.
API-documentation tool. By default, it will also include [Cargo], Rust's
package manager. You can disable this behavior by passing
`--set build.extended=false` to `./configure`.
[Cargo]: https://github.com/rust-lang/cargo
#### Configure and Make
This project provides a configure script and makefile (the latter of which just invokes `x.py`).
`./configure` is the recommended way to programatically generate a `config.toml`. `make` is not
recommended (we suggest using `x.py` directly), but it is supported and we try not to break it
unnecessarily.
This project provides a configure script and makefile (the latter of which just
invokes `x.py`). `./configure` is the recommended way to programatically
generate a `config.toml`. `make` is not recommended (we suggest using `x.py`
directly), but it is supported and we try not to break it unnecessarily.
```sh
./configure
make && sudo make install
```
`configure` generates a `config.toml` which can also be used with normal `x.py` invocations.
`configure` generates a `config.toml` which can also be used with normal `x.py`
invocations.
### Building on Windows
@ -193,7 +197,7 @@ toolchain.
#### MSVC
MSVC builds of Rust additionally require an installation of Visual Studio 2017
(or later) so `rustc` can use its linker. The simplest way is to get
(or later) so `rustc` can use its linker. The simplest way is to get
[Visual Studio], check the "C++ build tools" and "Windows 10 SDK" workload.
[Visual Studio]: https://visualstudio.microsoft.com/downloads/
@ -234,7 +238,8 @@ Windows build triples are:
The build triple can be specified by either specifying `--build=<triple>` when
invoking `x.py` commands, or by creating a `config.toml` file (as described in
[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing `--set build.build=<triple>` to `./configure`.
[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing
`--set build.build=<triple>` to `./configure`.
## Building Documentation

View file

@ -1,3 +1,146 @@
Version 1.71.0 (2023-07-13)
==========================
<a id="1.71.0-Language"></a>
Language
--------
- [Stabilize `raw-dylib`, `link_ordinal`, `import_name_type` and `-Cdlltool`.](https://github.com/rust-lang/rust/pull/109677/)
- [Uplift `clippy::{drop,forget}_{ref,copy}` lints.](https://github.com/rust-lang/rust/pull/109732/)
- [Type inference is more conservative around constrained vars.](https://github.com/rust-lang/rust/pull/110100/)
- [Use fulfillment to check `Drop` impl compatibility](https://github.com/rust-lang/rust/pull/110577/)
<a id="1.71.0-Compiler"></a>
Compiler
--------
- [Evaluate place expression in `PlaceMention`](https://github.com/rust-lang/rust/pull/104844/),
making `let _ =` patterns more consistent with respect to the borrow checker.
- [Add `--print deployment-target` flag for Apple targets.](https://github.com/rust-lang/rust/pull/105354/)
- [Stabilize `extern "C-unwind"` and friends.](https://github.com/rust-lang/rust/pull/106075/)
The existing `extern "C"` etc. may change behavior for cross-language unwinding in a future release.
- [Update the version of musl used on `*-linux-musl` targets to 1.2.3](https://github.com/rust-lang/rust/pull/107129/),
enabling [time64](https://musl.libc.org/time64.html) on 32-bit systems.
- [Stabilize `debugger_visualizer`](https://github.com/rust-lang/rust/pull/108668/)
for embedding metadata like Microsoft's Natvis.
- [Enable flatten-format-args by default.](https://github.com/rust-lang/rust/pull/109999/)
- [Make `Self` respect tuple constructor privacy.](https://github.com/rust-lang/rust/pull/111245/)
- [Improve niche placement by trying two strategies and picking the better result.](https://github.com/rust-lang/rust/pull/108106/)
- [Use `apple-m1` as the target CPU for `aarch64-apple-darwin`.](https://github.com/rust-lang/rust/pull/109899/)
- [Add Tier 3 support for the `x86_64h-apple-darwin` target.](https://github.com/rust-lang/rust/pull/108795/)
- [Promote `loongarch64-unknown-linux-gnu` to Tier 2 with host tools.](https://github.com/rust-lang/rust/pull/110936/)
Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.
<a id="1.71.0-Libraries"></a>
Libraries
---------
- [Rework handling of recursive panics.](https://github.com/rust-lang/rust/pull/110975/)
Additional panics are allowed while unwinding, as long as they are caught before escaping
a `Drop` implementation, but panicking within a panic hook is now an immediate abort.
- [Loosen `From<&[T]> for Box<[T]>` bound to `T: Clone`.](https://github.com/rust-lang/rust/pull/103406/)
- [Remove unnecessary `T: Send` bound](https://github.com/rust-lang/rust/pull/111134/)
in `Error for mpsc::SendError<T>` and `TrySendError<T>`.
- [Fix docs for `alloc::realloc`](https://github.com/rust-lang/rust/pull/108630/)
to match `Layout` requirements that the size must not exceed `isize::MAX`.
- [Document `const {}` syntax for `std::thread_local`.](https://github.com/rust-lang/rust/pull/110620/)
This syntax was stabilized in Rust 1.59, but not previously mentioned in release notes.
<a id="1.71.0-Stabilized-APIs"></a>
Stabilized APIs
---------------
- [`CStr::is_empty`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.is_empty)
- [`BuildHasher::hash_one`](https://doc.rust-lang.org/stable/std/hash/trait.BuildHasher.html#method.hash_one)
- [`NonZeroI*::is_positive`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.is_positive)
- [`NonZeroI*::is_negative`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.is_negative)
- [`NonZeroI*::checked_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.checked_neg)
- [`NonZeroI*::overflowing_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.overflowing_neg)
- [`NonZeroI*::saturating_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.saturating_neg)
- [`NonZeroI*::wrapping_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.wrapping_neg)
- [`Neg for NonZeroI*`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#impl-Neg-for-NonZeroI32)
- [`Neg for &NonZeroI*`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#impl-Neg-for-%26NonZeroI32)
- [`From<[T; N]> for (T...)`](https://doc.rust-lang.org/stable/std/primitive.array.html#impl-From%3C%5BT;+1%5D%3E-for-(T,))
(array to N-tuple for N in 1..=12)
- [`From<(T...)> for [T; N]`](https://doc.rust-lang.org/stable/std/primitive.array.html#impl-From%3C(T,)%3E-for-%5BT;+1%5D)
(N-tuple to array for N in 1..=12)
- [`windows::io::AsHandle for Box<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html#impl-AsHandle-for-Box%3CT%3E)
- [`windows::io::AsHandle for Rc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html#impl-AsHandle-for-Rc%3CT%3E)
- [`windows::io::AsHandle for Arc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html#impl-AsHandle-for-Arc%3CT%3E)
- [`windows::io::AsSocket for Box<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html#impl-AsSocket-for-Box%3CT%3E)
- [`windows::io::AsSocket for Rc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html#impl-AsSocket-for-Rc%3CT%3E)
- [`windows::io::AsSocket for Arc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html#impl-AsSocket-for-Arc%3CT%3E)
These APIs are now stable in const contexts:
- [`<*const T>::read`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read)
- [`<*const T>::read_unaligned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read_unaligned)
- [`<*mut T>::read`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read-1)
- [`<*mut T>::read_unaligned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read_unaligned-1)
- [`ptr::read`](https://doc.rust-lang.org/stable/std/ptr/fn.read.html)
- [`ptr::read_unaligned`](https://doc.rust-lang.org/stable/std/ptr/fn.read_unaligned.html)
- [`<[T]>::split_at`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_at)
<a id="1.71.0-Cargo"></a>
Cargo
-----
- [Allow named debuginfo options in `Cargo.toml`.](https://github.com/rust-lang/cargo/pull/11958/)
- [Add `workspace_default_members` to the output of `cargo metadata`.](https://github.com/rust-lang/cargo/pull/11978/)
- [`cargo add` now considers `rust-version` when selecting packages.](https://github.com/rust-lang/cargo/pull/12078/)
- [Automatically inherit workspace fields when running `cargo new`/`cargo init`.](https://github.com/rust-lang/cargo/pull/12069/)
<a id="1.71.0-Rustdoc"></a>
Rustdoc
-------
- [Add a new `rustdoc::unescaped_backticks` lint for broken inline code.](https://github.com/rust-lang/rust/pull/105848/)
- [Support strikethrough with single tildes.](https://github.com/rust-lang/rust/pull/111152/) (`~~old~~` vs. `~new~`)
<a id="1.71.0-Misc"></a>
Misc
----
<a id="1.71.0-Compatibility-Notes"></a>
Compatibility Notes
-------------------
- [Remove structural match from `TypeId`.](https://github.com/rust-lang/rust/pull/103291/)
Code that uses a constant `TypeId` in a pattern will potentially be broken.
Known cases have already been fixed -- in particular, users of the `log`
crate's `kv_unstable` feature should update to `log v0.4.18` or later.
- [Add a `sysroot` crate to represent the standard library crates.](https://github.com/rust-lang/rust/pull/108865/)
This does not affect stable users, but may require adjustment in tools that build their own standard library.
- [Cargo optimizes its usage under `rustup`.](https://github.com/rust-lang/cargo/pull/11917/) When
Cargo detects it will run `rustc` pointing to a rustup proxy, it'll try bypassing the proxy and
use the underlying binary directly. There are assumptions around the interaction with rustup and
`RUSTUP_TOOLCHAIN`. However, it's not expected to affect normal users.
- [When querying a package, Cargo tries only the original name, all hyphens, and all underscores to
handle misspellings.](https://github.com/rust-lang/cargo/pull/12083/) Previously, Cargo tried each
combination of hyphens and underscores, causing excessive requests to crates.io.
- Cargo now [disallows `RUSTUP_HOME`](https://github.com/rust-lang/cargo/pull/12101/) and
[`RUSTUP_TOOLCHAIN`](https://github.com/rust-lang/cargo/pull/12107/) in the `[env]` configuration
table. This is considered to be not a use case Cargo would like to support, since it will likely
cause problems or lead to confusion.
<a id="1.71.0-Internal-Changes"></a>
Internal Changes
----------------
These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.
Version 1.70.0 (2023-06-01)
==========================

View file

@ -9,7 +9,7 @@ use rustc_middle::mir::{
Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, RegionVid, TyCtxt};
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{sym, DesugaringKind, Span};
@ -584,7 +584,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
},
// If we see an unsized cast, then if it is our data we should check
// whether it is being cast to a trait object.
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), operand, ty) => {
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
operand,
ty,
) => {
match operand {
Operand::Copy(place) | Operand::Move(place) => {
if let Some(from) = place.as_local() {

View file

@ -28,7 +28,7 @@ use rustc_middle::mir::AssertKind;
use rustc_middle::mir::*;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
use rustc_middle::ty::visit::TypeVisitableExt;
@ -1908,7 +1908,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.check_operand(op, location);
match cast_kind {
CastKind::Pointer(PointerCast::ReifyFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
let fn_sig = op.ty(body, tcx).fn_sig(tcx);
// The type that we see in the fcx is like
@ -1937,7 +1937,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => {
let sig = match op.ty(body, tcx).kind() {
ty::Closure(_, substs) => substs.as_closure().sig(),
_ => bug!(),
@ -1962,7 +1962,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
let fn_sig = op.ty(body, tcx).fn_sig(tcx);
// The type that we see in the fcx is like
@ -1991,7 +1991,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
CastKind::Pointer(PointerCast::Unsize) => {
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
let &ty = ty;
let trait_ref = ty::TraitRef::from_lang_item(
tcx,
@ -2038,7 +2038,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
);
}
CastKind::Pointer(PointerCast::MutToConstPointer) => {
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
let ty::RawPtr(ty::TypeAndMut {
ty: ty_from,
mutbl: hir::Mutability::Mut,
@ -2080,7 +2080,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
CastKind::Pointer(PointerCast::ArrayToPointer) => {
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
let ty_from = op.ty(body, tcx);
let opt_ty_elem_mut = match ty_from.kind() {

View file

@ -2,7 +2,7 @@
use rustc_ast::InlineAsmOptions;
use rustc_index::IndexVec;
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
@ -571,7 +571,7 @@ fn codegen_stmt<'tcx>(
lval.write_cvalue(fx, res);
}
Rvalue::Cast(
CastKind::Pointer(PointerCast::ReifyFnPointer),
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
ref operand,
to_ty,
) => {
@ -596,17 +596,17 @@ fn codegen_stmt<'tcx>(
}
}
Rvalue::Cast(
CastKind::Pointer(PointerCast::UnsafeFnPointer),
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer),
ref operand,
to_ty,
)
| Rvalue::Cast(
CastKind::Pointer(PointerCast::MutToConstPointer),
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer),
ref operand,
to_ty,
)
| Rvalue::Cast(
CastKind::Pointer(PointerCast::ArrayToPointer),
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer),
ref operand,
to_ty,
) => {
@ -662,7 +662,7 @@ fn codegen_stmt<'tcx>(
}
}
Rvalue::Cast(
CastKind::Pointer(PointerCast::ClosureFnPointer(_)),
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
ref operand,
_to_ty,
) => {
@ -684,7 +684,11 @@ fn codegen_stmt<'tcx>(
_ => bug!("{} cannot be cast to a fn ptr", operand.layout().ty),
}
}
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), ref operand, _to_ty) => {
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
ref operand,
_to_ty,
) => {
let operand = codegen_operand(fx, operand);
crate::unsize::coerce_unsized_into(fx, operand, lval);
}

View file

@ -1,6 +1,6 @@
//! Codegen of the [`PointerCast::Unsize`] operation.
//! Codegen of the [`PointerCoercion::Unsize`] operation.
//!
//! [`PointerCast::Unsize`]: `rustc_middle::ty::adjustment::PointerCast::Unsize`
//! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize`
use crate::prelude::*;

View file

@ -328,8 +328,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let local_ref = &self.locals[local];
// FIXME Should the return place be named?
let name = if bx.sess().fewer_names() || local == mir::RETURN_PLACE {
let name = if bx.sess().fewer_names() {
None
} else {
Some(match whole_local_var.or(fallback_var.clone()) {

View file

@ -11,7 +11,7 @@ use rustc_middle::mir;
use rustc_middle::mir::Operand;
use rustc_middle::ty::cast::{CastTy, IntTy};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt};
use rustc_session::config::OptLevel;
use rustc_span::source_map::{Span, DUMMY_SP};
use rustc_target::abi::{self, FIRST_VARIANT};
@ -32,7 +32,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
cg_operand.val.store(bx, dest);
}
mir::Rvalue::Cast(mir::CastKind::Pointer(PointerCast::Unsize), ref source, _) => {
mir::Rvalue::Cast(
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
ref source,
_,
) => {
// The destination necessarily contains a fat pointer, so if
// it's a scalar pair, it's a fat pointer or newtype thereof.
if bx.cx().is_backend_scalar_pair(dest.layout) {
@ -411,7 +415,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let lladdr = bx.ptrtoint(llptr, llcast_ty);
OperandValue::Immediate(lladdr)
}
mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => {
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
match *operand.layout.ty.kind() {
ty::FnDef(def_id, substs) => {
let instance = ty::Instance::resolve_for_fn_ptr(
@ -427,7 +431,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty),
}
}
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => {
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
match *operand.layout.ty.kind() {
ty::Closure(def_id, substs) => {
let instance = Instance::resolve_closure(
@ -443,11 +447,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty),
}
}
mir::CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
// This is a no-op at the LLVM level.
operand.val
}
mir::CastKind::Pointer(PointerCast::Unsize) => {
mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => {
assert!(bx.cx().is_backend_scalar_pair(cast));
let (lldata, llextra) = match operand.val {
OperandValue::Pair(lldata, llextra) => {
@ -470,7 +474,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra);
OperandValue::Pair(lldata, llextra)
}
mir::CastKind::Pointer(PointerCast::MutToConstPointer)
mir::CastKind::PointerCoercion(PointerCoercion::MutToConstPointer)
| mir::CastKind::PtrToPtr
if bx.cx().is_backend_scalar_pair(operand.layout) =>
{
@ -504,8 +508,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);
OperandValue::Pair(lldata, llextra)
}
mir::CastKind::Pointer(
PointerCast::MutToConstPointer | PointerCast::ArrayToPointer,
mir::CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
)
| mir::CastKind::IntToInt
| mir::CastKind::FloatToInt

View file

@ -4,7 +4,7 @@ use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::{Float, FloatConvert};
use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
use rustc_middle::mir::CastKind;
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut};
use rustc_target::abi::Integer;
@ -24,51 +24,52 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
cast_ty: Ty<'tcx>,
dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> {
use rustc_middle::mir::CastKind::*;
// FIXME: In which cases should we trigger UB when the source is uninit?
match cast_kind {
Pointer(PointerCast::Unsize) => {
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
let cast_ty = self.layout_of(cast_ty)?;
self.unsize_into(src, cast_ty, dest)?;
}
PointerExposeAddress => {
CastKind::PointerExposeAddress => {
let src = self.read_immediate(src)?;
let res = self.pointer_expose_address_cast(&src, cast_ty)?;
self.write_immediate(res, dest)?;
}
PointerFromExposedAddress => {
CastKind::PointerFromExposedAddress => {
let src = self.read_immediate(src)?;
let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?;
self.write_immediate(res, dest)?;
}
IntToInt | IntToFloat => {
CastKind::IntToInt | CastKind::IntToFloat => {
let src = self.read_immediate(src)?;
let res = self.int_to_int_or_float(&src, cast_ty)?;
self.write_immediate(res, dest)?;
}
FloatToFloat | FloatToInt => {
CastKind::FloatToFloat | CastKind::FloatToInt => {
let src = self.read_immediate(src)?;
let res = self.float_to_float_or_int(&src, cast_ty)?;
self.write_immediate(res, dest)?;
}
FnPtrToPtr | PtrToPtr => {
CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
let src = self.read_immediate(&src)?;
let res = self.ptr_to_ptr(&src, cast_ty)?;
self.write_immediate(res, dest)?;
}
Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer) => {
CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
) => {
// These are NOPs, but can be wide pointers.
let v = self.read_immediate(src)?;
self.write_immediate(*v, dest)?;
}
Pointer(PointerCast::ReifyFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
@ -90,7 +91,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
Pointer(PointerCast::UnsafeFnPointer) => {
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
let src = self.read_immediate(src)?;
match cast_ty.kind() {
ty::FnPtr(_) => {
@ -101,7 +102,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
Pointer(PointerCast::ClosureFnPointer(_)) => {
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
@ -122,7 +123,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
DynStar => {
CastKind::DynStar => {
if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
// Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src.layout.ty, data.principal())?;
@ -136,7 +137,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
Transmute => {
CastKind::Transmute => {
assert!(src.layout.is_sized());
assert!(dest.layout.is_sized());
if src.layout.size != dest.layout.size {

View file

@ -700,8 +700,13 @@ where
assert_eq!(src.layout.size, dest.layout.size);
}
// Setting `nonoverlapping` here only has an effect when we don't hit the fast-path above,
// but that should at least match what LLVM does where `memcpy` is also only used when the
// type does not have Scalar/ScalarPair layout.
// (Or as the `Assign` docs put it, assignments "not producing primitives" must be
// non-overlapping.)
self.mem_copy(
src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ false,
src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ true,
)
}

View file

@ -9,7 +9,7 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
use rustc_middle::ty::{TraitRef, TypeVisitableExt};
use rustc_mir_dataflow::{self, Analysis};
use rustc_span::{sym, Span, Symbol};
@ -521,12 +521,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
Rvalue::Cast(
CastKind::Pointer(
PointerCast::MutToConstPointer
| PointerCast::ArrayToPointer
| PointerCast::UnsafeFnPointer
| PointerCast::ClosureFnPointer(_)
| PointerCast::ReifyFnPointer,
CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer
| PointerCoercion::ArrayToPointer
| PointerCoercion::UnsafeFnPointer
| PointerCoercion::ClosureFnPointer(_)
| PointerCoercion::ReifyFnPointer,
),
_,
_,
@ -534,7 +534,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// These are all okay; they only change the type, not the data.
}
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), _, _) => {
// Unsizing is implemented for CTFE.
}

View file

@ -650,7 +650,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
// FIXME: Add Checks for these
CastKind::PointerFromExposedAddress
| CastKind::PointerExposeAddress
| CastKind::Pointer(_) => {}
| CastKind::PointerCoercion(_) => {}
CastKind::IntToInt | CastKind::IntToFloat => {
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
let target_valid = target_type.is_numeric() || target_type.is_char();

View file

@ -8,6 +8,3 @@ crate-type = ["dylib"]
[dependencies]
rustc_driver_impl = { path = "../rustc_driver_impl" }
# FIXME(Nilstrieb): 0.37.12 adds eventfd support for FreeBSD,
# but FreeBSD 12 does not support it: https://github.com/bytecodealliance/rustix/issues/716
rustix = "=0.37.11"

View file

@ -722,7 +722,14 @@ pub(super) fn check_specialization_validity<'tcx>(
let result = opt_result.unwrap_or(Ok(()));
if let Err(parent_impl) = result {
report_forbidden_specialization(tcx, impl_item, parent_impl);
if !tcx.is_impl_trait_in_trait(impl_item) {
report_forbidden_specialization(tcx, impl_item, parent_impl);
} else {
tcx.sess.delay_span_bug(
DUMMY_SP,
format!("parent item: {:?} not marked as default", parent_impl),
);
}
}
}
@ -1485,7 +1492,9 @@ fn opaque_type_cycle_error(
}
for closure_def_id in visitor.closures {
let Some(closure_local_did) = closure_def_id.as_local() else { continue; };
let Some(closure_local_did) = closure_def_id.as_local() else {
continue;
};
let typeck_results = tcx.typeck(closure_local_did);
let mut label_match = |ty: Ty<'_>, span| {

View file

@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_span::{Span, DUMMY_SP};
use std::fmt;
use crate::errors;
@ -338,7 +338,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
Scope::TraitRefBoundary { .. } => {
// We should only see super trait lifetimes if there is a `Binder` above
assert!(supertrait_bound_vars.is_empty());
// though this may happen when we call `poly_trait_ref_binder_info` with
// an (erroneous, #113423) associated return type bound in an impl header.
if !supertrait_bound_vars.is_empty() {
self.tcx.sess.delay_span_bug(
DUMMY_SP,
format!(
"found supertrait lifetimes without a binder to append \
them to: {supertrait_bound_vars:?}"
),
);
}
break (vec![], BinderScopeType::Normal);
}

View file

@ -7,7 +7,7 @@ use rustc_arena::DroplessArena;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, CrateVariancesMap, ImplTraitInTraitData, SubstsRef, Ty, TyCtxt};
use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
use std::ops::ControlFlow;
@ -59,13 +59,6 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
return variance_of_opaque(tcx, item_def_id);
}
DefKind::AssocTy => {
if let Some(ImplTraitInTraitData::Trait { .. }) =
tcx.opt_rpitit_info(item_def_id.to_def_id())
{
return variance_of_opaque(tcx, item_def_id);
}
}
_ => {}
}
@ -125,7 +118,8 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
// at all for RPITITs.
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
if self.tcx.is_impl_trait_in_trait(*def_id) =>
if self.tcx.is_impl_trait_in_trait(*def_id)
&& !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() =>
{
self.visit_opaque(*def_id, substs)
}

View file

@ -47,7 +47,7 @@ use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
use rustc_infer::traits::{Obligation, PredicateObligation};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::RelateResult;
@ -592,7 +592,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
};
let coerce_target = self.next_ty_var(origin);
let mut coercion = self.unify_and(coerce_target, target, |target| {
let unsize = Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target };
let unsize = Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), target };
match reborrow {
None => vec![unsize],
Some((ref deref, ref autoref)) => vec![deref.clone(), autoref.clone(), unsize],
@ -849,7 +849,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
a,
fn_ty_a,
b,
simple(Adjust::Pointer(PointerCast::UnsafeFnPointer)),
simple(Adjust::Pointer(PointerCoercion::UnsafeFnPointer)),
identity,
)
}
@ -893,16 +893,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|unsafe_ty| {
vec![
Adjustment {
kind: Adjust::Pointer(PointerCast::ReifyFnPointer),
kind: Adjust::Pointer(PointerCoercion::ReifyFnPointer),
target: a_fn_pointer,
},
Adjustment {
kind: Adjust::Pointer(PointerCast::UnsafeFnPointer),
kind: Adjust::Pointer(PointerCoercion::UnsafeFnPointer),
target: unsafe_ty,
},
]
},
simple(Adjust::Pointer(PointerCast::ReifyFnPointer)),
simple(Adjust::Pointer(PointerCoercion::ReifyFnPointer)),
)?;
obligations.extend(o2);
@ -952,7 +952,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
self.unify_and(
pointer_ty,
b,
simple(Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety))),
simple(Adjust::Pointer(PointerCoercion::ClosureFnPointer(unsafety))),
)
}
_ => self.unify_and(a, b, identity),
@ -987,7 +987,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
]
})
} else if mt_a.mutbl != mutbl_b {
self.unify_and(a_unsafe, b, simple(Adjust::Pointer(PointerCast::MutToConstPointer)))
self.unify_and(a_unsafe, b, simple(Adjust::Pointer(PointerCoercion::MutToConstPointer)))
} else {
self.unify_and(a_unsafe, b, identity)
}
@ -1187,13 +1187,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Reify both sides and return the reified fn pointer type.
let fn_ptr = Ty::new_fn_ptr(self.tcx, sig);
let prev_adjustment = match prev_ty.kind() {
ty::Closure(..) => Adjust::Pointer(PointerCast::ClosureFnPointer(a_sig.unsafety())),
ty::FnDef(..) => Adjust::Pointer(PointerCast::ReifyFnPointer),
ty::Closure(..) => {
Adjust::Pointer(PointerCoercion::ClosureFnPointer(a_sig.unsafety()))
}
ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer),
_ => unreachable!(),
};
let next_adjustment = match new_ty.kind() {
ty::Closure(..) => Adjust::Pointer(PointerCast::ClosureFnPointer(b_sig.unsafety())),
ty::FnDef(..) => Adjust::Pointer(PointerCast::ReifyFnPointer),
ty::Closure(..) => {
Adjust::Pointer(PointerCoercion::ClosureFnPointer(b_sig.unsafety()))
}
ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer),
_ => unreachable!(),
};
for expr in exprs.iter().map(|e| e.as_coercion_site()) {

View file

@ -10,7 +10,7 @@ use rustc_hir_analysis::astconv::generics::{
use rustc_hir_analysis::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall};
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::{self, SubstsRef};
@ -212,8 +212,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
region,
ty::TypeAndMut { mutbl: mutbl.into(), ty: unsized_ty },
);
adjustments
.push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target });
adjustments.push(Adjustment {
kind: Adjust::Pointer(PointerCoercion::Unsize),
target,
});
}
}
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) => {
@ -226,7 +228,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
};
adjustments.push(Adjustment {
kind: Adjust::Pointer(PointerCast::MutToConstPointer),
kind: Adjust::Pointer(PointerCoercion::MutToConstPointer),
target,
});
}

View file

@ -394,8 +394,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut pat_ty = ty;
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(..), .. }) = lt.kind {
let expected = self.structurally_resolve_type(span, expected);
if let ty::Ref(_, inner_ty, _) = expected.kind()
&& matches!(inner_ty.kind(), ty::Slice(_))
if let ty::Ref(_, inner_ty, _) = *expected.kind()
&& self.try_structurally_resolve_type(span, inner_ty).is_slice()
{
let tcx = self.tcx;
trace!(?lt.hir_id.local_id, "polymorphic byte string lit");

View file

@ -6,7 +6,7 @@ use rustc_hir as hir;
use rustc_hir_analysis::autoderef::Autoderef;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::InferOk;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCoercion};
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::{sym, Ident};
@ -173,7 +173,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if unsize {
adjustments.push(Adjustment {
kind: Adjust::Pointer(PointerCast::Unsize),
kind: Adjust::Pointer(PointerCoercion::Unsize),
target: method.sig.inputs()[0],
});
}
@ -441,7 +441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let [
..,
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target },
Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), ref mut target },
] = adjustments[..]
{
*target = method.sig.inputs()[0];

View file

@ -11,7 +11,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_middle::hir::place::Place as HirPlace;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
@ -251,7 +251,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// Since this is "after" the other adjustment to be
// discarded, we do an extra `pop()`
if let Some(Adjustment {
kind: Adjust::Pointer(PointerCast::Unsize), ..
kind: Adjust::Pointer(PointerCoercion::Unsize), ..
}) = a.pop()
{
// So the borrow discard actually happens here

View file

@ -473,17 +473,6 @@ where
}
}
ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
// Skip lifetime parameters that are not captures.
let variances = self.tcx.variances_of(proj.def_id);
for (v, s) in std::iter::zip(variances, proj.substs.iter()) {
if *v != ty::Variance::Bivariant {
s.visit_with(self);
}
}
}
_ => {
ty.super_visit_with(self);
}

View file

@ -2014,7 +2014,7 @@ impl<'tcx> Rvalue<'tcx> {
| CastKind::IntToFloat
| CastKind::FnPtrToPtr
| CastKind::PtrToPtr
| CastKind::Pointer(_)
| CastKind::PointerCoercion(_)
| CastKind::PointerFromExposedAddress
| CastKind::DynStar
| CastKind::Transmute,

View file

@ -7,7 +7,7 @@ use super::{BasicBlock, Constant, Local, SwitchTargets, UserTypeProjection};
use crate::mir::coverage::{CodeRegion, CoverageKind};
use crate::traits::Reveal;
use crate::ty::adjustment::PointerCast;
use crate::ty::adjustment::PointerCoercion;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, List, Ty};
use crate::ty::{Region, UserTypeAnnotationIndex};
@ -1230,9 +1230,9 @@ pub enum CastKind {
/// An address-to-pointer cast that picks up an exposed provenance.
/// See the docs on `from_exposed_addr` for more details.
PointerFromExposedAddress,
/// All sorts of pointer-to-pointer casts. Note that reference-to-raw-ptr casts are
/// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
/// translated into `&raw mut/const *r`, i.e., they are not actually casts.
Pointer(PointerCast),
PointerCoercion(PointerCoercion),
/// Cast into a dyn* object.
DynStar,
IntToInt,

View file

@ -18,7 +18,7 @@ use rustc_index::IndexVec;
use rustc_middle::middle::region;
use rustc_middle::mir::interpret::AllocId;
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts};
use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
@ -329,9 +329,10 @@ pub enum ExprKind<'tcx> {
NeverToAny {
source: ExprId,
},
/// A pointer cast. More information can be found in [`PointerCast`].
Pointer {
cast: PointerCast,
/// A pointer coercion. More information can be found in [`PointerCoercion`].
/// Pointer casts that cannot be done by coercions are represented by [`ExprKind::Cast`].
PointerCoercion {
cast: PointerCoercion,
source: ExprId,
},
/// A `loop` expression.

View file

@ -65,7 +65,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
Use { source } => visitor.visit_expr(&visitor.thir()[source]),
NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
Let { expr, .. } => {
visitor.visit_expr(&visitor.thir()[expr]);
}

View file

@ -6,7 +6,7 @@ use rustc_span::Span;
use rustc_target::abi::FieldIdx;
#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum PointerCast {
pub enum PointerCoercion {
/// Go from a fn-item type to a fn-pointer type.
ReifyFnPointer,
@ -99,7 +99,7 @@ pub enum Adjust<'tcx> {
/// Take the address and produce either a `&` or `*` pointer.
Borrow(AutoBorrow<'tcx>),
Pointer(PointerCast),
Pointer(PointerCoercion),
/// Cast into a dyn* object.
DynStar,

View file

@ -1110,12 +1110,11 @@ where
///
/// This takes two primary parameters:
///
/// * `codegen_fn_attr_flags` - these are flags calculated as part of the
/// codegen attrs for a defined function. For function pointers this set of
/// flags is the empty set. This is only applicable for Rust-defined
/// functions, and generally isn't needed except for small optimizations where
/// we try to say a function which otherwise might look like it could unwind
/// doesn't actually unwind (such as for intrinsics and such).
/// * `fn_def_id` - the `DefId` of the function. If this is provided then we can
/// determine more precisely if the function can unwind. If this is not provided
/// then we will only infer whether the function can unwind or not based on the
/// ABI of the function. For example, a function marked with `#[rustc_nounwind]`
/// is known to not unwind even if it's using Rust ABI.
///
/// * `abi` - this is the ABI that the function is defined with. This is the
/// primary factor for determining whether a function can unwind or not.
@ -1147,11 +1146,6 @@ where
/// aborts the process.
/// * This affects whether functions have the LLVM `nounwind` attribute, which
/// affects various optimizations and codegen.
///
/// FIXME: this is actually buggy with respect to Rust functions. Rust functions
/// compiled with `-Cpanic=unwind` and referenced from another crate compiled
/// with `-Cpanic=abort` will look like they can't unwind when in fact they
/// might (from a foreign exception or similar).
#[inline]
#[tracing::instrument(level = "debug", skip(tcx))]
pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {

View file

@ -332,7 +332,7 @@ TrivialTypeTraversalAndLiftImpls! {
crate::ty::IntVarValue,
crate::ty::ParamConst,
crate::ty::ParamTy,
crate::ty::adjustment::PointerCast,
crate::ty::adjustment::PointerCoercion,
crate::ty::RegionVid,
crate::ty::UniverseIndex,
crate::ty::Variance,

View file

@ -535,7 +535,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::Cast { .. }
| ExprKind::Use { .. }
| ExprKind::NeverToAny { .. }
| ExprKind::Pointer { .. }
| ExprKind::PointerCoercion { .. }
| ExprKind::Repeat { .. }
| ExprKind::Borrow { .. }
| ExprKind::AddressOf { .. }

View file

@ -300,7 +300,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let cast_kind = mir_cast_kind(ty, expr.ty);
block.and(Rvalue::Cast(cast_kind, source, expr.ty))
}
ExprKind::Pointer { cast, source } => {
ExprKind::PointerCoercion { cast, source } => {
let source = unpack!(
block = this.as_operand(
block,
@ -310,7 +310,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
NeedsTemporary::No
)
);
block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
block.and(Rvalue::Cast(CastKind::PointerCoercion(cast), source, expr.ty))
}
ExprKind::Array { ref fields } => {
// (*) We would (maybe) be closer to codegen if we

View file

@ -63,7 +63,7 @@ impl Category {
| ExprKind::Binary { .. }
| ExprKind::Box { .. }
| ExprKind::Cast { .. }
| ExprKind::Pointer { .. }
| ExprKind::PointerCoercion { .. }
| ExprKind::Repeat { .. }
| ExprKind::Assign { .. }
| ExprKind::AssignOp { .. }

View file

@ -556,7 +556,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::Binary { .. }
| ExprKind::Box { .. }
| ExprKind::Cast { .. }
| ExprKind::Pointer { .. }
| ExprKind::PointerCoercion { .. }
| ExprKind::Repeat { .. }
| ExprKind::Array { .. }
| ExprKind::Tuple { .. }

View file

@ -16,7 +16,7 @@ use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::GenericArg;
use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
@ -423,7 +423,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
source_info,
temp,
Rvalue::Cast(
CastKind::Pointer(PointerCast::Unsize),
CastKind::PointerCoercion(PointerCoercion::Unsize),
Operand::Copy(val),
ty,
),
@ -436,7 +436,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
source_info,
slice,
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), expect, ty),
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::Unsize),
expect,
ty,
),
);
expect = Operand::Move(slice);
}

View file

@ -303,7 +303,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
| ExprKind::NeverToAny { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. }
| ExprKind::Pointer { .. }
| ExprKind::PointerCoercion { .. }
| ExprKind::Repeat { .. }
| ExprKind::StaticRef { .. }
| ExprKind::ThreadLocalRef { .. }

View file

@ -13,7 +13,7 @@ use rustc_middle::middle::region;
use rustc_middle::mir::{self, BinOp, BorrowKind, UnOp};
use rustc_middle::thir::*;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCoercion,
};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{
@ -125,11 +125,16 @@ impl<'tcx> Cx<'tcx> {
};
let kind = match adjustment.kind {
Adjust::Pointer(PointerCast::Unsize) => {
Adjust::Pointer(PointerCoercion::Unsize) => {
adjust_span(&mut expr);
ExprKind::Pointer { cast: PointerCast::Unsize, source: self.thir.exprs.push(expr) }
ExprKind::PointerCoercion {
cast: PointerCoercion::Unsize,
source: self.thir.exprs.push(expr),
}
}
Adjust::Pointer(cast) => {
ExprKind::PointerCoercion { cast, source: self.thir.exprs.push(expr) }
}
Adjust::Pointer(cast) => ExprKind::Pointer { cast, source: self.thir.exprs.push(expr) },
Adjust::NeverToAny if adjustment.target.is_never() => return expr,
Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
Adjust::Deref(None) => {
@ -192,9 +197,9 @@ impl<'tcx> Cx<'tcx> {
// Special cased so that we can type check that the element
// type of the source matches the pointed to type of the
// destination.
ExprKind::Pointer {
ExprKind::PointerCoercion {
source: self.mirror_expr(source),
cast: PointerCast::ArrayToPointer,
cast: PointerCoercion::ArrayToPointer,
}
} else {
// check whether this is casting an enum variant discriminant
@ -210,17 +215,18 @@ impl<'tcx> Cx<'tcx> {
// so we wouldn't have to compute and store the actual value
let hir::ExprKind::Path(ref qpath) = source.kind else {
return ExprKind::Cast { source: self.mirror_expr(source)};
return ExprKind::Cast { source: self.mirror_expr(source) };
};
let res = self.typeck_results().qpath_res(qpath, source.hir_id);
let ty = self.typeck_results().node_type(source.hir_id);
let ty::Adt(adt_def, substs) = ty.kind() else {
return ExprKind::Cast { source: self.mirror_expr(source)};
return ExprKind::Cast { source: self.mirror_expr(source) };
};
let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res else {
return ExprKind::Cast { source: self.mirror_expr(source)};
let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
else {
return ExprKind::Cast { source: self.mirror_expr(source) };
};
let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
@ -353,19 +359,35 @@ impl<'tcx> Cx<'tcx> {
});
}
}
let adt_data =
if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = fun.kind {
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
expr_ty.ty_adt_def().and_then(|adt_def| match path.res {
Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
&& let Some(adt_def) = expr_ty.ty_adt_def() {
match qpath {
hir::QPath::Resolved(_, ref path) => {
match path.res {
Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
}
Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
_ => None,
}
Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
_ => None,
})
} else {
None
};
}
hir::QPath::TypeRelative(_ty, _) => {
if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
self.typeck_results().type_dependent_def(fun.hir_id)
{
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
} else {
None
}
}
_ => None,
}
} else {
None
};
if let Some((adt_def, index)) = adt_data {
let substs = self.typeck_results().node_substs(fun.hir_id);
let user_provided_types = self.typeck_results().user_provided_types();

View file

@ -301,7 +301,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Pointer { cast, source } => {
PointerCoercion { cast, source } => {
print_indented!(self, "Pointer {", depth_lvl);
print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1);
print_indented!(self, "source:", depth_lvl + 1);

View file

@ -41,7 +41,7 @@ fn compute_slice_length<'tcx>(
for (local, rvalue, _) in ssa.assignments(body) {
match rvalue {
Rvalue::Cast(
CastKind::Pointer(ty::adjustment::PointerCast::Unsize),
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize),
operand,
cast_ty,
) => {

View file

@ -176,7 +176,7 @@ use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
use rustc_middle::mir::visit::Visitor as MirVisitor;
use rustc_middle::mir::{self, Local, Location};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{
@ -231,8 +231,8 @@ impl<'tcx> UsageMap<'tcx> {
assert!(self.used_map.insert(user_item, used_items).is_none());
}
pub fn get_user_items(&self, item: MonoItem<'tcx>) -> Option<&[MonoItem<'tcx>]> {
self.user_map.get(&item).map(|items| items.as_slice())
pub fn get_user_items(&self, item: MonoItem<'tcx>) -> &[MonoItem<'tcx>] {
self.user_map.get(&item).map(|items| items.as_slice()).unwrap_or(&[])
}
/// Internally iterate over all inlined items used by `item`.
@ -617,7 +617,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
// have to instantiate all methods of the trait being cast to, so we
// can build the appropriate vtable.
mir::Rvalue::Cast(
mir::CastKind::Pointer(PointerCast::Unsize),
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
ref operand,
target_ty,
)
@ -643,7 +643,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
}
}
mir::Rvalue::Cast(
mir::CastKind::Pointer(PointerCast::ReifyFnPointer),
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
ref operand,
_,
) => {
@ -652,7 +652,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
visit_fn_use(self.tcx, fn_ty, false, span, &mut self.output);
}
mir::Rvalue::Cast(
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)),
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
ref operand,
_,
) => {

View file

@ -427,9 +427,9 @@ fn merge_codegen_units<'tcx>(
// zero-padded suffixes, which means they are automatically sorted by
// names. The numeric suffix width depends on the number of CGUs, which
// is always greater than zero:
// - [1,9] CGUS: `0`, `1`, `2`, ...
// - [10,99] CGUS: `00`, `01`, `02`, ...
// - [100,999] CGUS: `000`, `001`, `002`, ...
// - [1,9] CGUs: `0`, `1`, `2`, ...
// - [10,99] CGUs: `00`, `01`, `02`, ...
// - [100,999] CGUs: `000`, `001`, `002`, ...
// - etc.
//
// If we didn't zero-pad the sorted-by-name order would be `XYZ-cgu.0`,
@ -458,7 +458,7 @@ fn internalize_symbols<'tcx>(
/// used to keep track of that.
#[derive(Clone, PartialEq, Eq, Debug)]
enum MonoItemPlacement {
SingleCgu { cgu_name: Symbol },
SingleCgu(Symbol),
MultipleCgus,
}
@ -466,7 +466,7 @@ fn internalize_symbols<'tcx>(
let single_codegen_unit = codegen_units.len() == 1;
if !single_codegen_unit {
for cgu in codegen_units.iter_mut() {
for cgu in codegen_units.iter() {
for item in cgu.items().keys() {
// If there is more than one codegen unit, we need to keep track
// in which codegen units each monomorphization is placed.
@ -474,13 +474,13 @@ fn internalize_symbols<'tcx>(
Entry::Occupied(e) => {
let placement = e.into_mut();
debug_assert!(match *placement {
MonoItemPlacement::SingleCgu { cgu_name } => cgu_name != cgu.name(),
MonoItemPlacement::SingleCgu(cgu_name) => cgu_name != cgu.name(),
MonoItemPlacement::MultipleCgus => true,
});
*placement = MonoItemPlacement::MultipleCgus;
}
Entry::Vacant(e) => {
e.insert(MonoItemPlacement::SingleCgu { cgu_name: cgu.name() });
e.insert(MonoItemPlacement::SingleCgu(cgu.name()));
}
}
}
@ -490,7 +490,7 @@ fn internalize_symbols<'tcx>(
// For each internalization candidates in each codegen unit, check if it is
// used from outside its defining codegen unit.
for cgu in codegen_units {
let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
let home_cgu = MonoItemPlacement::SingleCgu(cgu.name());
for (item, linkage_and_visibility) in cgu.items_mut() {
if !internalization_candidates.contains(item) {
@ -501,20 +501,20 @@ fn internalize_symbols<'tcx>(
if !single_codegen_unit {
debug_assert_eq!(mono_item_placements[item], home_cgu);
if let Some(user_items) = cx.usage_map.get_user_items(*item) {
if user_items
.iter()
.filter_map(|user_item| {
// Some user mono items might not have been
// instantiated. We can safely ignore those.
mono_item_placements.get(user_item)
})
.any(|placement| *placement != home_cgu)
{
// Found a user from another CGU, so skip to the next item
// without marking this one as internal.
continue;
}
if cx
.usage_map
.get_user_items(*item)
.iter()
.filter_map(|user_item| {
// Some user mono items might not have been
// instantiated. We can safely ignore those.
mono_item_placements.get(user_item)
})
.any(|placement| *placement != home_cgu)
{
// Found a user from another CGU, so skip to the next item
// without marking this one as internal.
continue;
}
}

View file

@ -2524,6 +2524,8 @@ pub fn build_session_options(
let error_format = parse_error_format(handler, matches, color, json_rendered);
handler.abort_if_error_and_set_error_format(error_format);
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
handler.early_error("`--diagnostic-width` must be an positive integer");
});

View file

@ -7,7 +7,8 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
use crate::stable_mir::{self, ty::TyKind, Context};
use crate::stable_mir::ty::{FloatTy, IntTy, RigidTy, TyKind, UintTy};
use crate::stable_mir::{self, Context};
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
@ -69,11 +70,28 @@ pub struct Tables<'tcx> {
impl<'tcx> Tables<'tcx> {
fn rustc_ty_to_ty(&mut self, ty: Ty<'tcx>) -> TyKind {
match ty.kind() {
ty::Bool => TyKind::Bool,
ty::Char => todo!(),
ty::Int(_) => todo!(),
ty::Uint(_) => todo!(),
ty::Float(_) => todo!(),
ty::Bool => TyKind::RigidTy(RigidTy::Bool),
ty::Char => TyKind::RigidTy(RigidTy::Char),
ty::Int(int_ty) => match int_ty {
ty::IntTy::Isize => TyKind::RigidTy(RigidTy::Int(IntTy::Isize)),
ty::IntTy::I8 => TyKind::RigidTy(RigidTy::Int(IntTy::I8)),
ty::IntTy::I16 => TyKind::RigidTy(RigidTy::Int(IntTy::I16)),
ty::IntTy::I32 => TyKind::RigidTy(RigidTy::Int(IntTy::I32)),
ty::IntTy::I64 => TyKind::RigidTy(RigidTy::Int(IntTy::I64)),
ty::IntTy::I128 => TyKind::RigidTy(RigidTy::Int(IntTy::I128)),
},
ty::Uint(uint_ty) => match uint_ty {
ty::UintTy::Usize => TyKind::RigidTy(RigidTy::Uint(UintTy::Usize)),
ty::UintTy::U8 => TyKind::RigidTy(RigidTy::Uint(UintTy::U8)),
ty::UintTy::U16 => TyKind::RigidTy(RigidTy::Uint(UintTy::U16)),
ty::UintTy::U32 => TyKind::RigidTy(RigidTy::Uint(UintTy::U32)),
ty::UintTy::U64 => TyKind::RigidTy(RigidTy::Uint(UintTy::U64)),
ty::UintTy::U128 => TyKind::RigidTy(RigidTy::Uint(UintTy::U128)),
},
ty::Float(float_ty) => match float_ty {
ty::FloatTy::F32 => TyKind::RigidTy(RigidTy::Float(FloatTy::F32)),
ty::FloatTy::F64 => TyKind::RigidTy(RigidTy::Float(FloatTy::F64)),
},
ty::Adt(_, _) => todo!(),
ty::Foreign(_) => todo!(),
ty::Str => todo!(),
@ -90,9 +108,9 @@ impl<'tcx> Tables<'tcx> {
ty::GeneratorWitness(_) => todo!(),
ty::GeneratorWitnessMIR(_, _) => todo!(),
ty::Never => todo!(),
ty::Tuple(fields) => {
TyKind::Tuple(fields.iter().map(|ty| self.intern_ty(ty)).collect())
}
ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple(
fields.iter().map(|ty| self.intern_ty(ty)).collect(),
)),
ty::Alias(_, _) => todo!(),
ty::Param(_) => todo!(),
ty::Bound(_, _) => todo!(),

View file

@ -9,7 +9,43 @@ impl Ty {
}
}
#[derive(Clone, Debug)]
pub enum TyKind {
RigidTy(RigidTy),
}
#[derive(Clone, Debug)]
pub enum RigidTy {
Bool,
Char,
Int(IntTy),
Uint(UintTy),
Float(FloatTy),
Tuple(Vec<Ty>),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum IntTy {
Isize,
I8,
I16,
I32,
I64,
I128,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum UintTy {
Usize,
U8,
U16,
U32,
U64,
U128,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FloatTy {
F32,
F64,
}

View file

@ -759,7 +759,6 @@ symbols! {
from_desugaring,
from_fn,
from_iter,
from_method,
from_output,
from_residual,
from_size_align_unchecked,

View file

@ -167,9 +167,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
// We don't normalize opaque types unless we have
// `Reveal::All`, even if we're in the defining scope.
let data = match *ty.kind() {
ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::UserFacing => {
alias_ty
}
ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::All => alias_ty,
_ => return ty.try_super_fold_with(self),
};

View file

@ -12,7 +12,6 @@ use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::{self, InferCtxt};
use crate::solve::{GenerateProofTree, InferCtxtEvalExt, UseGlobalCache};
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::query::normalize::QueryNormalizeExt as _;
use crate::traits::specialize::to_pretty_impl_header;
use crate::traits::NormalizeExt;
use on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _};
@ -33,7 +32,7 @@ use rustc_middle::traits::solve::Goal;
use rustc_middle::traits::{DefiningAnchor, SelectionOutputTypeParameterMismatch};
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
use rustc_middle::ty::{
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
@ -63,7 +62,7 @@ pub enum CandidateSimilarity {
Fuzzy { ignoring_lifetimes: bool },
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ImplCandidate<'tcx> {
pub trait_ref: ty::TraitRef<'tcx>,
pub similarity: CandidateSimilarity,
@ -1941,10 +1940,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
other: bool,
) -> bool {
let other = if other { "other " } else { "" };
let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
candidates.sort();
candidates.dedup();
let len = candidates.len();
let report = |candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
if candidates.is_empty() {
return false;
}
@ -1973,11 +1969,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
candidates.iter().map(|c| c.print_only_trait_path().to_string()).collect();
traits.sort();
traits.dedup();
// FIXME: this could use a better heuristic, like just checking
// that substs[1..] is the same.
let all_traits_equal = traits.len() == 1;
let mut candidates: Vec<String> = candidates
let candidates: Vec<String> = candidates
.into_iter()
.map(|c| {
if traits.len() == 1 {
if all_traits_equal {
format!("\n {}", c.self_ty())
} else {
format!("\n {}", c)
@ -1985,14 +1984,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
})
.collect();
candidates.sort();
candidates.dedup();
let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
err.help(format!(
"the following {other}types implement trait `{}`:{}{}",
trait_ref.print_only_trait_path(),
candidates[..end].join(""),
if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
if candidates.len() > 9 {
format!("\nand {} others", candidates.len() - 8)
} else {
String::new()
}
));
true
};
@ -2006,7 +2007,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Mentioning implementers of `Copy`, `Debug` and friends is not useful.
return false;
}
let normalized_impl_candidates: Vec<_> = self
let mut impl_candidates: Vec<_> = self
.tcx
.all_impls(def_id)
// Ignore automatically derived impls and `!Trait` impls.
@ -2033,7 +2034,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
})
.collect();
return report(normalized_impl_candidates, err);
impl_candidates.sort();
impl_candidates.dedup();
return report(impl_candidates, err);
}
// Sort impl candidates so that ordering is consistent for UI tests.
@ -2042,27 +2046,25 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
//
// Prefer more similar candidates first, then sort lexicographically
// by their normalized string representation.
let mut normalized_impl_candidates_and_similarities = impl_candidates
let mut impl_candidates: Vec<_> = impl_candidates
.iter()
.copied()
.map(|ImplCandidate { trait_ref, similarity }| {
// FIXME(compiler-errors): This should be using `NormalizeExt::normalize`
let normalized = self
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
.query_normalize(trait_ref)
.map_or(trait_ref, |normalized| normalized.value);
(similarity, normalized)
.cloned()
.map(|mut cand| {
// Fold the consts so that they shows up as, e.g., `10`
// instead of `core::::array::{impl#30}::{constant#0}`.
cand.trait_ref = cand.trait_ref.fold_with(&mut BottomUpFolder {
tcx: self.tcx,
ty_op: |ty| ty,
lt_op: |lt| lt,
ct_op: |ct| ct.eval(self.tcx, ty::ParamEnv::empty()),
});
cand
})
.collect::<Vec<_>>();
normalized_impl_candidates_and_similarities.sort();
normalized_impl_candidates_and_similarities.dedup();
.collect();
impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref));
impl_candidates.dedup();
let normalized_impl_candidates = normalized_impl_candidates_and_similarities
.into_iter()
.map(|(_, normalized)| normalized)
.collect::<Vec<_>>();
report(normalized_impl_candidates, err)
report(impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(), err)
}
fn report_similar_impl_candidates_for_root_obligation(

View file

@ -41,7 +41,6 @@ pub trait TypeErrCtxtExt<'tcx> {
static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
kw::SelfUpper,
sym::ItemContext,
sym::from_method,
sym::from_desugaring,
sym::direct,
sym::cause,
@ -172,23 +171,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}
if let ObligationCauseCode::ItemObligation(item)
| ObligationCauseCode::BindingObligation(item, _)
| ObligationCauseCode::ExprItemObligation(item, ..)
| ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code()
{
// FIXME: maybe also have some way of handling methods
// from other traits? That would require name resolution,
// which we might want to be some sort of hygienic.
//
// Currently I'm leaving it for what I need for `try`.
if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
let method = self.tcx.item_name(item);
flags.push((sym::from_method, None));
flags.push((sym::from_method, Some(method.to_string())));
}
}
if let Some(k) = obligation.cause.span.desugaring_kind() {
flags.push((sym::from_desugaring, None));
flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
@ -672,7 +654,7 @@ impl<'tcx> OnUnimplementedFormatString {
None => {
if let Some(val) = options.get(&s) {
val
} else if s == sym::from_desugaring || s == sym::from_method {
} else if s == sym::from_desugaring {
// don't break messages using these two arguments incorrectly
&empty_string
} else if s == sym::ItemContext {

View file

@ -221,7 +221,7 @@ fn recurse_build<'tcx>(
maybe_supported_error(GenericConstantTooComplexSub::AdtNotSupported(node.span))?
}
// dont know if this is correct
ExprKind::Pointer { .. } => {
ExprKind::PointerCoercion { .. } => {
error(GenericConstantTooComplexSub::PointerNotSupported(node.span))?
}
ExprKind::Yield { .. } => {
@ -324,7 +324,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
| thir::ExprKind::Cast { .. }
| thir::ExprKind::Use { .. }
| thir::ExprKind::NeverToAny { .. }
| thir::ExprKind::Pointer { .. }
| thir::ExprKind::PointerCoercion { .. }
| thir::ExprKind::Loop { .. }
| thir::ExprKind::Let { .. }
| thir::ExprKind::Match { .. }

View file

@ -400,10 +400,20 @@ changelog-seen = 2
# =============================================================================
[rust]
# Whether or not to optimize the compiler and standard library.
# Whether or not to optimize when compiling the compiler and standard library,
# and what level of optimization to use.
# WARNING: Building with optimize = false is NOT SUPPORTED. Due to bootstrapping,
# building without optimizations takes much longer than optimizing. Further, some platforms
# fail to build without this optimization (c.f. #65352).
# The valid options are:
# true - Enable optimizations.
# false - Disable optimizations.
# 0 - Disable optimizations.
# 1 - Basic optimizations.
# 2 - Some optimizations.
# 3 - All optimizations.
# "s" - Optimize for binary size.
# "z" - Optimize for binary size, but also turn off loop vectorization.
#optimize = true
# Indicates that the build should be configured for debugging Rust. A
@ -757,7 +767,7 @@ changelog-seen = 2
# This option will override the same option under [build] section.
#profiler = build.profiler (bool)
# This option supports enable `rpath` in each target independently,
# This option supports enable `rpath` in each target independently,
# and will override the same option under [rust] section. It only works on Unix platforms
#rpath = rust.rpath (bool)

View file

@ -133,51 +133,6 @@ pub trait Default: Sized {
fn default() -> Self;
}
/// Return the default value of a type according to the `Default` trait.
///
/// The type to return is inferred from context; this is equivalent to
/// `Default::default()` but shorter to type.
///
/// For example:
/// ```
/// #![feature(default_free_fn)]
///
/// use std::default::default;
///
/// #[derive(Default)]
/// struct AppConfig {
/// foo: FooConfig,
/// bar: BarConfig,
/// }
///
/// #[derive(Default)]
/// struct FooConfig {
/// foo: i32,
/// }
///
/// #[derive(Default)]
/// struct BarConfig {
/// bar: f32,
/// baz: u8,
/// }
///
/// fn main() {
/// let options = AppConfig {
/// foo: default(),
/// bar: BarConfig {
/// bar: 10.1,
/// ..default()
/// },
/// };
/// }
/// ```
#[unstable(feature = "default_free_fn", issue = "73014")]
#[must_use]
#[inline]
pub fn default<T: Default>() -> T {
Default::default()
}
/// Derive macro generating an impl of the trait `Default`.
#[rustc_builtin_macro(Default, attributes(default))]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]

View file

@ -851,6 +851,8 @@ impl<T> [T] {
/// Swaps two elements in the slice.
///
/// If `a` equals to `b`, it's guaranteed that elements won't change value.
///
/// # Arguments
///
/// * a - The index of the first element

View file

@ -500,10 +500,7 @@ impl f32 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log2(self) -> f32 {
#[cfg(target_os = "android")]
return crate::sys::android::log2f32(self);
#[cfg(not(target_os = "android"))]
return unsafe { intrinsics::log2f32(self) };
crate::sys::log2f32(self)
}
/// Returns the base 10 logarithm of the number.

View file

@ -456,7 +456,7 @@ impl f64 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn ln(self) -> f64 {
self.log_wrapper(|n| unsafe { intrinsics::logf64(n) })
crate::sys::log_wrapper(self, |n| unsafe { intrinsics::logf64(n) })
}
/// Returns the logarithm of the number with respect to an arbitrary base.
@ -500,12 +500,7 @@ impl f64 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log2(self) -> f64 {
self.log_wrapper(|n| {
#[cfg(target_os = "android")]
return crate::sys::android::log2f64(n);
#[cfg(not(target_os = "android"))]
return unsafe { intrinsics::log2f64(n) };
})
crate::sys::log_wrapper(self, crate::sys::log2f64)
}
/// Returns the base 10 logarithm of the number.
@ -525,7 +520,7 @@ impl f64 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log10(self) -> f64 {
self.log_wrapper(|n| unsafe { intrinsics::log10f64(n) })
crate::sys::log_wrapper(self, |n| unsafe { intrinsics::log10f64(n) })
}
/// The positive difference of two numbers.
@ -962,28 +957,4 @@ impl f64 {
pub fn atanh(self) -> f64 {
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
}
// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
// because of their non-standard behavior (e.g., log(-n) returns -Inf instead
// of expected NaN).
#[rustc_allow_incoherent_impl]
fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
if !cfg!(any(target_os = "solaris", target_os = "illumos")) {
log_fn(self)
} else if self.is_finite() {
if self > 0.0 {
log_fn(self)
} else if self == 0.0 {
Self::NEG_INFINITY // log(0) = -Inf
} else {
Self::NAN // log(-n) = NaN
}
} else if self.is_nan() {
self // log(NaN) = NaN
} else if self > 0.0 {
self // log(Inf) = Inf
} else {
Self::NAN // log(-Inf) = NaN
}
}
}

View file

@ -1,4 +1,8 @@
use super::{BorrowedBuf, BufReader, BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE};
use crate::alloc::Allocator;
use crate::cmp;
use crate::collections::VecDeque;
use crate::io::IoSlice;
use crate::mem::MaybeUninit;
#[cfg(test)]
@ -86,7 +90,7 @@ where
/// Specialization of the read-write loop that reuses the internal
/// buffer of a BufReader. If there's no buffer then the writer side
/// should be used intead.
/// should be used instead.
trait BufferedReaderSpec {
fn buffer_size(&self) -> usize;
@ -104,7 +108,39 @@ where
}
default fn copy_to(&mut self, _to: &mut (impl Write + ?Sized)) -> Result<u64> {
unimplemented!("only called from specializations");
unreachable!("only called from specializations")
}
}
impl BufferedReaderSpec for &[u8] {
fn buffer_size(&self) -> usize {
// prefer this specialization since the source "buffer" is all we'll ever need,
// even if it's small
usize::MAX
}
fn copy_to(&mut self, to: &mut (impl Write + ?Sized)) -> Result<u64> {
let len = self.len();
to.write_all(self)?;
*self = &self[len..];
Ok(len as u64)
}
}
impl<A: Allocator> BufferedReaderSpec for VecDeque<u8, A> {
fn buffer_size(&self) -> usize {
// prefer this specialization since the source "buffer" is all we'll ever need,
// even if it's small
usize::MAX
}
fn copy_to(&mut self, to: &mut (impl Write + ?Sized)) -> Result<u64> {
let len = self.len();
let (front, back) = self.as_slices();
let bufs = &mut [IoSlice::new(front), IoSlice::new(back)];
to.write_all_vectored(bufs)?;
self.clear();
Ok(len as u64)
}
}
@ -218,6 +254,47 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
}
}
impl<A: Allocator> BufferedWriterSpec for Vec<u8, A> {
fn buffer_size(&self) -> usize {
cmp::max(DEFAULT_BUF_SIZE, self.capacity() - self.len())
}
fn copy_from<R: Read + ?Sized>(&mut self, reader: &mut R) -> Result<u64> {
let mut bytes = 0;
// avoid allocating before we have determined that there's anything to read
if self.capacity() == 0 {
bytes = stack_buffer_copy(&mut reader.take(DEFAULT_BUF_SIZE as u64), self)?;
if bytes == 0 {
return Ok(0);
}
}
loop {
self.reserve(DEFAULT_BUF_SIZE);
let mut buf: BorrowedBuf<'_> = self.spare_capacity_mut().into();
match reader.read_buf(buf.unfilled()) {
Ok(()) => {}
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
let read = buf.filled().len();
if read == 0 {
break;
}
// SAFETY: BorrowedBuf guarantees all of its filled bytes are init
// and the number of read bytes can't exceed the spare capacity since
// that's what the buffer is borrowing from.
unsafe { self.set_len(self.len() + read) };
bytes += read as u64;
}
Ok(bytes)
}
}
fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
reader: &mut R,
writer: &mut W,

View file

@ -1,4 +1,6 @@
use crate::cmp::{max, min};
use crate::collections::VecDeque;
use crate::io;
use crate::io::*;
#[test]
@ -19,7 +21,7 @@ struct ShortReader {
impl Read for ShortReader {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let bytes = min(self.cap, self.read_size);
let bytes = min(self.cap, self.read_size).min(buf.len());
self.cap -= bytes;
self.observed_buffer = max(self.observed_buffer, buf.len());
Ok(bytes)
@ -78,6 +80,40 @@ fn copy_specializes_bufreader() {
);
}
#[test]
fn copy_specializes_to_vec() {
let cap = 123456;
let mut source = ShortReader { cap, observed_buffer: 0, read_size: 1337 };
let mut sink = Vec::new();
assert_eq!(cap as u64, io::copy(&mut source, &mut sink).unwrap());
assert!(
source.observed_buffer > DEFAULT_BUF_SIZE,
"expected a large buffer to be provided to the reader"
);
}
#[test]
fn copy_specializes_from_vecdeque() {
let mut source = VecDeque::with_capacity(100 * 1024);
for _ in 0..20 * 1024 {
source.push_front(0);
}
for _ in 0..20 * 1024 {
source.push_back(0);
}
let mut sink = WriteObserver { observed_buffer: 0 };
assert_eq!(40 * 1024u64, io::copy(&mut source, &mut sink).unwrap());
assert_eq!(20 * 1024, sink.observed_buffer);
}
#[test]
fn copy_specializes_from_slice() {
let mut source = [1; 60 * 1024].as_slice();
let mut sink = WriteObserver { observed_buffer: 0 };
assert_eq!(60 * 1024u64, io::copy(&mut source, &mut sink).unwrap());
assert_eq!(60 * 1024, sink.observed_buffer);
}
#[cfg(unix)]
mod io_benches {
use crate::fs::File;

View file

@ -603,7 +603,6 @@ pub mod alloc;
// Private support modules
mod panicking;
mod personality;
#[path = "../../backtrace/src/lib.rs"]
#[allow(dead_code, unused_attributes, fuzzy_provenance_casts)]

View file

@ -23,6 +23,7 @@
#![allow(missing_debug_implementations)]
pub mod common;
mod personality;
cfg_if::cfg_if! {
if #[cfg(unix)] {
@ -60,3 +61,52 @@ cfg_if::cfg_if! {
pub const FULL_BACKTRACE_DEFAULT: bool = false;
}
}
#[cfg(not(test))]
cfg_if::cfg_if! {
if #[cfg(target_os = "android")] {
pub use self::android::log2f32;
pub use self::android::log2f64;
} else {
#[inline]
pub fn log2f32(n: f32) -> f32 {
unsafe { crate::intrinsics::log2f32(n) }
}
#[inline]
pub fn log2f64(n: f64) -> f64 {
unsafe { crate::intrinsics::log2f64(n) }
}
}
}
// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
// because of their non-standard behavior (e.g., log(-n) returns -Inf instead
// of expected NaN).
#[cfg(not(test))]
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
#[inline]
pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
if n.is_finite() {
if n > 0.0 {
log_fn(n)
} else if n == 0.0 {
f64::NEG_INFINITY // log(0) = -Inf
} else {
f64::NAN // log(-n) = NaN
}
} else if n.is_nan() {
n // log(NaN) = NaN
} else if n > 0.0 {
n // log(Inf) = Inf
} else {
f64::NAN // log(-Inf) = NaN
}
}
#[cfg(not(test))]
#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
#[inline]
pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
log_fn(n)
}

View file

@ -85,6 +85,10 @@ dependencies = [
[[package]]
name = "build_helper"
version = "0.1.0"
dependencies = [
"serde",
"serde_derive",
]
[[package]]
name = "cc"

View file

@ -665,6 +665,7 @@ impl<'a> Builder<'a> {
llvm::Lld,
llvm::CrtBeginEnd,
tool::RustdocGUITest,
tool::OptimizedDist
),
Kind::Check | Kind::Clippy | Kind::Fix => describe!(
check::Std,

View file

@ -508,6 +508,49 @@ impl Step for StdLink {
};
add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
// Special case for stage0, to make `rustup toolchain link` and `x dist --stage 0`
// work for stage0-sysroot. We only do this if the stage0 compiler comes from beta,
// and is not set to a custom path.
if compiler.stage == 0
&& builder
.build
.config
.initial_rustc
.starts_with(builder.out.join(&compiler.host.triple).join("stage0/bin"))
{
// Copy bin files from stage0/bin to stage0-sysroot/bin
let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot");
let host = compiler.host.triple;
let stage0_bin_dir = builder.out.join(&host).join("stage0/bin");
let sysroot_bin_dir = sysroot.join("bin");
t!(fs::create_dir_all(&sysroot_bin_dir));
builder.cp_r(&stage0_bin_dir, &sysroot_bin_dir);
// Copy all *.so files from stage0/lib to stage0-sysroot/lib
let stage0_lib_dir = builder.out.join(&host).join("stage0/lib");
if let Ok(files) = fs::read_dir(&stage0_lib_dir) {
for file in files {
let file = t!(file);
let path = file.path();
if path.is_file() && is_dylib(&file.file_name().into_string().unwrap()) {
builder.copy(&path, &sysroot.join("lib").join(path.file_name().unwrap()));
}
}
}
// Copy codegen-backends from stage0
let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler);
t!(fs::create_dir_all(&sysroot_codegen_backends));
let stage0_codegen_backends = builder
.out
.join(&host)
.join("stage0/lib/rustlib")
.join(&host)
.join("codegen-backends");
builder.cp_r(&stage0_codegen_backends, &sysroot_codegen_backends);
}
}
}

View file

@ -875,11 +875,10 @@ impl Default for StringOrBool {
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RustOptimize {
#[serde(deserialize_with = "deserialize_and_validate_opt_level")]
String(String),
Int(u8),
Bool(bool),
}
@ -889,26 +888,74 @@ impl Default for RustOptimize {
}
}
fn deserialize_and_validate_opt_level<'de, D>(d: D) -> Result<String, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let v = String::deserialize(d)?;
if ["0", "1", "2", "3", "s", "z"].iter().find(|x| **x == v).is_some() {
Ok(v)
} else {
Err(format!(r#"unrecognized option for rust optimize: "{}", expected one of "0", "1", "2", "3", "s", "z""#, v)).map_err(serde::de::Error::custom)
impl<'de> Deserialize<'de> for RustOptimize {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(OptimizeVisitor)
}
}
struct OptimizeVisitor;
impl<'de> serde::de::Visitor<'de> for OptimizeVisitor {
type Value = RustOptimize;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str(r#"one of: 0, 1, 2, 3, "s", "z", true, false"#)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
if ["s", "z"].iter().find(|x| **x == value).is_some() {
Ok(RustOptimize::String(value.to_string()))
} else {
Err(format_optimize_error_msg(value)).map_err(serde::de::Error::custom)
}
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
if matches!(value, 0..=3) {
Ok(RustOptimize::Int(value as u8))
} else {
Err(format_optimize_error_msg(value)).map_err(serde::de::Error::custom)
}
}
fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(RustOptimize::Bool(value))
}
}
fn format_optimize_error_msg(v: impl std::fmt::Display) -> String {
format!(
r#"unrecognized option for rust optimize: "{}", expected one of 0, 1, 2, 3, "s", "z", true, false"#,
v
)
}
impl RustOptimize {
pub(crate) fn is_release(&self) -> bool {
if let RustOptimize::Bool(true) | RustOptimize::String(_) = &self { true } else { false }
match &self {
RustOptimize::Bool(true) | RustOptimize::String(_) => true,
RustOptimize::Int(i) => *i > 0,
RustOptimize::Bool(false) => false,
}
}
pub(crate) fn get_opt_level(&self) -> Option<String> {
match &self {
RustOptimize::String(s) => Some(s.clone()),
RustOptimize::Int(i) => Some(i.to_string()),
RustOptimize::Bool(_) => None,
}
}

View file

@ -184,7 +184,10 @@ fn rust_optimize() {
assert_eq!(parse("").rust_optimize.is_release(), true);
assert_eq!(parse("rust.optimize = false").rust_optimize.is_release(), false);
assert_eq!(parse("rust.optimize = true").rust_optimize.is_release(), true);
assert_eq!(parse("rust.optimize = \"1\"").rust_optimize.get_opt_level(), Some("1".to_string()));
assert_eq!(parse("rust.optimize = 0").rust_optimize.is_release(), false);
assert_eq!(parse("rust.optimize = 1").rust_optimize.is_release(), true);
assert_eq!(parse("rust.optimize = 1").rust_optimize.get_opt_level(), Some("1".to_string()));
assert_eq!(parse("rust.optimize = \"s\"").rust_optimize.is_release(), true);
assert_eq!(parse("rust.optimize = \"s\"").rust_optimize.get_opt_level(), Some("s".to_string()));
}

View file

@ -1,4 +1,4 @@
Change this file to make users of the `download-ci-llvm` configuration download
a new version of LLVM from CI, even if the LLVM submodule hasnt changed.
Last change is for: https://github.com/rust-lang/rust/pull/96971
Last change is for: https://github.com/rust-lang/rust/pull/112931

View file

@ -352,7 +352,7 @@ impl Step for Llvm {
// Disable zstd to avoid a dependency on libzstd.so.
cfg.define("LLVM_ENABLE_ZSTD", "OFF");
if target != "aarch64-apple-darwin" && !target.contains("windows") {
if !target.contains("windows") {
cfg.define("LLVM_ENABLE_ZLIB", "ON");
} else {
cfg.define("LLVM_ENABLE_ZLIB", "OFF");

View file

@ -7,7 +7,10 @@
use crate::builder::{Builder, Step};
use crate::util::t;
use crate::Build;
use serde_derive::{Deserialize, Serialize};
use build_helper::metrics::{
JsonInvocation, JsonInvocationSystemStats, JsonNode, JsonRoot, JsonStepSystemStats, Test,
TestOutcome, TestSuite, TestSuiteMetadata,
};
use std::cell::RefCell;
use std::fs::File;
use std::io::BufWriter;
@ -241,98 +244,7 @@ struct StepMetrics {
test_suites: Vec<TestSuite>,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
struct JsonRoot {
#[serde(default)] // For version 0 the field was not present.
format_version: usize,
system_stats: JsonInvocationSystemStats,
invocations: Vec<JsonInvocation>,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
struct JsonInvocation {
// Unix timestamp in seconds
//
// This is necessary to easily correlate this invocation with logs or other data.
start_time: u64,
duration_including_children_sec: f64,
children: Vec<JsonNode>,
}
#[derive(Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
enum JsonNode {
RustbuildStep {
#[serde(rename = "type")]
type_: String,
debug_repr: String,
duration_excluding_children_sec: f64,
system_stats: JsonStepSystemStats,
children: Vec<JsonNode>,
},
TestSuite(TestSuite),
}
#[derive(Serialize, Deserialize)]
struct TestSuite {
metadata: TestSuiteMetadata,
tests: Vec<Test>,
}
#[derive(Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub(crate) enum TestSuiteMetadata {
CargoPackage {
crates: Vec<String>,
target: String,
host: String,
stage: u32,
},
Compiletest {
suite: String,
mode: String,
compare_mode: Option<String>,
target: String,
host: String,
stage: u32,
},
}
#[derive(Serialize, Deserialize)]
pub(crate) struct Test {
name: String,
#[serde(flatten)]
outcome: TestOutcome,
}
#[derive(Serialize, Deserialize)]
#[serde(tag = "outcome", rename_all = "snake_case")]
pub(crate) enum TestOutcome {
Passed,
Failed,
Ignored { ignore_reason: Option<String> },
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
struct JsonInvocationSystemStats {
cpu_threads_count: usize,
cpu_model: String,
memory_total_bytes: u64,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
struct JsonStepSystemStats {
cpu_utilization_percent: f64,
}
#[derive(Deserialize)]
#[derive(serde_derive::Deserialize)]
struct OnlyFormatVersion {
#[serde(default)] // For version 0 the field was not present.
format_version: usize,

View file

@ -141,9 +141,9 @@ impl<'a> Renderer<'a> {
self.builder.metrics.record_test(
&test.name,
match outcome {
Outcome::Ok | Outcome::BenchOk => crate::metrics::TestOutcome::Passed,
Outcome::Failed => crate::metrics::TestOutcome::Failed,
Outcome::Ignored { reason } => crate::metrics::TestOutcome::Ignored {
Outcome::Ok | Outcome::BenchOk => build_helper::metrics::TestOutcome::Passed,
Outcome::Failed => build_helper::metrics::TestOutcome::Failed,
Outcome::Ignored { reason } => build_helper::metrics::TestOutcome::Ignored {
ignore_reason: reason.map(|s| s.to_string()),
},
},

View file

@ -340,7 +340,7 @@ impl Step for Cargo {
#[cfg(feature = "build-metrics")]
builder.metrics.begin_test_suite(
crate::metrics::TestSuiteMetadata::CargoPackage {
build_helper::metrics::TestSuiteMetadata::CargoPackage {
crates: vec!["cargo".into()],
target: self.host.triple.to_string(),
host: self.host.triple.to_string(),
@ -799,6 +799,10 @@ impl Step for Clippy {
// The tests succeeded; nothing to do.
return;
}
if !builder.config.cmd.bless() {
crate::detail_exit_macro!(1);
}
}
}
@ -1823,7 +1827,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
#[cfg(feature = "build-metrics")]
builder.metrics.begin_test_suite(
crate::metrics::TestSuiteMetadata::Compiletest {
build_helper::metrics::TestSuiteMetadata::Compiletest {
suite: suite.into(),
mode: mode.into(),
compare_mode: None,
@ -1848,7 +1852,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
#[cfg(feature = "build-metrics")]
builder.metrics.begin_test_suite(
crate::metrics::TestSuiteMetadata::Compiletest {
build_helper::metrics::TestSuiteMetadata::Compiletest {
suite: suite.into(),
mode: mode.into(),
compare_mode: Some(compare_mode.into()),
@ -2196,7 +2200,7 @@ fn run_cargo_test(
#[cfg(feature = "build-metrics")]
builder.metrics.begin_test_suite(
crate::metrics::TestSuiteMetadata::CargoPackage {
build_helper::metrics::TestSuiteMetadata::CargoPackage {
crates: crates.iter().map(|c| c.to_string()).collect(),
target: target.triple.to_string(),
host: compiler.host.triple.to_string(),

View file

@ -303,6 +303,7 @@ bootstrap_tool!(
SuggestTests, "src/tools/suggest-tests", "suggest-tests";
GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys";
RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = "test";
OptimizedDist, "src/tools/opt-dist", "opt-dist";
);
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]

View file

@ -54,7 +54,8 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
RUN ./build-clang.sh
ENV CC=clang CXX=clang++
# rustc-perf version from 2023-03-15
# rustc-perf version from 2023-05-30
# Should also be changed in the opt-dist tool for other environments.
ENV PERF_COMMIT 8b2ac3042e1ff2c0074455a0a3618adef97156b1
RUN curl -LS -o perf.zip https://github.com/rust-lang/rustc-perf/archive/$PERF_COMMIT.zip && \
unzip perf.zip && \
@ -81,7 +82,9 @@ ENV RUST_CONFIGURE_ARGS \
--set rust.jemalloc \
--set rust.use-lld=true \
--set rust.lto=thin
ENV SCRIPT python3 ../src/ci/stage-build.py python3 ../x.py dist \
ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
./build/$HOSTS/stage0-tools-bin/opt-dist python3 ../x.py dist \
--host $HOSTS --target $HOSTS \
--include-default-paths \
build-manifest bootstrap

View file

@ -24,7 +24,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
qemu-system-x86 \
&& rm -rf /var/lib/apt/lists/*
RUN curl -sL https://nodejs.org/dist/v15.14.0/node-v15.14.0-linux-x64.tar.xz | \
RUN curl -sL https://nodejs.org/dist/v18.12.0/node-v18.12.0-linux-x64.tar.xz | \
tar -xJ
# Install 32-bit OVMF files for the i686-unknown-uefi test. This package
@ -42,7 +42,7 @@ RUN sh /scripts/sccache.sh
ENV RUST_CONFIGURE_ARGS \
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
--set build.nodejs=/node-v15.14.0-linux-x64/bin/node \
--set build.nodejs=/node-v18.12.0-linux-x64/bin/node \
--set rust.lld
# Some run-make tests have assertions about code size, and enabling debug
@ -58,6 +58,8 @@ ENV WASM_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $WASM_T
tests/ui \
tests/mir-opt \
tests/codegen-units \
tests/codegen \
tests/assembly \
library/core
ENV NVPTX_TARGETS=nvptx64-nvidia-cuda

View file

@ -302,7 +302,7 @@ concurrency:
# For a given workflow, if we push to the same branch, cancel all previous builds on that branch.
# We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which
# are all triggered on the same branch, but which should be able to run concurrently.
group: ${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}
group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}
cancel-in-progress: true
jobs:
@ -643,7 +643,7 @@ jobs:
--target=x86_64-pc-windows-msvc
--enable-full-tools
--enable-profiler
SCRIPT: PGO_HOST=x86_64-pc-windows-msvc python src/ci/stage-build.py python x.py dist bootstrap --include-default-paths
SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist python x.py dist bootstrap --include-default-paths
DIST_REQUIRE_ALL_TOOLS: 1
<<: *job-windows-8c

File diff suppressed because it is too large Load diff

View file

@ -1,47 +0,0 @@
# `default_free_fn`
The tracking issue for this feature is: [#73014]
[#73014]: https://github.com/rust-lang/rust/issues/73014
------------------------
Adds a free `default()` function to the `std::default` module. This function
just forwards to [`Default::default()`], but may remove repetition of the word
"default" from the call site.
[`Default::default()`]: ../../std/default/trait.Default.html#tymethod.default
Here is an example:
```rust
#![feature(default_free_fn)]
use std::default::default;
#[derive(Default)]
struct AppConfig {
foo: FooConfig,
bar: BarConfig,
}
#[derive(Default)]
struct FooConfig {
foo: i32,
}
#[derive(Default)]
struct BarConfig {
bar: f32,
baz: u8,
}
fn main() {
let options = AppConfig {
foo: default(),
bar: BarConfig {
bar: 10.1,
..default()
},
};
}
```

View file

@ -6,3 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = "1"
serde_derive = "1"

View file

@ -1,3 +1,4 @@
pub mod ci;
pub mod git;
pub mod metrics;
pub mod util;

View file

@ -0,0 +1,92 @@
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct JsonRoot {
#[serde(default)] // For version 0 the field was not present.
pub format_version: usize,
pub system_stats: JsonInvocationSystemStats,
pub invocations: Vec<JsonInvocation>,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct JsonInvocation {
// Unix timestamp in seconds
//
// This is necessary to easily correlate this invocation with logs or other data.
pub start_time: u64,
pub duration_including_children_sec: f64,
pub children: Vec<JsonNode>,
}
#[derive(Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum JsonNode {
RustbuildStep {
#[serde(rename = "type")]
type_: String,
debug_repr: String,
duration_excluding_children_sec: f64,
system_stats: JsonStepSystemStats,
children: Vec<JsonNode>,
},
TestSuite(TestSuite),
}
#[derive(Serialize, Deserialize)]
pub struct TestSuite {
pub metadata: TestSuiteMetadata,
pub tests: Vec<Test>,
}
#[derive(Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum TestSuiteMetadata {
CargoPackage {
crates: Vec<String>,
target: String,
host: String,
stage: u32,
},
Compiletest {
suite: String,
mode: String,
compare_mode: Option<String>,
target: String,
host: String,
stage: u32,
},
}
#[derive(Serialize, Deserialize)]
pub struct Test {
pub name: String,
#[serde(flatten)]
pub outcome: TestOutcome,
}
#[derive(Serialize, Deserialize)]
#[serde(tag = "outcome", rename_all = "snake_case")]
pub enum TestOutcome {
Passed,
Failed,
Ignored { ignore_reason: Option<String> },
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct JsonInvocationSystemStats {
pub cpu_threads_count: usize,
pub cpu_model: String,
pub memory_total_bytes: u64,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct JsonStepSystemStats {
pub cpu_utilization_percent: f64,
}

@ -1 +1 @@
Subproject commit 5b377cece0e0dd0af686cf53ce4637d5d85c2a10
Subproject commit 45782b6b8afd1da042d45c2daeec9c0744f72cc7

View file

@ -9,7 +9,7 @@ use rustc_hir::{
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, PointerCast};
use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, Ty, TypeckResults};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;
@ -116,7 +116,7 @@ fn check_struct<'tcx>(
let is_default_without_adjusts = |expr| {
is_default_equivalent(cx, expr)
&& typeck_results.expr_adjustments(expr).iter().all(|adj| {
!matches!(adj.kind, Adjust::Pointer(PointerCast::Unsize)
!matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize)
if contains_trait_object(adj.target))
})
};

View file

@ -14,7 +14,7 @@ use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{BindingAnnotation, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, PointerCast};
use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, RegionKind};
use rustc_session::{declare_tool_lint, impl_lint_pass};
@ -195,7 +195,7 @@ impl<'tcx> PassByRefOrValue {
.adjustments()
.items()
.flat_map(|(_, a)| a)
.any(|a| matches!(a.kind, Adjust::Pointer(PointerCast::UnsafeFnPointer)))
.any(|a| matches!(a.kind, Adjust::Pointer(PointerCoercion::UnsafeFnPointer)))
{
continue;
}

View file

@ -16,7 +16,7 @@ use rustc_middle::mir::{
};
use rustc_middle::traits::{ImplSource, ObligationCause};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
use rustc_middle::ty::{BoundConstness, TraitRef};
use rustc_semver::RustcVersion;
use rustc_span::symbol::sym;
@ -119,18 +119,18 @@ fn check_rvalue<'tcx>(
| CastKind::FloatToFloat
| CastKind::FnPtrToPtr
| CastKind::PtrToPtr
| CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
| CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer),
operand,
_,
) => check_operand(tcx, operand, span, body),
Rvalue::Cast(
CastKind::Pointer(
PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer,
CastKind::PointerCoercion(
PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) | PointerCoercion::ReifyFnPointer,
),
_,
_,
) => Err((span, "function pointer casts are not allowed in const fn".into())),
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => {
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), op, cast_ty) => {
let pointee_ty = if let Some(deref_ty) = cast_ty.builtin_deref(true) {
deref_ty.ty
} else {

View file

@ -1,9 +0,0 @@
//@run-rustfix
//@compile-flags: -C incremental=target/debug/test/incr
// see https://github.com/rust-lang/rust-clippy/issues/10969
fn main() {
let s = "Hello, world!";
println!("{}", s.to_string());
}

View file

@ -1,10 +0,0 @@
error: `to_string` applied to a type that implements `Display` in `println!` args
--> $DIR/to_string_in_format_args_incremental.rs:8:21
|
LL | println!("{}", s.to_string());
| ^^^^^^^^^^^^ help: remove this
|
= note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
error: aborting due to previous error

View file

@ -588,21 +588,22 @@ impl TestProps {
}
}
/// Extract a `(Option<line_config>, directive)` directive from a line if comment is present.
pub fn line_directive<'line>(
comment: &str,
ln: &'line str,
) -> Option<(Option<&'line str>, &'line str)> {
let ln = ln.trim_start();
if ln.starts_with(comment) {
let ln = ln[comment.len()..].trim_start();
if ln.starts_with('[') {
// A comment like `//[foo]` is specific to revision `foo`
if let Some(close_brace) = ln.find(']') {
let lncfg = &ln[1..close_brace];
let Some(close_brace) = ln.find(']') else {
panic!("malformed condition directive: expected `{}[foo]`, found `{}`", comment, ln);
};
Some((Some(lncfg), ln[(close_brace + 1)..].trim_start()))
} else {
panic!("malformed condition directive: expected `{}[foo]`, found `{}`", comment, ln)
}
let lncfg = &ln[1..close_brace];
Some((Some(lncfg), ln[(close_brace + 1)..].trim_start()))
} else {
Some((None, ln))
}

View file

@ -41,7 +41,7 @@ use crate::extract_gdb_version;
use crate::is_android_gdb_target;
mod debugger;
use debugger::{check_debugger_output, DebuggerCommands};
use debugger::DebuggerCommands;
#[cfg(test)]
mod tests;
@ -997,16 +997,13 @@ impl<'test> TestCx<'test> {
};
// Parse debugger commands etc from test files
let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
match DebuggerCommands::parse_from(
&self.testpaths.file,
self.config,
prefixes,
self.revision,
) {
Ok(cmds) => cmds,
Err(e) => self.fatal(&e),
};
let dbg_cmds = DebuggerCommands::parse_from(
&self.testpaths.file,
self.config,
prefixes,
self.revision,
)
.unwrap_or_else(|e| self.fatal(&e));
// https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
let mut script_str = String::with_capacity(2048);
@ -1023,12 +1020,12 @@ impl<'test> TestCx<'test> {
// Set breakpoints on every line that contains the string "#break"
let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
for line in &breakpoint_lines {
for line in &dbg_cmds.breakpoint_lines {
script_str.push_str(&format!("bp `{}:{}`\n", source_file_name, line));
}
// Append the other `cdb-command:`s
for line in &commands {
for line in &dbg_cmds.commands {
script_str.push_str(line);
script_str.push_str("\n");
}
@ -1058,7 +1055,7 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("Error while running CDB", &debugger_run_result);
}
if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
self.fatal_proc_rec(&e, &debugger_run_result);
}
}
@ -1088,17 +1085,14 @@ impl<'test> TestCx<'test> {
PREFIXES
};
let DebuggerCommands { commands, check_lines, breakpoint_lines } =
match DebuggerCommands::parse_from(
&self.testpaths.file,
self.config,
prefixes,
self.revision,
) {
Ok(cmds) => cmds,
Err(e) => self.fatal(&e),
};
let mut cmds = commands.join("\n");
let dbg_cmds = DebuggerCommands::parse_from(
&self.testpaths.file,
self.config,
prefixes,
self.revision,
)
.unwrap_or_else(|e| self.fatal(&e));
let mut cmds = dbg_cmds.commands.join("\n");
// compile test file (it should have 'compile-flags:-g' in the header)
let should_run = self.run_if_enabled();
@ -1132,13 +1126,14 @@ impl<'test> TestCx<'test> {
./{}/stage2/lib/rustlib/{}/lib/\n",
self.config.host, self.config.target
));
for line in &breakpoint_lines {
for line in &dbg_cmds.breakpoint_lines {
script_str.push_str(
&format!(
format!(
"break {:?}:{}\n",
self.testpaths.file.file_name().unwrap().to_string_lossy(),
*line
)[..],
)
.as_str(),
);
}
script_str.push_str(&cmds);
@ -1279,7 +1274,7 @@ impl<'test> TestCx<'test> {
}
// Add line breakpoints
for line in &breakpoint_lines {
for line in &dbg_cmds.breakpoint_lines {
script_str.push_str(&format!(
"break '{}':{}\n",
self.testpaths.file.file_name().unwrap().to_string_lossy(),
@ -1315,7 +1310,7 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("gdb failed to execute", &debugger_run_result);
}
if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
self.fatal_proc_rec(&e, &debugger_run_result);
}
}
@ -1372,16 +1367,13 @@ impl<'test> TestCx<'test> {
};
// Parse debugger commands etc from test files
let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
match DebuggerCommands::parse_from(
&self.testpaths.file,
self.config,
prefixes,
self.revision,
) {
Ok(cmds) => cmds,
Err(e) => self.fatal(&e),
};
let dbg_cmds = DebuggerCommands::parse_from(
&self.testpaths.file,
self.config,
prefixes,
self.revision,
)
.unwrap_or_else(|e| self.fatal(&e));
// Write debugger script:
// We don't want to hang when calling `quit` while the process is still running
@ -1430,7 +1422,7 @@ impl<'test> TestCx<'test> {
// Set breakpoints on every line that contains the string "#break"
let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
for line in &breakpoint_lines {
for line in &dbg_cmds.breakpoint_lines {
script_str.push_str(&format!(
"breakpoint set --file '{}' --line {}\n",
source_file_name, line
@ -1438,7 +1430,7 @@ impl<'test> TestCx<'test> {
}
// Append the other commands
for line in &commands {
for line in &dbg_cmds.commands {
script_str.push_str(line);
script_str.push_str("\n");
}
@ -1458,7 +1450,7 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
}
if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
self.fatal_proc_rec(&e, &debugger_run_result);
}
}

View file

@ -2,18 +2,25 @@ use crate::common::Config;
use crate::header::line_directive;
use crate::runtest::ProcRes;
use std::fmt::Write;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::path::{Path, PathBuf};
/// Representation of information to invoke a debugger and check its output
pub(super) struct DebuggerCommands {
/// Commands for the debuuger
pub commands: Vec<String>,
pub check_lines: Vec<String>,
/// Lines to insert breakpoints at
pub breakpoint_lines: Vec<usize>,
/// Contains the source line number to check and the line itself
check_lines: Vec<(usize, String)>,
/// Source file name
file: PathBuf,
}
impl DebuggerCommands {
pub(super) fn parse_from(
pub fn parse_from(
file: &Path,
config: &Config,
debugger_prefixes: &[&str],
@ -21,7 +28,7 @@ impl DebuggerCommands {
) -> Result<Self, String> {
let directives = debugger_prefixes
.iter()
.map(|prefix| (format!("{}-command", prefix), format!("{}-check", prefix)))
.map(|prefix| (format!("{prefix}-command"), format!("{prefix}-check")))
.collect::<Vec<_>>();
let mut breakpoint_lines = vec![];
@ -29,63 +36,88 @@ impl DebuggerCommands {
let mut check_lines = vec![];
let mut counter = 0;
let reader = BufReader::new(File::open(file).unwrap());
for line in reader.lines() {
for (line_no, line) in reader.lines().enumerate() {
counter += 1;
match line {
Ok(line) => {
let (lnrev, line) = line_directive("//", &line).unwrap_or((None, &line));
let line = line.map_err(|e| format!("Error while parsing debugger commands: {}", e))?;
let (lnrev, line) = line_directive("//", &line).unwrap_or((None, &line));
// Skip any revision specific directive that doesn't match the current
// revision being tested
if lnrev.is_some() && lnrev != rev {
continue;
}
// Skip any revision specific directive that doesn't match the current
// revision being tested
if lnrev.is_some() && lnrev != rev {
continue;
}
if line.contains("#break") {
breakpoint_lines.push(counter);
}
if line.contains("#break") {
breakpoint_lines.push(counter);
}
for &(ref command_directive, ref check_directive) in &directives {
config
.parse_name_value_directive(&line, command_directive)
.map(|cmd| commands.push(cmd));
for &(ref command_directive, ref check_directive) in &directives {
config
.parse_name_value_directive(&line, command_directive)
.map(|cmd| commands.push(cmd));
config
.parse_name_value_directive(&line, check_directive)
.map(|cmd| check_lines.push(cmd));
}
}
Err(e) => return Err(format!("Error while parsing debugger commands: {}", e)),
config
.parse_name_value_directive(&line, check_directive)
.map(|cmd| check_lines.push((line_no, cmd)));
}
}
Ok(Self { commands, check_lines, breakpoint_lines })
}
}
pub(super) fn check_debugger_output(
debugger_run_result: &ProcRes,
check_lines: &[String],
) -> Result<(), String> {
let num_check_lines = check_lines.len();
let mut check_line_index = 0;
for line in debugger_run_result.stdout.lines() {
if check_line_index >= num_check_lines {
break;
}
if check_single_line(line, &(check_lines[check_line_index])[..]) {
check_line_index += 1;
}
}
if check_line_index != num_check_lines && num_check_lines > 0 {
Err(format!("line not found in debugger output: {}", check_lines[check_line_index]))
} else {
Ok(())
Ok(Self { commands, breakpoint_lines, check_lines, file: file.to_owned() })
}
/// Given debugger output and lines to check, ensure that every line is
/// contained in the debugger output. The check lines need to be found in
/// order, but there can be extra lines between.
pub fn check_output(&self, debugger_run_result: &ProcRes) -> Result<(), String> {
// (src_lineno, ck_line) that we did find
let mut found = vec![];
// (src_lineno, ck_line) that we couldn't find
let mut missing = vec![];
// We can find our any current match anywhere after our last match
let mut last_idx = 0;
let dbg_lines: Vec<&str> = debugger_run_result.stdout.lines().collect();
for (src_lineno, ck_line) in &self.check_lines {
if let Some(offset) = dbg_lines
.iter()
.skip(last_idx)
.position(|out_line| check_single_line(out_line, &ck_line))
{
last_idx += offset;
found.push((src_lineno, dbg_lines[last_idx]));
} else {
missing.push((src_lineno, ck_line));
}
}
if missing.is_empty() {
Ok(())
} else {
let fname = self.file.file_name().unwrap().to_string_lossy();
let mut msg = format!(
"check directive(s) from `{}` not found in debugger output. errors:",
self.file.display()
);
for (src_lineno, err_line) in missing {
write!(msg, "\n ({fname}:{num}) `{err_line}`", num = src_lineno + 1).unwrap();
}
if !found.is_empty() {
let init = "\nthe following subset of check directive(s) was found successfully:";
msg.push_str(init);
for (src_lineno, found_line) in found {
write!(msg, "\n ({fname}:{num}) `{found_line}`", num = src_lineno + 1)
.unwrap();
}
}
Err(msg)
}
}
}
/// Check that the pattern in `check_line` applies to `line`. Returns `true` if they do match.
fn check_single_line(line: &str, check_line: &str) -> bool {
// Allow check lines to leave parts unspecified (e.g., uninitialized
// bits in the wrong case of an enum) with the notation "[...]".
@ -101,21 +133,19 @@ fn check_single_line(line: &str, check_line: &str) -> bool {
}
let (mut rest, first_fragment) = if can_start_anywhere {
match line.find(check_fragments[0]) {
Some(pos) => (&line[pos + check_fragments[0].len()..], 1),
None => return false,
}
let Some(pos) = line.find(check_fragments[0]) else {
return false;
};
(&line[pos + check_fragments[0].len()..], 1)
} else {
(line, 0)
};
for current_fragment in &check_fragments[first_fragment..] {
match rest.find(current_fragment) {
Some(pos) => {
rest = &rest[pos + current_fragment.len()..];
}
None => return false,
}
let Some(pos) = rest.find(current_fragment) else {
return false;
};
rest = &rest[pos + current_fragment.len()..];
}
if !can_end_anywhere && !rest.is_empty() { false } else { true }

View file

@ -1 +1 @@
d4096e0412ac5de785d739a0aa2b1c1c7b9d3b7d
743333f3dd90721461c09387ec73d09c080d5f5f

View file

@ -0,0 +1,23 @@
#![feature(core_intrinsics)]
#![feature(custom_mir)]
use std::intrinsics::mir::*;
// It's not that easy to fool the MIR validity check
// which wants to prevent overlapping assignments...
// So we use two separate pointer arguments, and then arrange for them to alias.
#[custom_mir(dialect = "runtime", phase = "optimized")]
pub fn self_copy(ptr1: *mut [i32; 4], ptr2: *mut [i32; 4]) {
mir! {
{
*ptr1 = *ptr2; //~ERROR: overlapping ranges
Return()
}
}
}
pub fn main() {
let mut x = [0; 4];
let ptr = std::ptr::addr_of_mut!(x);
self_copy(ptr, ptr);
}

View file

@ -0,0 +1,20 @@
error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
--> $DIR/overlapping_assignment.rs:LL:CC
|
LL | *ptr1 = *ptr2;
| ^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `self_copy` at $DIR/overlapping_assignment.rs:LL:CC
note: inside `main`
--> $DIR/overlapping_assignment.rs:LL:CC
|
LL | self_copy(ptr, ptr);
| ^^^^^^^^^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to previous error

View file

@ -0,0 +1,22 @@
[package]
name = "opt-dist"
version = "0.1.0"
edition = "2021"
[dependencies]
build_helper = { path = "../build_helper" }
env_logger = "0.10"
log = "0.4"
anyhow = { version = "1", features = ["backtrace"] }
humantime = "2"
humansize = "2"
sysinfo = { version = "0.29", default-features = false }
fs_extra = "1"
camino = "1"
reqwest = { version = "0.11", features = ["blocking"] }
zip = { version = "0.6", default-features = false, features = ["deflate"] }
tar = "0.4"
xz = "0.1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
glob = "0.3"

View file

@ -0,0 +1,7 @@
# Optimized build pipeline
This binary implements a heavily optimized build pipeline for `rustc` and `LLVM` artifacts that are used for both for
benchmarking using the perf. bot and for final distribution to users.
It uses LTO, PGO and BOLT to optimize the compiler and LLVM as much as possible.
This logic is not part of bootstrap, because it needs to invoke bootstrap multiple times, force-rebuild various
artifacts repeatedly and sometimes go around bootstrap's cache mechanism.

View file

@ -0,0 +1,54 @@
use crate::environment::Environment;
use crate::exec::cmd;
use crate::utils::io::copy_directory;
use camino::{Utf8Path, Utf8PathBuf};
pub(super) struct LinuxEnvironment;
impl Environment for LinuxEnvironment {
fn python_binary(&self) -> &'static str {
"python3"
}
fn checkout_path(&self) -> Utf8PathBuf {
Utf8PathBuf::from("/checkout")
}
fn downloaded_llvm_dir(&self) -> Utf8PathBuf {
Utf8PathBuf::from("/rustroot")
}
fn opt_artifacts(&self) -> Utf8PathBuf {
Utf8PathBuf::from("/tmp/tmp-multistage/opt-artifacts")
}
fn build_root(&self) -> Utf8PathBuf {
self.checkout_path().join("obj")
}
fn prepare_rustc_perf(&self) -> anyhow::Result<()> {
// /tmp/rustc-perf comes from the x64 dist Dockerfile
copy_directory(Utf8Path::new("/tmp/rustc-perf"), &self.rustc_perf_dir())?;
cmd(&[self.cargo_stage_0().as_str(), "build", "-p", "collector"])
.workdir(&self.rustc_perf_dir())
.env("RUSTC", &self.rustc_stage_0().into_string())
.env("RUSTC_BOOTSTRAP", "1")
.run()?;
Ok(())
}
fn supports_bolt(&self) -> bool {
true
}
fn executable_extension(&self) -> &'static str {
""
}
fn skipped_tests(&self) -> &'static [&'static str] {
&[
// Fails because of linker errors, as of June 2023.
"tests/ui/process/nofile-limit.rs",
]
}
}

Some files were not shown because too many files have changed in this diff Show more