Merge pull request #4145 from rust-lang/rustup-2025-01-23

Automatic Rustup
This commit is contained in:
Ben Kimock 2025-01-23 06:14:06 +00:00 committed by GitHub
commit e923d85be4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1432 changed files with 19128 additions and 11013 deletions

70
.github/ISSUE_TEMPLATE/bootstrap.md vendored Normal file
View file

@ -0,0 +1,70 @@
---
name: Bootstrap (Rust Build System) Report
about: Issues encountered on bootstrap build system
labels: C-bug, T-bootstrap
---
<!--
Thank you for submitting a bootstrap report! Please provide detailed information to help us reproduce and diagnose the issue.
-->
### Summary
<!--
Provide a brief description of the problem you are experiencing.
-->
### Command used
```sh
<command>
```
### Expected behaviour
<!--
Describe what you expected to happen.
-->
### Actual behaviour
<!--
Describe what actually happened.
-->
### Bootstrap configuration (config.toml)
```toml
<config>
```
### Operating system
<!--
e.g., Ubuntu 22.04, macOS 12, Windows 10
-->
### HEAD
<!--
Output of `git rev-parse HEAD` command, or content of the `git-commit-hash` file if using a tarball source.
-->
### Additional context
<!--
Include any other relevant information (e.g., if you have custom patches or modifications on the project).
-->
<!--
Include the complete build log in the section below.
Enable backtrace and verbose mode if possible for more detailed information e.g., with `RUST_BACKTRACE=1 ./x build -v`.
-->
<details><summary>Build Log</summary>
<p>
```txt
<log>
```
</p>
</details>

1
.gitignore vendored
View file

@ -83,6 +83,7 @@ __pycache__/
node_modules
package-lock.json
package.json
/src/doc/rustc-dev-guide/mermaid.min.js
## Rustdoc GUI tests
tests/rustdoc-gui/src/**.lock

View file

@ -12,6 +12,15 @@ Documentation for contributing to the compiler or tooling is located in the [Gui
Development][rustc-dev-guide], commonly known as the [rustc-dev-guide]. Documentation for the
standard library in the [Standard library developers Guide][std-dev-guide], commonly known as the [std-dev-guide].
## Making changes to subtrees and submodules
For submodules, changes need to be made against the repository corresponding the
submodule, and not the main `rust-lang/rust` repository.
For subtrees, prefer sending a PR against the subtree's repository if it does
not need to be made against the main `rust-lang/rust` repostory (e.g. a
rustc-dev-guide change that does not accompany a compiler change).
## About the [rustc-dev-guide]
The [rustc-dev-guide] is meant to help document how rustc the Rust compiler works,

View file

@ -172,11 +172,12 @@ dependencies = [
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys 0.59.0",
]
@ -254,9 +255,9 @@ dependencies = [
[[package]]
name = "bitflags"
version = "2.7.0"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "blake3"
@ -450,9 +451,9 @@ dependencies = [
[[package]]
name = "chrono-tz"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd6dd8046d00723a59a2f8c5f295c515b9bb9a331ee4f8f3d4dd49e428acd3b6"
checksum = "9c6ac4f2c0bf0f44e9161aec9675e1050aa4a530663c4a9e37e108fa948bca9f"
dependencies = [
"chrono",
"chrono-tz-build",
@ -733,7 +734,7 @@ dependencies = [
"tracing-subscriber",
"unified-diff",
"walkdir",
"windows",
"windows 0.59.0",
]
[[package]]
@ -1223,7 +1224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
dependencies = [
"crc32fast",
"miniz_oxide 0.8.2",
"miniz_oxide 0.8.3",
]
[[package]]
@ -1524,7 +1525,6 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
"serde",
]
[[package]]
@ -1534,6 +1534,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
dependencies = [
"foldhash",
"serde",
]
[[package]]
@ -1954,9 +1955,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.76"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
@ -2152,9 +2153,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.22"
version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
name = "lzma-sys"
@ -2317,9 +2318,9 @@ dependencies = [
[[package]]
name = "miniz_oxide"
version = "0.8.2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
dependencies = [
"adler2",
]
@ -3574,7 +3575,7 @@ dependencies = [
"thorin-dwp",
"tracing",
"wasm-encoder 0.219.1",
"windows",
"windows 0.59.0",
]
[[package]]
@ -3632,7 +3633,7 @@ dependencies = [
"tempfile",
"thin-vec",
"tracing",
"windows",
"windows 0.59.0",
]
[[package]]
@ -3694,7 +3695,7 @@ dependencies = [
"shlex",
"time",
"tracing",
"windows",
"windows 0.59.0",
]
[[package]]
@ -3747,7 +3748,7 @@ dependencies = [
"termcolor",
"termize",
"tracing",
"windows",
"windows 0.59.0",
]
[[package]]
@ -4480,7 +4481,7 @@ dependencies = [
"smallvec",
"termize",
"tracing",
"windows",
"windows 0.59.0",
]
[[package]]
@ -5183,7 +5184,7 @@ checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
dependencies = [
"core-foundation-sys",
"libc",
"windows",
"windows 0.57.0",
]
[[package]]
@ -5836,18 +5837,18 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.11.1"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b913a3b5fe84142e269d63cc62b64319ccaf89b748fc31fe025177f767a756c4"
checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4"
dependencies = [
"getrandom",
]
[[package]]
name = "valuable"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "vcpkg"
@ -5879,26 +5880,27 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi-preview1-component-adapter-provider"
version = "24.0.1"
version = "29.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f76d9fa52234153eeb40b088de91a8c13dc28a912cf6f31cd89ca4bac9024e0"
checksum = "dcd9f21bbde82ba59e415a8725e6ad0d0d7e9e460b1a3ccbca5bdee952c1a324"
[[package]]
name = "wasm-bindgen"
version = "0.2.99"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.99"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
@ -5910,9 +5912,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.99"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -5920,9 +5922,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.99"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
@ -5933,15 +5935,18 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.99"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "wasm-component-ld"
version = "0.5.11"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2b05c3820968b335f10e703218459e4fd2cc91fdfc8f7936a993f1aacaa0938"
checksum = "580305a8e3f1b7a79859a8db897de643533b2851c5eb080fe5800233f16dec88"
dependencies = [
"anyhow",
"clap",
@ -5949,7 +5954,7 @@ dependencies = [
"libc",
"tempfile",
"wasi-preview1-component-adapter-provider",
"wasmparser 0.219.1",
"wasmparser 0.223.0",
"wat",
"windows-sys 0.59.0",
"winsplit",
@ -5986,9 +5991,9 @@ dependencies = [
[[package]]
name = "wasm-metadata"
version = "0.219.1"
version = "0.223.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af5a8e37a5e996861e1813f8de30911c47609c9ff51a7284f7dbd754dc3a9f3"
checksum = "5c730c3379d3d20e5a0245b0724b924483e853588ca8fba547c1e21f19e7d735"
dependencies = [
"anyhow",
"indexmap",
@ -5996,8 +6001,9 @@ dependencies = [
"serde_derive",
"serde_json",
"spdx",
"wasm-encoder 0.219.1",
"wasmparser 0.219.1",
"url",
"wasm-encoder 0.223.0",
"wasmparser 0.223.0",
]
[[package]]
@ -6006,12 +6012,8 @@ version = "0.219.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5"
dependencies = [
"ahash",
"bitflags",
"hashbrown 0.14.5",
"indexmap",
"semver",
"serde",
]
[[package]]
@ -6030,8 +6032,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35"
dependencies = [
"bitflags",
"hashbrown 0.15.2",
"indexmap",
"semver",
"serde",
]
[[package]]
@ -6107,6 +6111,16 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
dependencies = [
"windows-core 0.59.0",
"windows-targets 0.53.0",
]
[[package]]
name = "windows-bindgen"
version = "0.58.0"
@ -6136,12 +6150,25 @@ version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
dependencies = [
"windows-implement",
"windows-interface",
"windows-result",
"windows-implement 0.57.0",
"windows-interface 0.57.0",
"windows-result 0.1.2",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
dependencies = [
"windows-implement 0.59.0",
"windows-interface 0.59.0",
"windows-result 0.3.0",
"windows-strings",
"windows-targets 0.53.0",
]
[[package]]
name = "windows-implement"
version = "0.57.0"
@ -6153,6 +6180,17 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "windows-implement"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
]
[[package]]
name = "windows-interface"
version = "0.57.0"
@ -6164,6 +6202,17 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "windows-interface"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
]
[[package]]
name = "windows-metadata"
version = "0.58.0"
@ -6179,6 +6228,24 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-result"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d08106ce80268c4067c0571ca55a9b4e9516518eaa1a1fe9b37ca403ae1d1a34"
dependencies = [
"windows-targets 0.53.0",
]
[[package]]
name = "windows-strings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b888f919960b42ea4e11c2f408fadb55f78a9f236d5eef084103c8ce52893491"
dependencies = [
"windows-targets 0.53.0",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
@ -6230,13 +6297,29 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
dependencies = [
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
"windows_i686_gnullvm 0.53.0",
"windows_i686_msvc 0.53.0",
"windows_x86_64_gnu 0.53.0",
"windows_x86_64_gnullvm 0.53.0",
"windows_x86_64_msvc 0.53.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
@ -6249,6 +6332,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
@ -6261,6 +6350,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
@ -6273,12 +6368,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
@ -6291,6 +6398,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
@ -6303,6 +6416,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
@ -6315,6 +6434,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
@ -6327,6 +6452,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.5.40"
@ -6344,9 +6475,9 @@ checksum = "3ab703352da6a72f35c39a533526393725640575bb211f61987a2748323ad956"
[[package]]
name = "wit-component"
version = "0.219.1"
version = "0.223.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1673163c0cb14a6a19ddbf44dd4efe6f015ec1ebb8156710ac32501f19fba2"
checksum = "c10ed2aeee4c8ec5715875f62f4a3de3608d6987165c116810d8c2908aa9d93b"
dependencies = [
"anyhow",
"bitflags",
@ -6355,17 +6486,17 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"wasm-encoder 0.219.1",
"wasm-encoder 0.223.0",
"wasm-metadata",
"wasmparser 0.219.1",
"wasmparser 0.223.0",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.219.1"
version = "0.223.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598"
checksum = "92772f4dcacb804b275981eea1d920b12b377993b53307f1e33d87404e080281"
dependencies = [
"anyhow",
"id-arena",
@ -6376,7 +6507,7 @@ dependencies = [
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser 0.219.1",
"wasmparser 0.223.0",
]
[[package]]

View file

@ -359,7 +359,7 @@ Language
- [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834)
- [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/)
- [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/)
- [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672)
- [Stabilize `+ use<'lt>` opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672)
- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679)
- [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921)
- [Stabilize nested field access in `offset_of!`](https://github.com/rust-lang/rust/pull/128284)

View file

@ -18,12 +18,6 @@ pub enum EntryPointType {
/// fn main() {}
/// ```
RustcMainAttr,
/// This is a function with the `#[start]` attribute.
/// ```ignore (clashes with test entrypoint)
/// #[start]
/// fn main() {}
/// ```
Start,
/// This function is **not** an entrypoint but simply named `main` (not at the root).
/// This is only used for diagnostics.
/// ```
@ -40,9 +34,7 @@ pub fn entry_point_type(
at_root: bool,
name: Option<Symbol>,
) -> EntryPointType {
if attr::contains_name(attrs, sym::start) {
EntryPointType::Start
} else if attr::contains_name(attrs, sym::rustc_main) {
if attr::contains_name(attrs, sym::rustc_main) {
EntryPointType::RustcMainAttr
} else if let Some(name) = name
&& name == sym::main

View file

@ -72,7 +72,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
if let Some(local_sig_id) = def_id.as_local() {
// The value may be missing due to recursive delegation.
// Error will be emitted later during HIR ty lowering.
self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self)
self.resolver.delegation_fn_sigs.get(&local_sig_id).is_some_and(|sig| sig.has_self)
} else {
match self.tcx.def_kind(def_id) {
DefKind::Fn => false,

View file

@ -2159,7 +2159,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let path = hir::ExprKind::Path(hir::QPath::TypeRelative(
self.arena.alloc(self.ty(span, hir::TyKind::Path(qpath))),
self.arena.alloc(hir::PathSegment::new(
Ident::new(name, span),
Ident::new(name, self.lower_span(span)),
self.next_id(),
Res::Err,
)),

View file

@ -78,24 +78,31 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
// Make sure that the DepNode of some node coincides with the HirId
// owner of that node.
if cfg!(debug_assertions) && hir_id.owner != self.owner {
span_bug!(
span,
"inconsistent HirId at `{:?}` for `{:?}`: \
if cfg!(debug_assertions) {
if hir_id.owner != self.owner {
span_bug!(
span,
"inconsistent HirId at `{:?}` for `{node:?}`: \
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
self.tcx.sess.source_map().span_to_diagnostic_string(span),
node,
self.tcx
.definitions_untracked()
.def_path(self.owner.def_id)
.to_string_no_crate_verbose(),
self.owner,
self.tcx
.definitions_untracked()
.def_path(hir_id.owner.def_id)
.to_string_no_crate_verbose(),
hir_id.owner,
)
self.tcx.sess.source_map().span_to_diagnostic_string(span),
self.tcx
.definitions_untracked()
.def_path(self.owner.def_id)
.to_string_no_crate_verbose(),
self.owner,
self.tcx
.definitions_untracked()
.def_path(hir_id.owner.def_id)
.to_string_no_crate_verbose(),
hir_id.owner,
)
}
if self.tcx.sess.opts.incremental.is_some()
&& span.parent().is_none()
&& !span.is_dummy()
{
span_bug!(span, "span without a parent: {:#?}, {node:?}", span.data())
}
}
self.nodes[hir_id.local_id] = ParentedNode { parent: self.parent_node, node };

View file

@ -1092,6 +1092,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// this as a special case.
return self.lower_fn_body(decl, |this| {
if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic) {
let span = this.lower_span(span);
let empty_block = hir::Block {
hir_id: this.next_id(),
stmts: &[],

View file

@ -375,24 +375,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
expr: &Expr,
allow_paths: bool,
) -> &'hir hir::PatExpr<'hir> {
let span = self.lower_span(expr.span);
let err = |guar| hir::PatExprKind::Lit {
lit: self.arena.alloc(respan(self.lower_span(expr.span), LitKind::Err(guar))),
lit: self.arena.alloc(respan(span, LitKind::Err(guar))),
negated: false,
};
let kind = match &expr.kind {
ExprKind::Lit(lit) => {
hir::PatExprKind::Lit { lit: self.lower_lit(lit, expr.span), negated: false }
hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: false }
}
ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c)),
ExprKind::IncludedBytes(bytes) => hir::PatExprKind::Lit {
lit: self.arena.alloc(respan(
self.lower_span(expr.span),
LitKind::ByteStr(Arc::clone(bytes), StrStyle::Cooked),
)),
lit: self
.arena
.alloc(respan(span, LitKind::ByteStr(Arc::clone(bytes), StrStyle::Cooked))),
negated: false,
},
ExprKind::Err(guar) => err(*guar),
ExprKind::Dummy => span_bug!(expr.span, "lowered ExprKind::Dummy"),
ExprKind::Dummy => span_bug!(span, "lowered ExprKind::Dummy"),
ExprKind::Path(qself, path) if allow_paths => hir::PatExprKind::Path(self.lower_qpath(
expr.id,
qself,
@ -403,21 +403,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
None,
)),
ExprKind::Unary(UnOp::Neg, inner) if let ExprKind::Lit(lit) = &inner.kind => {
hir::PatExprKind::Lit { lit: self.lower_lit(lit, expr.span), negated: true }
hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: true }
}
_ => {
let pattern_from_macro = expr.is_approximately_pattern();
let guar = self.dcx().emit_err(ArbitraryExpressionInPattern {
span: expr.span,
span,
pattern_from_macro_note: pattern_from_macro,
});
err(guar)
}
};
self.arena.alloc(hir::PatExpr {
hir_id: self.lower_node_id(expr.id),
span: expr.span,
kind,
})
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
}
}

View file

@ -83,7 +83,7 @@ impl<'a> PostExpansionVisitor<'a> {
feature_err_issue(&self.sess, feature, span, GateIssue::Language, explain).emit();
}
Err(abi::AbiDisabled::Unrecognized) => {
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
if self.sess.opts.pretty.is_none_or(|ppm| ppm.needs_hir()) {
self.sess.dcx().span_delayed_bug(
span,
format!(
@ -230,18 +230,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
ast::ItemKind::Fn(..) => {
if attr::contains_name(&i.attrs, sym::start) {
gate!(
&self,
start,
i.span,
"`#[start]` functions are experimental and their signature may change \
over time"
);
}
}
ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => {
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {

View file

@ -166,7 +166,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec<ReprAttr
// the `check_mod_attrs` pass, but this pass doesn't always run
// (e.g. if we only pretty-print the source), so we have to gate
// the `span_delayed_bug` call as follows:
if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) {
if sess.opts.pretty.is_none_or(|pp| pp.needs_analysis()) {
dcx.span_delayed_bug(item.span(), "unrecognized representation hint");
}
}

View file

@ -39,7 +39,9 @@ use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
use rustc_trait_selection::traits::{
Obligation, ObligationCause, ObligationCtxt, supertrait_def_ids,
};
use tracing::{debug, instrument};
use super::explain_borrow::{BorrowExplanation, LaterUseKind};
@ -658,8 +660,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
clause.as_trait_clause().is_some_and(|tc| {
tc.self_ty().skip_binder().is_param(param.index)
&& tc.polarity() == ty::PredicatePolarity::Positive
&& tcx
.supertrait_def_ids(tc.def_id())
&& supertrait_def_ids(tcx, tc.def_id())
.flat_map(|trait_did| tcx.associated_items(trait_did).in_definition_order())
.any(|item| item.fn_has_self_parameter)
})
@ -2480,7 +2481,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// To support cases like `|| { v.call(|this| v.get()) }`
// FIXME: actually support such cases (need to figure out how to move from the
// capture place to original local).
&& self.res.as_ref().map_or(true, |(prev_res, _)| prev_res.span.contains(ex.span))
&& self.res.as_ref().is_none_or(|(prev_res, _)| prev_res.span.contains(ex.span))
{
self.res = Some((ex, closure));
}

View file

@ -131,10 +131,10 @@ impl<'tcx> BorrowExplanation<'tcx> {
&& let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
{
suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
} else if path_span.map_or(true, |path_span| path_span == var_or_use_span) {
} else if path_span.is_none_or(|path_span| path_span == var_or_use_span) {
// We can use `var_or_use_span` if either `path_span` is not present, or both
// spans are the same.
if borrow_span.map_or(true, |sp| !sp.overlaps(var_or_use_span)) {
if borrow_span.is_none_or(|sp| !sp.overlaps(var_or_use_span)) {
err.span_label(
var_or_use_span,
format!("{borrow_desc}borrow later {message}"),

View file

@ -829,6 +829,7 @@ use self::ReadOrWrite::{Activation, Read, Reservation, Write};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum ArtificialField {
ArrayLength,
FakeBorrow,
}
@ -1338,11 +1339,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
);
}
&Rvalue::Discriminant(place) => {
&(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
let af = match *rvalue {
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
Rvalue::Discriminant(..) => None,
_ => unreachable!(),
};
self.access_place(
location,
(place, span),
(Shallow(None), Read(ReadKind::Copy)),
(Shallow(af), Read(ReadKind::Copy)),
LocalMutationIsAllowed::No,
state,
);

View file

@ -203,7 +203,8 @@ fn place_components_conflict<'tcx>(
let base_ty = base.ty(body, tcx).ty;
match (elem, base_ty.kind(), access) {
(_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
| (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
// The array length is like additional fields on the
// type; it does not overlap any existing data there.
// Furthermore, if cannot actually be a prefix of any

View file

@ -300,11 +300,16 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
self.consume_operand(location, op);
}
&Rvalue::Discriminant(place) => {
&(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
let af = match rvalue {
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
Rvalue::Discriminant(..) => None,
_ => unreachable!(),
};
self.access_place(
location,
place,
(Shallow(None), Read(ReadKind::Copy)),
(Shallow(af), Read(ReadKind::Copy)),
LocalMutationIsAllowed::No,
);
}

View file

@ -185,7 +185,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CustomTypeOp::new(
|ocx| {
let structurally_normalize = |ty| {
ocx.structurally_normalize(
ocx.structurally_normalize_ty(
&ObligationCause::misc(
location.to_locations().span(body),
body.source.def_id().expect_local(),
@ -230,7 +230,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ConstraintCategory::Boring,
CustomTypeOp::new(
|ocx| {
ocx.structurally_normalize(
ocx.structurally_normalize_ty(
&ObligationCause::misc(
location.to_locations().span(body),
body.source.def_id().expect_local(),

View file

@ -2235,6 +2235,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Rvalue::RawPtr(..)
| Rvalue::ThreadLocalRef(..)
| Rvalue::Len(..)
| Rvalue::Discriminant(..)
| Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {}
}
@ -2250,6 +2251,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
| Rvalue::Repeat(..)
| Rvalue::Ref(..)
| Rvalue::RawPtr(..)
| Rvalue::Len(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::BinaryOp(..)

View file

@ -16,6 +16,7 @@
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![feature(rustdoc_internals)]
#![feature(string_from_utf8_lossy_owned)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end

View file

@ -13,7 +13,7 @@ use rustc_expand::base::{
use rustc_expand::module::DirOwnership;
use rustc_lint_defs::BuiltinLintDiag;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error};
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
use rustc_span::source_map::SourceMap;
use rustc_span::{Pos, Span, Symbol};
@ -209,9 +209,10 @@ pub(crate) fn expand_include_str(
let interned_src = Symbol::intern(src);
MacEager::expr(cx.expr_str(cx.with_def_site_ctxt(bsp), interned_src))
}
Err(_) => {
let guar = cx.dcx().span_err(sp, format!("`{path}` wasn't a utf-8 file"));
DummyResult::any(sp, guar)
Err(utf8err) => {
let mut err = cx.dcx().struct_span_err(sp, format!("`{path}` wasn't a utf-8 file"));
utf8_error(cx.source_map(), path.as_str(), None, &mut err, utf8err, &bytes[..]);
DummyResult::any(sp, err.emit())
}
},
Err(dummy) => dummy,
@ -273,7 +274,7 @@ fn load_binary_file(
.and_then(|path| path.into_os_string().into_string().ok());
if let Some(new_path) = new_path {
err.span_suggestion(
err.span_suggestion_verbose(
path_span,
"there is a file with the same name in a different directory",
format!("\"{}\"", new_path.replace('\\', "/").escape_debug()),

View file

@ -204,11 +204,11 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
ast::mut_visit::walk_item(self, item);
self.depth -= 1;
// Remove any #[rustc_main] or #[start] from the AST so it doesn't
// Remove any #[rustc_main] from the AST so it doesn't
// clash with the one we're going to add, but mark it as
// #[allow(dead_code)] to avoid printing warnings.
match entry_point_type(&item, self.depth == 0) {
EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => {
EntryPointType::MainNamed | EntryPointType::RustcMainAttr => {
let allow_dead_code = attr::mk_attr_nested_word(
&self.sess.psess.attr_id_generator,
ast::AttrStyle::Outer,
@ -217,8 +217,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
sym::dead_code,
self.def_site,
);
item.attrs
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
item.attrs.retain(|attr| !attr.has_name(sym::rustc_main));
item.attrs.push(allow_dead_code);
}
EntryPointType::None | EntryPointType::OtherMain => {}

View file

@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2025-01-10"
channel = "nightly-2025-01-20"
components = ["rust-src", "rustc-dev", "llvm-tools"]
profile = "minimal"

View file

@ -176,12 +176,11 @@ diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-supp
index 9607ff02f96..b7d97caf9a2 100644
--- a/src/tools/run-make-support/src/external_deps/rustdoc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs
@@ -34,8 +34,6 @@ pub fn bare() -> Self {
@@ -34,7 +34,6 @@ pub fn bare() -> Self {
#[track_caller]
pub fn new() -> Self {
let mut cmd = setup_common();
- let target_rpath_dir = env_var_os("TARGET_RPATH_DIR");
- cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
- cmd.arg("-L").arg(env_var_os("TARGET_RPATH_DIR"));
Self { cmd }
}

View file

@ -828,6 +828,12 @@ fn codegen_stmt<'tcx>(
fx.bcx.ins().nop();
}
}
Rvalue::Len(place) => {
let place = codegen_place(fx, place);
let usize_layout = fx.layout_of(fx.tcx.types.usize);
let len = codegen_array_len(fx, place);
lval.write_cvalue(fx, CValue::by_val(len, usize_layout));
}
Rvalue::ShallowInitBox(ref operand, content_ty) => {
let content_ty = fx.monomorphize(content_ty);
let box_layout = fx.layout_of(Ty::new_box(fx.tcx, content_ty));

View file

@ -333,9 +333,17 @@ fn make_module(sess: &Session, name: String) -> UnwindModule<ObjectModule> {
let mut builder =
ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap();
// Disable function sections by default on MSVC as it causes significant slowdowns with link.exe.
// Maybe link.exe has exponential behavior when there are many sections with the same name? Also
// explicitly disable it on MinGW as rustc already disables it by default on MinGW and as such
// isn't tested. If rustc enables it in the future on MinGW, we can re-enable it too once it has
// been on MinGW.
let default_function_sections = sess.target.function_sections && !sess.target.is_like_windows;
builder.per_function_section(
sess.opts.unstable_opts.function_sections.unwrap_or(sess.target.function_sections),
sess.opts.unstable_opts.function_sections.unwrap_or(default_function_sections),
);
UnwindModule::new(ObjectModule::new(builder), true)
}

View file

@ -1,4 +1,5 @@
//! Codegen of intrinsics. This includes `extern "rust-intrinsic"`,
//! functions marked with the `#[rustc_intrinsic]` attribute
//! and LLVM intrinsics that have symbol names starting with `llvm.`.
macro_rules! intrinsic_args {

View file

@ -1,7 +1,7 @@
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use rustc_hir::LangItem;
use rustc_middle::ty::{AssocKind, GenericArg};
use rustc_session::config::{EntryFnType, sigpipe};
use rustc_session::config::EntryFnType;
use rustc_span::{DUMMY_SP, Ident};
use crate::prelude::*;
@ -14,10 +14,9 @@ pub(crate) fn maybe_create_entry_wrapper(
is_jit: bool,
is_primary_cgu: bool,
) {
let (main_def_id, (is_main_fn, sigpipe)) = match tcx.entry_fn(()) {
let (main_def_id, sigpipe) = match tcx.entry_fn(()) {
Some((def_id, entry_ty)) => (def_id, match entry_ty {
EntryFnType::Main { sigpipe } => (true, sigpipe),
EntryFnType::Start => (false, sigpipe::DEFAULT),
EntryFnType::Main { sigpipe } => sigpipe,
}),
None => return,
};
@ -31,14 +30,13 @@ pub(crate) fn maybe_create_entry_wrapper(
return;
}
create_entry_fn(tcx, module, main_def_id, is_jit, is_main_fn, sigpipe);
create_entry_fn(tcx, module, main_def_id, is_jit, sigpipe);
fn create_entry_fn(
tcx: TyCtxt<'_>,
m: &mut dyn Module,
rust_main_def_id: DefId,
ignore_lang_start_wrapper: bool,
is_main_fn: bool,
sigpipe: u8,
) {
let main_ret_ty = tcx.fn_sig(rust_main_def_id).no_bound_vars().unwrap().output();
@ -94,8 +92,8 @@ pub(crate) fn maybe_create_entry_wrapper(
let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);
let result = if is_main_fn && ignore_lang_start_wrapper {
// regular main fn, but ignoring #[lang = "start"] as we are running in the jit
let result = if ignore_lang_start_wrapper {
// ignoring #[lang = "start"] as we are running in the jit
// FIXME set program arguments somehow
let call_inst = bcx.ins().call(main_func_ref, &[]);
let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();
@ -133,7 +131,8 @@ pub(crate) fn maybe_create_entry_wrapper(
types::I64 => bcx.ins().sextend(types::I64, res),
_ => unimplemented!("16bit systems are not yet supported"),
}
} else if is_main_fn {
} else {
// Regular main fn invoked via start lang item.
let start_def_id = tcx.require_lang_item(LangItem::Start, None);
let start_instance = Instance::expect_resolve(
tcx,
@ -150,10 +149,6 @@ pub(crate) fn maybe_create_entry_wrapper(
let call_inst =
bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]);
bcx.inst_results(call_inst)[0]
} else {
// using user-defined start fn
let call_inst = bcx.ins().call(main_func_ref, &[arg_argc, arg_argv]);
bcx.inst_results(call_inst)[0]
};
bcx.ins().return_(&[result]);

View file

@ -426,19 +426,6 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
run_command_with_env(&command, None, Some(env))?;
maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?;
// FIXME: create a function "display_if_not_quiet" or something along the line.
println!("[AOT] mod_bench");
let mut command = args.config_info.rustc_command_vec();
command.extend_from_slice(&[
&"example/mod_bench.rs",
&"--crate-type",
&"bin",
&"--target",
&args.config_info.target_triple,
]);
run_command_with_env(&command, None, Some(env))?;
// FIXME: the compiled binary is not run.
Ok(())
}
@ -696,19 +683,6 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
Ok(())
}
// echo "[BENCH COMPILE] mod_bench"
//
// COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline"
// COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o $cargo_target_dir/mod_bench_llvm_0 -Cpanic=abort"
// COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o $cargo_target_dir/mod_bench_llvm_1 -Cpanic=abort"
// COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o $cargo_target_dir/mod_bench_llvm_2 -Cpanic=abort"
// COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o $cargo_target_dir/mod_bench_llvm_3 -Cpanic=abort"
//
// Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow
// hyperfine --runs ${COMPILE_RUNS:-100} "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3"
// echo "[BENCH RUN] mod_bench"
// hyperfine --runs ${RUN_RUNS:-10} $cargo_target_dir/mod_bench{,_inline} $cargo_target_dir/mod_bench_llvm_*
fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> {
if !args.is_using_gcc_master_branch() {
println!("Not using GCC master branch. Skipping `extended_rand_tests`.");

View file

@ -1,5 +1,6 @@
#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
#![feature(core_intrinsics, alloc_error_handler, lang_items)]
#![no_std]
#![no_main]
#![allow(internal_features)]
extern crate alloc;
@ -37,8 +38,8 @@ unsafe extern "C" fn _Unwind_Resume() {
core::intrinsics::unreachable();
}
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
let world: Box<&str> = Box::new("Hello World!\0");
unsafe {
puts(*world as *const str as *const u8);

View file

@ -1,7 +1,7 @@
// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
#![feature(
no_core, unboxed_closures, start, lang_items, never_type, linkage,
no_core, unboxed_closures, lang_items, never_type, linkage,
extern_types, thread_local
)]
#![no_core]

View file

@ -1,36 +0,0 @@
#![feature(start, core_intrinsics, lang_items)]
#![no_std]
#![allow(internal_features)]
#[link(name = "c")]
extern "C" {}
#[panic_handler]
fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! {
core::intrinsics::abort();
}
#[lang="eh_personality"]
fn eh_personality(){}
// Required for rustc_codegen_llvm
#[no_mangle]
unsafe extern "C" fn _Unwind_Resume() {
core::intrinsics::unreachable();
}
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
for i in 2..100_000_000 {
black_box((i + 1) % i);
}
0
}
#[inline(never)]
fn black_box(i: u32) {
if i != 1 {
core::intrinsics::abort();
}
}

View file

@ -64,6 +64,11 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
}
fn is_undef(&self, _val: RValue<'gcc>) -> bool {
// FIXME: actually check for undef
false
}
fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> {
let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined");
if typ.is_struct().is_some() {

View file

@ -513,7 +513,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
} else {
// If the symbol already exists, it is an error: for example, the user wrote
// #[no_mangle] extern "C" fn main(..) {..}
// instead of #[start]
None
}
}

View file

@ -113,15 +113,15 @@ fn make_mir_scope<'gcc, 'tcx>(
let scope_data = &mir.source_scopes[scope];
let parent_scope = if let Some(parent) = scope_data.parent_scope {
make_mir_scope(cx, _instance, mir, variables, debug_context, instantiated, parent);
debug_context.scopes[parent].unwrap()
debug_context.scopes[parent]
} else {
// The root is the function itself.
let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
debug_context.scopes[scope] = Some(DebugScope {
debug_context.scopes[scope] = DebugScope {
file_start_pos: file.start_pos,
file_end_pos: file.end_position(),
..debug_context.scopes[scope].unwrap()
});
..debug_context.scopes[scope]
};
instantiated.insert(scope);
return;
};
@ -130,7 +130,7 @@ fn make_mir_scope<'gcc, 'tcx>(
if !vars.contains(scope) && scope_data.inlined.is_none() {
// Do not create a DIScope if there are no variables defined in this
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
debug_context.scopes[scope] = Some(parent_scope);
debug_context.scopes[scope] = parent_scope;
instantiated.insert(scope);
return;
}
@ -157,12 +157,12 @@ fn make_mir_scope<'gcc, 'tcx>(
// TODO(tempdragon): dbg_scope: Add support for scope extension here.
inlined_at.or(p_inlined_at);
debug_context.scopes[scope] = Some(DebugScope {
debug_context.scopes[scope] = DebugScope {
dbg_scope,
inlined_at,
file_start_pos: loc.file.start_pos,
file_end_pos: loc.file.end_position(),
});
};
instantiated.insert(scope);
}
@ -232,12 +232,12 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
}
// Initialize fn debug context (including scopes).
let empty_scope = Some(DebugScope {
let empty_scope = DebugScope {
dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
inlined_at: None,
file_start_pos: BytePos(0),
file_end_pos: BytePos(0),
});
};
let mut fn_debug_context = FunctionDebugContext {
scopes: IndexVec::from_elem(empty_scope, mir.source_scopes.as_slice()),
inlined_function_scopes: Default::default(),

View file

@ -3,11 +3,12 @@
// Run-time:
// status: signal
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -49,7 +50,7 @@ fn test_fail() -> ! {
unsafe { intrinsics::abort() };
}
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
test_fail();
}

View file

@ -3,11 +3,12 @@
// Run-time:
// status: signal
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -50,8 +51,8 @@ fn fail() -> i32 {
0
}
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
fail();
0
}

View file

@ -7,10 +7,11 @@
// 5
// 10
#![feature(no_core, start)]
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
@ -28,8 +29,8 @@ fn make_array() -> [u8; 3] {
[42, 10, 5]
}
#[start]
fn main(argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let array = [42, 7, 5];
let array2 = make_array();
unsafe {

View file

@ -6,10 +6,11 @@
// 10
#![allow(internal_features, unused_attributes)]
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -142,8 +143,8 @@ fn inc(num: isize) -> isize {
}
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
argc = inc(argc);
unsafe {
libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);

View file

@ -8,10 +8,11 @@
// Int argument: 2
// Both args: 11
#![feature(no_core, start)]
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
@ -22,8 +23,8 @@ mod libc {
}
}
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let string = "Arg: %d\n\0";
let mut closure = || {
unsafe {

View file

@ -5,10 +5,11 @@
// stdout: true
// 1
#![feature(no_core, start)]
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
@ -19,8 +20,8 @@ mod libc {
}
}
#[start]
fn main(argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
unsafe {
if argc == 1 {
libc::printf(b"true\n\0" as *const u8 as *const i8);

View file

@ -3,11 +3,12 @@
// Run-time:
// status: 0
#![feature(auto_traits, lang_items, no_core, start)]
#![feature(auto_traits, lang_items, no_core)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
* Code
*/
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
0
}

View file

@ -3,11 +3,12 @@
// Run-time:
// status: 2
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
#![feature(auto_traits, lang_items, no_core, intrinsics)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
mod libc {
#[link(name = "c")]
@ -41,8 +42,8 @@ pub(crate) unsafe auto trait Freeze {}
* Code
*/
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
unsafe {
libc::exit(2);
}

View file

@ -3,11 +3,12 @@
// Run-time:
// status: 1
#![feature(auto_traits, lang_items, no_core, start)]
#![feature(auto_traits, lang_items, no_core)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
* Code
*/
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
1
}

View file

@ -4,10 +4,11 @@
// status: 0
// stdout: 1
#![feature(no_core, start)]
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
@ -26,8 +27,8 @@ fn call_func(func: fn(i16) -> i8, param: i16) -> i8 {
func(param)
}
#[start]
fn main(argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
unsafe {
let result = call_func(i16_as_i8, argc as i16) as isize;
libc::printf(b"%ld\n\0" as *const u8 as *const i8, result);

View file

@ -8,10 +8,11 @@
// 11
#![allow(internal_features, unused_attributes)]
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -148,8 +149,8 @@ fn update_num(num: &mut isize) {
*num = *num + 5;
}
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let mut test = test(argc);
unsafe {
libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);

View file

@ -6,10 +6,11 @@
// 10
#![allow(internal_features, unused_attributes)]
#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)]
#![feature(auto_traits, lang_items, no_core, intrinsics, arbitrary_self_types, rustc_attrs)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -231,8 +232,8 @@ pub fn panic_const_mul_overflow() -> ! {
* Code
*/
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
unsafe {
libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 + argc);
libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 - argc);

View file

@ -4,10 +4,11 @@
// status: 0
// stdout: 1
#![feature(no_core, start)]
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
@ -24,8 +25,8 @@ fn make_array() -> [u8; 3] {
[42, 10, 5]
}
#[start]
fn main(argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
unsafe {
let ptr = ONE as *mut usize;
let value = ptr as usize;

View file

@ -6,11 +6,12 @@
// 10
// 42
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
#![feature(auto_traits, lang_items, no_core, intrinsics)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
#[lang = "copy"]
pub unsafe trait Copy {}
@ -61,8 +62,8 @@ fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u3
)
}
#[start]
fn main(argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42);
unsafe {
libc::printf(b"%d\n\0" as *const u8 as *const i8, c);

View file

@ -4,10 +4,11 @@
// status: 0
// stdout: 5
#![feature(no_core, start)]
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
@ -26,8 +27,8 @@ fn index_slice(s: &[u32]) -> u32 {
}
}
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let array = [42, 7, 5];
unsafe {
libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array));

View file

@ -9,11 +9,12 @@
// 12
// 1
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -98,8 +99,8 @@ static mut WITH_REF: WithRef = WithRef {
refe: unsafe { &TEST },
};
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
unsafe {
libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT);
libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field);

View file

@ -5,11 +5,12 @@
// stdout: 1
// 2
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
#![feature(auto_traits, lang_items, no_core, intrinsics)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -55,8 +56,8 @@ fn one() -> isize {
1
}
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let test = Test {
field: one(),
};

View file

@ -4,11 +4,12 @@
// status: 0
// stdout: 3
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
#![feature(auto_traits, lang_items, no_core, intrinsics)]
#![allow(internal_features)]
#![no_std]
#![no_core]
#![no_main]
/*
* Core
@ -42,8 +43,8 @@ mod libc {
* Code
*/
#[start]
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let test: (isize, isize, isize) = (3, 1, 4);
unsafe {
libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0);

View file

@ -9,6 +9,8 @@ test = false
[dependencies]
# tidy-alphabetical-start
bitflags = "2.4.1"
# To avoid duplicate dependencies, this should match the version of gimli used
# by `rustc_codegen_ssa` via its `thorin-dwp` dependency.
gimli = "0.30"
itertools = "0.12"
libc = "0.2"

View file

@ -126,6 +126,10 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
unsafe { llvm::LLVMGetUndef(t) }
}
fn is_undef(&self, v: &'ll Value) -> bool {
unsafe { llvm::LLVMIsUndef(v) == True }
}
fn const_poison(&self, t: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMGetPoison(t) }
}

View file

@ -751,7 +751,6 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
} else {
// If the symbol already exists, it is an error: for example, the user wrote
// #[no_mangle] extern "C" fn main(..) {..}
// instead of #[start]
None
}
}

View file

@ -9,7 +9,7 @@ use rustc_middle::mir::{Body, SourceScope};
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
use rustc_middle::ty::{self, Instance};
use rustc_session::config::DebugInfo;
use rustc_span::{BytePos, hygiene};
use rustc_span::{BytePos, DUMMY_SP, hygiene};
use super::metadata::file_metadata;
use super::utils::DIB;
@ -85,23 +85,15 @@ fn make_mir_scope<'ll, 'tcx>(
discriminators,
parent,
);
if let Some(parent_scope) = debug_context.scopes[parent] {
parent_scope
} else {
// If the parent scope could not be represented then no children
// can be either.
debug_context.scopes[scope] = None;
instantiated.insert(scope);
return;
}
debug_context.scopes[parent]
} else {
// The root is the function itself.
let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
debug_context.scopes[scope] = Some(DebugScope {
debug_context.scopes[scope] = DebugScope {
file_start_pos: file.start_pos,
file_end_pos: file.end_position(),
..debug_context.scopes[scope].unwrap()
});
..debug_context.scopes[scope]
};
instantiated.insert(scope);
return;
};
@ -112,7 +104,7 @@ fn make_mir_scope<'ll, 'tcx>(
{
// Do not create a DIScope if there are no variables defined in this
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
debug_context.scopes[scope] = Some(parent_scope);
debug_context.scopes[scope] = parent_scope;
instantiated.insert(scope);
return;
}
@ -145,14 +137,7 @@ fn make_mir_scope<'ll, 'tcx>(
},
};
let mut debug_scope = Some(DebugScope {
dbg_scope,
inlined_at: parent_scope.inlined_at,
file_start_pos: loc.file.start_pos,
file_end_pos: loc.file.end_position(),
});
if let Some((_, callsite_span)) = scope_data.inlined {
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
let callsite_span = hygiene::walk_chain_collapsed(callsite_span, mir.span);
let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
let loc = cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span);
@ -175,29 +160,29 @@ fn make_mir_scope<'ll, 'tcx>(
// Note further that we can't key this hashtable on the span itself,
// because these spans could have distinct SyntaxContexts. We have
// to key on exactly what we're giving to LLVM.
let inlined_at = match discriminators.entry(callsite_span.lo()) {
match discriminators.entry(callsite_span.lo()) {
Entry::Occupied(mut o) => {
*o.get_mut() += 1;
// NB: We have to emit *something* here or we'll fail LLVM IR verification
// in at least some circumstances (see issue #135322) so if the required
// discriminant cannot be encoded fall back to the dummy location.
unsafe { llvm::LLVMRustDILocationCloneWithBaseDiscriminator(loc, *o.get()) }
.unwrap_or_else(|| {
cx.dbg_loc(callsite_scope, parent_scope.inlined_at, DUMMY_SP)
})
}
Entry::Vacant(v) => {
v.insert(0);
Some(loc)
}
};
match inlined_at {
Some(inlined_at) => {
debug_scope.as_mut().unwrap().inlined_at = Some(inlined_at);
}
None => {
// LLVM has a maximum discriminator that it can encode (currently
// it uses 12 bits for 4096 possible values). If we exceed that
// there is little we can do but drop the debug info.
debug_scope = None;
loc
}
}
}
});
debug_context.scopes[scope] = debug_scope;
debug_context.scopes[scope] = DebugScope {
dbg_scope,
inlined_at: inlined_at.or(parent_scope.inlined_at),
file_start_pos: loc.file.start_pos,
file_end_pos: loc.file.end_position(),
};
instantiated.insert(scope);
}

View file

@ -442,7 +442,7 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
// (or if there is no allocator argument).
ty::Adt(def, args)
if def.is_box()
&& args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) =>
&& args.get(1).is_none_or(|arg| cx.layout_of(arg.expect_ty()).is_1zst()) =>
{
build_pointer_or_reference_di_node(cx, t, t.expect_boxed_ty(), unique_type_id)
}

View file

@ -295,12 +295,12 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
// Initialize fn debug context (including scopes).
let empty_scope = Some(DebugScope {
let empty_scope = DebugScope {
dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
inlined_at: None,
file_start_pos: BytePos(0),
file_end_pos: BytePos(0),
});
};
let mut fn_debug_context = FunctionDebugContext {
scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes),
inlined_function_scopes: Default::default(),

View file

@ -741,8 +741,11 @@ pub mod debuginfo {
pub type DIEnumerator = DIDescriptor;
pub type DITemplateTypeParameter = DIDescriptor;
// These values **must** match with LLVMRustDIFlags!!
bitflags! {
/// Must match the layout of `LLVMDIFlags` in the LLVM-C API.
///
/// Each value declared here must also be covered by the static
/// assertions in `RustWrapper.cpp` used by `fromRust(LLVMDIFlags)`.
#[repr(transparent)]
#[derive(Clone, Copy, Default)]
pub struct DIFlags: u32 {
@ -752,7 +755,7 @@ pub mod debuginfo {
const FlagPublic = 3;
const FlagFwdDecl = (1 << 2);
const FlagAppleBlock = (1 << 3);
const FlagBlockByrefStruct = (1 << 4);
const FlagReservedBit4 = (1 << 4);
const FlagVirtual = (1 << 5);
const FlagArtificial = (1 << 6);
const FlagExplicit = (1 << 7);
@ -763,10 +766,21 @@ pub mod debuginfo {
const FlagStaticMember = (1 << 12);
const FlagLValueReference = (1 << 13);
const FlagRValueReference = (1 << 14);
const FlagExternalTypeRef = (1 << 15);
const FlagReserved = (1 << 15);
const FlagSingleInheritance = (1 << 16);
const FlagMultipleInheritance = (2 << 16);
const FlagVirtualInheritance = (3 << 16);
const FlagIntroducedVirtual = (1 << 18);
const FlagBitField = (1 << 19);
const FlagNoReturn = (1 << 20);
// The bit at (1 << 21) is unused, but was `LLVMDIFlagMainSubprogram`.
const FlagTypePassByValue = (1 << 22);
const FlagTypePassByReference = (1 << 23);
const FlagEnumClass = (1 << 24);
const FlagThunk = (1 << 25);
const FlagNonTrivial = (1 << 26);
const FlagBigEndian = (1 << 27);
const FlagLittleEndian = (1 << 28);
}
}
@ -918,6 +932,7 @@ unsafe extern "C" {
pub fn LLVMMetadataTypeInContext(C: &Context) -> &Type;
// Operations on all values
pub fn LLVMIsUndef(Val: &Value) -> Bool;
pub fn LLVMTypeOf(Val: &Value) -> &Type;
pub fn LLVMGetValueName2(Val: &Value, Length: *mut size_t) -> *const c_char;
pub fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t);

View file

@ -59,5 +59,5 @@ default-features = false
features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write", "wasm"]
[target.'cfg(windows)'.dependencies.windows]
version = "0.57.0"
version = "0.59.0"
features = ["Win32_Globalization"]

View file

@ -211,7 +211,7 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
.help = did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead
.help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point
codegen_ssa_no_field = no field `{$name}`

View file

@ -490,8 +490,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let ptr_ty = cx.type_ptr();
let (arg_argc, arg_argv) = get_argc_argv(&mut bx);
let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type
{
let EntryFnType::Main { sigpipe } = entry_type;
let (start_fn, start_ty, args, instance) = {
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
let start_instance = ty::Instance::expect_resolve(
cx.tcx(),
@ -512,10 +512,6 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
vec![rust_main, arg_argc, arg_argv, arg_sigpipe],
Some(start_instance),
)
} else {
debug!("using user-defined start fn");
let start_ty = cx.type_func(&[isize_ty, ptr_ty], isize_ty);
(rust_main, start_ty, vec![arg_argc, arg_argv], None)
};
let result = bx.call(start_ty, None, None, start_fn, &args, None, instance);
@ -530,7 +526,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}
/// Obtain the `argc` and `argv` values to pass to the rust start function.
/// Obtain the `argc` and `argv` values to pass to the rust start function
/// (i.e., the "start" lang item).
fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(bx: &mut Bx) -> (Bx::Value, Bx::Value) {
if bx.cx().sess().target.os.contains("uefi") {
// Params for UEFI

View file

@ -19,9 +19,7 @@ use crate::traits::*;
pub struct FunctionDebugContext<'tcx, S, L> {
/// Maps from source code to the corresponding debug info scope.
/// May be None if the backend is not capable of representing the scope for
/// some reason.
pub scopes: IndexVec<mir::SourceScope, Option<DebugScope<S, L>>>,
pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
/// Maps from an inlined function to its debug info declaration.
pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
@ -232,7 +230,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&self,
source_info: mir::SourceInfo,
) -> Option<(Bx::DIScope, Option<Bx::DILocation>, Span)> {
let scope = &self.debug_context.as_ref()?.scopes[source_info.scope]?;
let scope = &self.debug_context.as_ref()?.scopes[source_info.scope];
let span = hygiene::walk_chain_collapsed(source_info.span, self.mir.span);
Some((scope.adjust_dbg_scope_for_span(self.cx, span), scope.inlined_at, span))
}

View file

@ -204,14 +204,30 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
let alloc_align = alloc.inner().align;
assert!(alloc_align >= layout.align.abi);
// Returns `None` when the value is partially undefined or any byte of it has provenance.
// Otherwise returns the value or (if the entire value is undef) returns an undef.
let read_scalar = |start, size, s: abi::Scalar, ty| {
let range = alloc_range(start, size);
match alloc.0.read_scalar(
bx,
alloc_range(start, size),
range,
/*read_provenance*/ matches!(s.primitive(), abi::Primitive::Pointer(_)),
) {
Ok(val) => bx.scalar_to_backend(val, s, ty),
Err(_) => bx.const_poison(ty),
Ok(val) => Some(bx.scalar_to_backend(val, s, ty)),
Err(_) => {
// We may have failed due to partial provenance or unexpected provenance,
// continue down the normal code path if so.
if alloc.0.provenance().range_empty(range, &bx.tcx())
// Since `read_scalar` failed, but there were no relocations involved, the
// bytes must be partially or fully uninitialized. Thus we can now unwrap the
// information about the range of uninit bytes and check if it's the full range.
&& alloc.0.init_mask().is_range_initialized(range).unwrap_err() == range
{
Some(bx.const_undef(ty))
} else {
None
}
}
}
};
@ -222,16 +238,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
// check that walks over the type of `mplace` to make sure it is truly correct to treat this
// like a `Scalar` (or `ScalarPair`).
match layout.backend_repr {
BackendRepr::Scalar(s @ abi::Scalar::Initialized { .. }) => {
BackendRepr::Scalar(s) => {
let size = s.size(bx);
assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
let val = read_scalar(offset, size, s, bx.immediate_backend_type(layout));
OperandRef { val: OperandValue::Immediate(val), layout }
if let Some(val) = read_scalar(offset, size, s, bx.immediate_backend_type(layout)) {
return OperandRef { val: OperandValue::Immediate(val), layout };
}
}
BackendRepr::ScalarPair(
a @ abi::Scalar::Initialized { .. },
b @ abi::Scalar::Initialized { .. },
) => {
BackendRepr::ScalarPair(a, b) => {
let (a_size, b_size) = (a.size(bx), b.size(bx));
let b_offset = (offset + a_size).align_to(b.align(bx).abi);
assert!(b_offset.bytes() > 0);
@ -247,20 +261,21 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
b,
bx.scalar_pair_element_backend_type(layout, 1, true),
);
OperandRef { val: OperandValue::Pair(a_val, b_val), layout }
}
_ if layout.is_zst() => OperandRef::zero_sized(layout),
_ => {
// Neither a scalar nor scalar pair. Load from a place
// FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the
// same `ConstAllocation`?
let init = bx.const_data_from_alloc(alloc);
let base_addr = bx.static_addr_of(init, alloc_align, None);
let llval = bx.const_ptr_byte_offset(base_addr, offset);
bx.load_operand(PlaceRef::new_sized(llval, layout))
if let (Some(a_val), Some(b_val)) = (a_val, b_val) {
return OperandRef { val: OperandValue::Pair(a_val, b_val), layout };
}
}
_ if layout.is_zst() => return OperandRef::zero_sized(layout),
_ => {}
}
// Neither a scalar nor scalar pair. Load from a place
// FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the
// same `ConstAllocation`?
let init = bx.const_data_from_alloc(alloc);
let base_addr = bx.static_addr_of(init, alloc_align, None);
let llval = bx.const_ptr_byte_offset(base_addr, offset);
bx.load_operand(PlaceRef::new_sized(llval, layout))
}
/// Asserts that this operand refers to a scalar and returns

View file

@ -8,11 +8,11 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::{bug, mir, span_bug};
use rustc_session::config::OptLevel;
use rustc_span::{DUMMY_SP, Span};
use tracing::{debug, instrument};
use tracing::{debug, instrument, trace};
use super::FunctionCx;
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
use super::{FunctionCx, LocalRef};
use crate::common::IntPredicate;
use crate::traits::*;
use crate::{MemFlags, base};
@ -93,6 +93,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return;
}
// If `v` is an integer constant whose value is just a single byte repeated N times,
// emit a `memset` filling the entire `dest` with that byte.
let try_init_all_same = |bx: &mut Bx, v| {
let start = dest.val.llval;
let size = bx.const_usize(dest.layout.size.bytes());
@ -117,13 +119,33 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
false
};
trace!(?cg_elem.val);
match cg_elem.val {
OperandValue::Immediate(v) => {
if try_init_all_same(bx, v) {
return;
}
}
_ => (),
OperandValue::Pair(a, b) => {
let a_is_undef = bx.cx().is_undef(a);
match (a_is_undef, bx.cx().is_undef(b)) {
// Can happen for uninit unions
(true, true) => {
// FIXME: can we produce better output here?
}
(false, true) | (true, false) => {
let val = if a_is_undef { b } else { a };
if try_init_all_same(bx, val) {
return;
}
}
(false, false) => {
// FIXME: if both are the same value, use try_init_all_same
}
}
}
OperandValue::ZeroSized => unreachable!("checked above"),
OperandValue::Ref(..) => {}
}
let count = self
@ -365,10 +387,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
use abi::Primitive::*;
imm = bx.from_immediate(imm);
// When scalars are passed by value, there's no metadata recording their
// valid ranges. For example, `char`s are passed as just `i32`, with no
// way for LLVM to know that they're 0x10FFFF at most. Thus we assume
// the range of the input value too, not just the output range.
// If we have a scalar, we must already know its range. Either
//
// 1) It's a parameter with `range` parameter metadata,
// 2) It's something we `load`ed with `!range` metadata, or
// 3) After a transmute we `assume`d the range (see below).
//
// That said, last time we tried removing this, it didn't actually help
// the rustc-perf results, so might as well keep doing it
// <https://github.com/rust-lang/rust/pull/135610#issuecomment-2599275182>
self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
@ -389,7 +416,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.bitcast(int_imm, to_backend_ty)
}
};
// This `assume` remains important for cases like (a conceptual)
// transmute::<u32, NonZeroU32>(x) == 0
// since it's never passed to something with parameter metadata (especially
// after MIR inlining) so the only way to tell the backend about the
// constraint that the `transmute` introduced is to `assume` it.
self.assume_scalar_range(bx, imm, to_scalar, to_backend_ty);
imm = bx.to_immediate_scalar(imm, to_scalar);
imm
}
@ -411,31 +445,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return;
}
let abi::WrappingRange { start, end } = scalar.valid_range(self.cx);
if start <= end {
if start > 0 {
let low = bx.const_uint_big(backend_ty, start);
let cmp = bx.icmp(IntPredicate::IntUGE, imm, low);
bx.assume(cmp);
}
let type_max = scalar.size(self.cx).unsigned_int_max();
if end < type_max {
let high = bx.const_uint_big(backend_ty, end);
let cmp = bx.icmp(IntPredicate::IntULE, imm, high);
bx.assume(cmp);
}
} else {
let low = bx.const_uint_big(backend_ty, start);
let cmp_low = bx.icmp(IntPredicate::IntUGE, imm, low);
let high = bx.const_uint_big(backend_ty, end);
let cmp_high = bx.icmp(IntPredicate::IntULE, imm, high);
let or = bx.or(cmp_low, cmp_high);
bx.assume(or);
}
let range = scalar.valid_range(self.cx);
bx.assume_integer_range(imm, backend_ty, range);
}
pub(crate) fn codegen_rvalue_unsized(
@ -607,6 +618,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.codegen_place_to_pointer(bx, place, mk_ptr)
}
mir::Rvalue::Len(place) => {
let size = self.evaluate_array_len(bx, place);
OperandRef {
val: OperandValue::Immediate(size),
layout: bx.cx().layout_of(bx.tcx().types.usize),
}
}
mir::Rvalue::BinaryOp(op_with_overflow, box (ref lhs, ref rhs))
if let Some(op) = op_with_overflow.overflowing_to_wrapping() =>
{
@ -806,6 +825,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value {
// ZST are passed as operands and require special handling
// because codegen_place() panics if Local is operand.
if let Some(index) = place.as_local() {
if let LocalRef::Operand(op) = self.locals[index] {
if let ty::Array(_, n) = op.layout.ty.kind() {
let n = n
.try_to_target_usize(bx.tcx())
.expect("expected monomorphic const in codegen");
return bx.cx().const_usize(n);
}
}
}
// use common size calculation for non zero-sized types
let cg_value = self.codegen_place(bx, place.as_ref());
cg_value.len(bx.cx())
}
/// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref`
fn codegen_place_to_pointer(
&mut self,
@ -1077,6 +1114,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::Rvalue::Ref(..) |
mir::Rvalue::CopyForDeref(..) |
mir::Rvalue::RawPtr(..) |
mir::Rvalue::Len(..) |
mir::Rvalue::Cast(..) | // (*)
mir::Rvalue::ShallowInitBox(..) | // (*)
mir::Rvalue::BinaryOp(..) |

View file

@ -217,6 +217,27 @@ pub trait BuilderMethods<'a, 'tcx>:
dest: PlaceRef<'tcx, Self::Value>,
);
/// Emits an `assume` that the integer value `imm` of type `ty` is contained in `range`.
///
/// This *always* emits the assumption, so you probably want to check the
/// optimization level and `Scalar::is_always_valid` before calling it.
fn assume_integer_range(&mut self, imm: Self::Value, ty: Self::Type, range: WrappingRange) {
let WrappingRange { start, end } = range;
// Perhaps one day we'll be able to use assume operand bundles for this,
// but for now this encoding with a single icmp+assume is best per
// <https://github.com/llvm/llvm-project/issues/123278#issuecomment-2597440158>
let shifted = if start == 0 {
imm
} else {
let low = self.const_uint_big(ty, start);
self.sub(imm, low)
};
let width = self.const_uint_big(ty, u128::wrapping_sub(end, start));
let cmp = self.icmp(IntPredicate::IntULE, shifted, width);
self.assume(cmp);
}
fn range_metadata(&mut self, load: Self::Value, range: WrappingRange);
fn nonnull_metadata(&mut self, load: Self::Value);

View file

@ -9,6 +9,7 @@ pub trait ConstCodegenMethods<'tcx>: BackendTypes {
/// Generate an uninitialized value (matching uninitialized memory in MIR).
/// Whether memory is initialized or not is tracked byte-for-byte.
fn const_undef(&self, t: Self::Type) -> Self::Value;
fn is_undef(&self, v: Self::Value) -> bool;
/// Generate a fake value. Poison always affects the entire value, even if just a single byte is
/// poison. This can only be used in codepaths that are already UB, i.e., UB-free Rust code
/// (including code that e.g. copies uninit memory with `MaybeUninit`) can never encounter a

View file

@ -424,7 +424,7 @@ const_eval_unstable_in_stable_exposed =
.bypass_sugg = otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
const_eval_unstable_intrinsic = `{$name}` is not yet stable as a const intrinsic
.help = add `#![feature({$feature})]` to the crate attributes to enable
const_eval_unstable_intrinsic_suggestion = add `#![feature({$feature})]` to the crate attributes to enable
const_eval_unterminated_c_string =
reading a null-terminated string starting at {$pointer} with no null found before end of allocation

View file

@ -464,6 +464,12 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
err_span,
);
}
fn crate_inject_span(&self) -> Option<Span> {
self.tcx.hir_crate_items(()).definitions().next().and_then(|id| {
self.tcx.crate_level_attribute_injection_span(self.tcx.local_def_id_to_hir_id(id))
})
}
}
impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
@ -495,7 +501,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Rvalue::Use(_)
| Rvalue::CopyForDeref(..)
| Rvalue::Repeat(..)
| Rvalue::Discriminant(..) => {}
| Rvalue::Discriminant(..)
| Rvalue::Len(_) => {}
Rvalue::Aggregate(kind, ..) => {
if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref()
@ -579,27 +586,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
) => {}
Rvalue::ShallowInitBox(_, _) => {}
Rvalue::UnaryOp(op, operand) => {
Rvalue::UnaryOp(_, operand) => {
let ty = operand.ty(self.body, self.tcx);
match op {
UnOp::Not | UnOp::Neg => {
if is_int_bool_float_or_char(ty) {
// Int, bool, float, and char operations are fine.
} else {
span_bug!(
self.span,
"non-primitive type in `Rvalue::UnaryOp{op:?}`: {ty:?}",
);
}
}
UnOp::PtrMetadata => {
if !ty.is_ref() && !ty.is_unsafe_ptr() {
span_bug!(
self.span,
"non-pointer type in `Rvalue::UnaryOp({op:?})`: {ty:?}",
);
}
}
if is_int_bool_float_or_char(ty) {
// Int, bool, float, and char operations are fine.
} else {
span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
}
}
@ -823,6 +815,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
name: intrinsic.name,
feature,
const_stable_indirect: is_const_stable,
suggestion: self.crate_inject_span(),
});
}
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
@ -911,7 +904,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// regular stability.
feature == sym::rustc_private
&& issue == NonZero::new(27812)
&& self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
&& tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
};
// Even if the feature is enabled, we still need check_op to double-check
// this if the callee is not safe to expose on stable.
@ -921,6 +914,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
feature,
feature_enabled,
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
suggestion_span: self.crate_inject_span(),
});
}
}

View file

@ -1,8 +1,8 @@
//! Concrete error types for all operations which may be invalid in a certain const context.
use hir::{ConstContext, LangItem};
use rustc_errors::Diag;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
@ -388,6 +388,7 @@ pub(crate) struct FnCallUnstable {
/// expose on stable.
pub feature_enabled: bool,
pub safe_to_expose_on_stable: bool,
pub suggestion_span: Option<Span>,
}
impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
@ -407,8 +408,18 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
def_path: ccx.tcx.def_path_str(self.def_id),
});
// FIXME: make this translatable
let msg = format!("add `#![feature({})]` to the crate attributes to enable", self.feature);
#[allow(rustc::untranslatable_diagnostic)]
err.help(format!("add `#![feature({})]` to the crate attributes to enable", self.feature));
if let Some(span) = self.suggestion_span {
err.span_suggestion_verbose(
span,
msg,
format!("#![feature({})]\n", self.feature),
Applicability::MachineApplicable,
);
} else {
err.help(msg);
}
err
}
@ -436,6 +447,7 @@ pub(crate) struct IntrinsicUnstable {
pub name: Symbol,
pub feature: Symbol,
pub const_stable_indirect: bool,
pub suggestion: Option<Span>,
}
impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
@ -455,6 +467,8 @@ impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
span,
name: self.name,
feature: self.feature,
suggestion: self.suggestion,
help: self.suggestion.is_none(),
})
}
}

View file

@ -230,7 +230,9 @@ where
Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx))
}
Rvalue::Discriminant(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
Rvalue::Discriminant(place) | Rvalue::Len(place) => {
in_place::<Q, _>(cx, in_local, place.as_ref())
}
Rvalue::CopyForDeref(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),

View file

@ -197,6 +197,7 @@ where
| mir::Rvalue::CopyForDeref(..)
| mir::Rvalue::ThreadLocalRef(..)
| mir::Rvalue::Repeat(..)
| mir::Rvalue::Len(..)
| mir::Rvalue::BinaryOp(..)
| mir::Rvalue::NullaryOp(..)
| mir::Rvalue::UnaryOp(..)

View file

@ -123,12 +123,19 @@ pub(crate) struct UnstableConstFn {
#[derive(Diagnostic)]
#[diag(const_eval_unstable_intrinsic)]
#[help]
pub(crate) struct UnstableIntrinsic {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub feature: Symbol,
#[suggestion(
const_eval_unstable_intrinsic_suggestion,
code = "#![feature({feature})]\n",
applicability = "machine-applicable"
)]
pub suggestion: Option<Span>,
#[help(const_eval_unstable_intrinsic_suggestion)]
pub help: bool,
}
#[derive(Diagnostic)]

View file

@ -9,13 +9,12 @@ use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_middle::{bug, mir, span_bug};
use rustc_span::source_map::Spanned;
use rustc_span::{DesugaringKind, Span};
use rustc_target::callconv::FnAbi;
use tracing::{info, instrument, trace};
use super::{
FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
Projectable, interp_ok, throw_ub,
Projectable, Scalar, interp_ok, throw_ub,
};
use crate::util;
@ -81,9 +80,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
use rustc_middle::mir::StatementKind::*;
match &stmt.kind {
Assign(box (place, rvalue)) => {
self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
}
Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
SetDiscriminant { place, variant_index } => {
let dest = self.eval_place(**place)?;
@ -162,7 +159,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
&mut self,
rvalue: &mir::Rvalue<'tcx>,
place: mir::Place<'tcx>,
span: Span,
) -> InterpResult<'tcx> {
let dest = self.eval_place(place)?;
// FIXME: ensure some kind of non-aliasing between LHS and RHS?
@ -218,6 +214,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_repeat(operand, &dest)?;
}
Len(place) => {
let src = self.eval_place(place)?;
let len = src.len(self)?;
self.write_scalar(Scalar::from_target_usize(len, self), &dest)?;
}
Ref(_, borrow_kind, place) => {
let src = self.eval_place(place)?;
let place = self.force_allocation(&src)?;
@ -248,13 +250,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let src = self.eval_place(place)?;
let place = self.force_allocation(&src)?;
let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
if !place_base_raw
&& span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
{
if !place_base_raw {
// If this was not already raw, it needs retagging.
// As a special hack, we exclude the desugared `PtrMetadata(&raw const *_n)`
// from indexing. (Really we should not do any retag on `&raw` but that does not
// currently work with Stacked Borrows.)
val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
}
self.write_immediate(*val, &dest)?;

View file

@ -32,7 +32,7 @@ tracing = "0.1"
version = "0.12"
[target.'cfg(windows)'.dependencies.windows]
version = "0.57.0"
version = "0.59.0"
features = [
"Win32_Foundation",
"Win32_Storage_FileSystem",

View file

@ -60,9 +60,9 @@ impl Lock {
unsafe {
LockFileEx(
HANDLE(file.as_raw_handle() as isize),
HANDLE(file.as_raw_handle()),
flags,
0,
None,
u32::MAX,
u32::MAX,
&mut overlapped,

View file

@ -59,7 +59,7 @@ libc = "0.2"
# tidy-alphabetical-end
[target.'cfg(windows)'.dependencies.windows]
version = "0.57.0"
version = "0.59.0"
features = [
"Win32_System_Diagnostics_Debug",
]

View file

@ -53,7 +53,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_session::config::{
CG_OPTIONS, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType, UnstableOptions,
Z_OPTIONS, nightly_options,
Z_OPTIONS, nightly_options, parse_target_triple,
};
use rustc_session::getopts::{self, Matches};
use rustc_session::lint::{Lint, LintId};
@ -916,13 +916,7 @@ pub fn version_at_macro_invocation(
safe_println!("host: {}", config::host_tuple());
safe_println!("release: {release}");
let debug_flags = matches.opt_strs("Z");
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
let opts = config::Options::default();
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
let target = config::build_target_config(early_dcx, &opts, &sysroot);
get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_version();
get_backend_from_raw_matches(early_dcx, matches).print_version();
}
}
@ -1125,19 +1119,32 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
}
if cg_flags.iter().any(|x| *x == "passes=list") {
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
let opts = config::Options::default();
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
let target = config::build_target_config(early_dcx, &opts, &sysroot);
get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_passes();
get_backend_from_raw_matches(early_dcx, matches).print_passes();
return true;
}
false
}
/// Get the codegen backend based on the raw [`Matches`].
///
/// `rustc -vV` and `rustc -Cpasses=list` need to get the codegen backend before we have parsed all
/// arguments and created a [`Session`]. This function reads `-Zcodegen-backend`, `--target` and
/// `--sysroot` without validating any other arguments and loads the codegen backend based on these
/// arguments.
fn get_backend_from_raw_matches(
early_dcx: &EarlyDiagCtxt,
matches: &Matches,
) -> Box<dyn CodegenBackend> {
let debug_flags = matches.opt_strs("Z");
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
let target = parse_target_triple(early_dcx, matches);
let sysroot = filesearch::materialize_sysroot(matches.opt_str("sysroot").map(PathBuf::from));
let target = config::build_target_config(early_dcx, &target, &sysroot);
get_codegen_backend(early_dcx, &sysroot, backend_name, &target)
}
fn describe_debug_flags() {
safe_println!("\nAvailable options:\n");
print_flag_list("-Z", config::Z_OPTIONS);
@ -1191,15 +1198,6 @@ fn print_flag_list<T>(cmdline_opt: &str, flag_list: &[OptionDesc<T>]) {
/// be public when using rustc as a library, see
/// <https://github.com/rust-lang/rust/commit/2b4c33817a5aaecabf4c6598d41e190080ec119e>
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<getopts::Matches> {
if args.is_empty() {
// user did not write `-v` nor `-Z unstable-options`, so do not
// include that extra information.
let nightly_build =
rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build();
usage(false, false, nightly_build);
return None;
}
// Parse with *all* options defined in the compiler, we don't worry about
// option stability here we just want to parse as much as possible.
let mut options = getopts::Options::new();
@ -1245,7 +1243,7 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
// (unstable option being used on stable)
nightly_options::check_nightly_options(early_dcx, &matches, &config::rustc_optgroups());
if matches.opt_present("h") || matches.opt_present("help") {
if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
// Only show unstable options in --help if we accept unstable options.
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
let nightly_build = nightly_options::match_is_nightly_build(&matches);
@ -1530,9 +1528,9 @@ fn report_ice(
// If backtraces are enabled, also print the query stack
let backtrace = env::var_os("RUST_BACKTRACE").is_some_and(|x| &x != "0");
let num_frames = if backtrace { None } else { Some(2) };
let limit_frames = if backtrace { None } else { Some(2) };
interface::try_print_query_stack(dcx, num_frames, file);
interface::try_print_query_stack(dcx, limit_frames, file);
// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
// printed all the relevant info.

View file

@ -264,15 +264,15 @@ trait Foo {
### Trait contains associated constants
Just like static functions, associated constants aren't stored on the method
table. If the trait or any subtrait contain an associated constant, they cannot
be made into an object.
table. If the trait or any subtrait contain an associated constant, they are not
dyn compatible.
```compile_fail,E0038
trait Foo {
const X: i32;
}
impl Foo {}
impl dyn Foo {}
```
A simple workaround is to use a helper method instead:

View file

@ -1,32 +1,3 @@
#### Note: this error code is no longer emitted by the compiler.
A function with the `start` attribute was declared with type parameters.
Erroneous code example:
```compile_fail,E0132
#![feature(start)]
#[start]
fn f<T>() {}
```
It is not possible to declare type parameters on a function that has the `start`
attribute. Such a function must have the following type signature (for more
information, view [the unstable book][1]):
[1]: https://doc.rust-lang.org/unstable-book/language-features/start.html
```
# let _:
fn(isize, *const *const u8) -> isize;
```
Example:
```
#![feature(start)]
#[start]
fn my_start(argc: isize, argv: *const *const u8) -> isize {
0
}
```

View file

@ -1,25 +1,3 @@
#### Note: this error code is no longer emitted by the compiler.
More than one function was declared with the `#[start]` attribute.
Erroneous code example:
```compile_fail,E0138
#![feature(start)]
#[start]
fn foo(argc: isize, argv: *const *const u8) -> isize {}
#[start]
fn f(argc: isize, argv: *const *const u8) -> isize {}
// error: multiple 'start' functions
```
This error indicates that the compiler found multiple functions with the
`#[start]` attribute. This is an error because there must be a unique entry
point into a Rust program. Example:
```
#![feature(start)]
#[start]
fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
```

View file

@ -1,13 +1,3 @@
#### Note: this error code is no longer emitted by the compiler.
The `start` function was defined with a where clause.
Erroneous code example:
```compile_fail,E0647
#![feature(start)]
#[start]
fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
//^ error: `#[start]` function is not allowed to have a where clause
0
}
```

View file

@ -24,6 +24,10 @@
//
// Both columns are necessary because it's not possible in Rust to create a new identifier such as
// `E0123` from an integer literal such as `0123`, unfortunately.
//
// Do *not* remove entries from this list. Instead, just add a note th the corresponding markdown
// file saying that this error is not emitted by the compiler any more (see E0001.md for an
// example), and remove all code examples that do not build any more.
#[macro_export]
macro_rules! error_codes {
($macro:path) => (

View file

@ -31,7 +31,7 @@ tracing = "0.1"
# tidy-alphabetical-end
[target.'cfg(windows)'.dependencies.windows]
version = "0.57.0"
version = "0.59.0"
features = [
"Win32_Foundation",
"Win32_Security",

View file

@ -3146,7 +3146,7 @@ impl FileWithAnnotatedLines {
add_annotation_to_file(&mut output, Lrc::clone(&file), line, ann.as_line());
}
let line_end = ann.line_end - 1;
let end_is_empty = file.get_line(line_end - 1).map_or(false, |s| !filter(&s));
let end_is_empty = file.get_line(line_end - 1).is_some_and(|s| !filter(&s));
if middle < line_end && !end_is_empty {
add_annotation_to_file(&mut output, Lrc::clone(&file), line_end, ann.as_line());
}

View file

@ -463,7 +463,8 @@ impl DiagnosticSpan {
// is an empty string, increase the length to include the newline so we don't
// leave an empty line
if start.col.0 == 0
&& suggestion.map_or(false, |(s, _)| s.is_empty())
&& let Some((suggestion, _)) = suggestion
&& suggestion.is_empty()
&& let Ok(after) = je.sm.span_to_next_source(span)
&& after.starts_with('\n')
{

View file

@ -35,6 +35,7 @@ use std::backtrace::{Backtrace, BacktraceStatus};
use std::borrow::Cow;
use std::cell::Cell;
use std::error::Report;
use std::ffi::OsStr;
use std::hash::Hash;
use std::io::Write;
use std::num::NonZero;
@ -1717,7 +1718,7 @@ impl DiagCtxtInner {
let bugs: Vec<_> =
std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0");
let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
let decorate = backtrace || self.ice_file.is_none();
let mut out = self
.ice_file

View file

@ -391,7 +391,7 @@ impl<'a> StripUnconfigured<'a> {
validate_attr::deny_builtin_meta_unsafety(&self.sess.psess, &meta_item);
(
parse_cfg(&meta_item, self.sess).map_or(true, |meta_item| {
parse_cfg(&meta_item, self.sess).is_none_or(|meta_item| {
attr::cfg_matches(meta_item, &self.sess, self.lint_node_id, self.features)
}),
Some(meta_item),

View file

@ -159,7 +159,7 @@ impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'match
if self
.best_failure
.as_ref()
.map_or(true, |failure| failure.is_better_position(*approx_position))
.is_none_or(|failure| failure.is_better_position(*approx_position))
{
self.best_failure = Some(BestFailure {
token: token.clone(),

View file

@ -282,11 +282,13 @@ pub(super) fn transcribe<'a>(
}
MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => {
marker.visit_span(&mut sp);
with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
let kind = token::NtIdent(*ident, *is_raw);
TokenTree::token_alone(kind, sp)
}
MatchedSingle(ParseNtResult::Lifetime(ident, is_raw)) => {
marker.visit_span(&mut sp);
with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
let kind = token::NtLifetime(*ident, *is_raw);
TokenTree::token_alone(kind, sp)
}
@ -295,6 +297,8 @@ pub(super) fn transcribe<'a>(
// `Delimiter::Invisible` to maintain parsing priorities.
// `Interpolated` is currently used for such groups in rustc parser.
marker.visit_span(&mut sp);
let use_span = nt.use_span();
with_metavar_spans(|mspans| mspans.insert(use_span, sp));
TokenTree::token_alone(token::Interpolated(Lrc::clone(nt)), sp)
}
MatchedSeq(..) => {
@ -410,19 +414,15 @@ fn maybe_use_metavar_location(
return orig_tt.clone();
}
let insert = |mspans: &mut FxHashMap<_, _>, s, ms| match mspans.try_insert(s, ms) {
Ok(_) => true,
Err(err) => *err.entry.get() == ms, // Tried to insert the same span, still success
};
marker.visit_span(&mut metavar_span);
let no_collision = match orig_tt {
TokenTree::Token(token, ..) => {
with_metavar_spans(|mspans| insert(mspans, token.span, metavar_span))
with_metavar_spans(|mspans| mspans.insert(token.span, metavar_span))
}
TokenTree::Delimited(dspan, ..) => with_metavar_spans(|mspans| {
insert(mspans, dspan.open, metavar_span)
&& insert(mspans, dspan.close, metavar_span)
&& insert(mspans, dspan.entire(), metavar_span)
mspans.insert(dspan.open, metavar_span)
&& mspans.insert(dspan.close, metavar_span)
&& mspans.insert(dspan.entire(), metavar_span)
}),
};
if no_collision || psess.source_map().is_imported(metavar_span) {
@ -434,14 +434,14 @@ fn maybe_use_metavar_location(
match orig_tt {
TokenTree::Token(Token { kind, span }, spacing) => {
let span = metavar_span.with_ctxt(span.ctxt());
with_metavar_spans(|mspans| insert(mspans, span, metavar_span));
with_metavar_spans(|mspans| mspans.insert(span, metavar_span));
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
}
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
let open = metavar_span.with_ctxt(dspan.open.ctxt());
let close = metavar_span.with_ctxt(dspan.close.ctxt());
with_metavar_spans(|mspans| {
insert(mspans, open, metavar_span) && insert(mspans, close, metavar_span)
mspans.insert(open, metavar_span) && mspans.insert(close, metavar_span)
});
let dspan = DelimSpan::from_pair(open, close);
TokenTree::Delimited(dspan, *dspacing, *delimiter, tts.clone())

View file

@ -448,7 +448,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
// Entry point:
ungated!(start, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),

View file

@ -163,7 +163,7 @@ declare_features! (
/// then removed. But there was no utility storing it separately, so now
/// it's in this list.
(removed, no_stack_check, "1.0.0", None, None),
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn-compatible (object safe).
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible (object safe).
/// Renamed to `dyn_compatible_for_dispatch`.
(removed, object_safe_for_dispatch, "1.83.0", Some(43561),
Some("renamed to `dyn_compatible_for_dispatch`")),
@ -220,8 +220,9 @@ declare_features! (
(removed, rustc_diagnostic_macros, "1.38.0", None, None),
/// Allows identifying crates that contain sanitizer runtimes.
(removed, sanitizer_runtime, "1.17.0", None, None),
(removed, simd, "1.0.0", Some(27731),
Some("removed in favor of `#[repr(simd)]`")),
(removed, simd, "1.0.0", Some(27731), Some("removed in favor of `#[repr(simd)]`")),
/// Allows using `#[start]` on a function indicating that it is the program entrypoint.
(removed, start, "1.0.0", Some(29633), Some("not portable enough and never RFC'd")),
/// Allows `#[link(kind = "static-nobundle", ...)]`.
(removed, static_nobundle, "1.16.0", Some(37403),
Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#)),

View file

@ -272,7 +272,7 @@ declare_features! (
(unstable, doc_notable_trait, "1.52.0", Some(45040)),
/// Allows using the `may_dangle` attribute (RFC 1327).
(unstable, dropck_eyepatch, "1.10.0", Some(34761)),
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn-compatible[^1].
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1].
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
///
@ -300,8 +300,6 @@ declare_features! (
(internal, rustdoc_internals, "1.58.0", Some(90418)),
/// Allows using the `rustdoc::missing_doc_code_examples` lint
(unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730)),
/// Allows using `#[start]` on a function indicating that it is the program entrypoint.
(unstable, start, "1.0.0", Some(29633)),
/// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
/// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library
/// feature with the same name exists.
@ -722,7 +720,8 @@ impl Features {
/// Some features are not allowed to be used together at the same time, if
/// the two are present, produce an error.
///
/// Currently empty, but we will probably need this again in the future,
/// so let's keep it in for now.
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[];
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[
// Experimental match ergonomics rulesets are incompatible with each other, to simplify the
// boolean logic required to tell which typing rules to use.
(sym::ref_pat_eat_one_layer_2024, sym::ref_pat_eat_one_layer_2024_structural),
];

View file

@ -794,7 +794,7 @@ impl<Id> Res<Id> {
/// Always returns `true` if `self` is `Res::Err`
pub fn matches_ns(&self, ns: Namespace) -> bool {
self.ns().map_or(true, |actual_ns| actual_ns == ns)
self.ns().is_none_or(|actual_ns| actual_ns == ns)
}
/// Returns whether such a resolved path can occur in a tuple struct/variant pattern

View file

@ -332,6 +332,10 @@ language_item_table! {
FallbackSurfaceDrop, sym::fallback_surface_drop, fallback_surface_drop_fn, Target::Fn, GenericRequirement::None;
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
/// For all binary crates without `#![no_main]`, Rust will generate a "main" function.
/// The exact name and signature are target-dependent. The "main" function will invoke
/// this lang item, passing it the `argc` and `argv` (or null, if those don't exist
/// on the current target) as well as the user-defined `fn main` from the binary crate.
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;

View file

@ -489,21 +489,6 @@ hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is hi
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
hir_analysis_start_function_parameters = `#[start]` function is not allowed to have type parameters
.label = `#[start]` function cannot have type parameters
hir_analysis_start_function_where = `#[start]` function is not allowed to have a `where` clause
.label = `#[start]` function cannot have a `where` clause
hir_analysis_start_not_async = `#[start]` function is not allowed to be `async`
.label = `#[start]` is not allowed to be `async`
hir_analysis_start_not_target_feature = `#[start]` function is not allowed to have `#[target_feature]`
.label = `#[start]` function is not allowed to have `#[target_feature]`
hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
.label = `#[start]` function is not allowed to be `#[track_caller]`
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature

View file

@ -86,7 +86,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
if self.infcx.next_trait_solver()
&& let ty::Alias(..) = ty.kind()
{
let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
let (normalized_ty, obligations) = self.structurally_normalize_ty(ty)?;
self.state.obligations.extend(obligations);
(AutoderefKind::Builtin, normalized_ty)
} else {
@ -166,7 +166,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
}
let (normalized_ty, obligations) =
self.structurally_normalize(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
self.structurally_normalize_ty(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
self.state.obligations.extend(obligations);
@ -174,12 +174,12 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
}
#[instrument(level = "debug", skip(self), ret)]
pub fn structurally_normalize(
pub fn structurally_normalize_ty(
&self,
ty: Ty<'tcx>,
) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> {
let ocx = ObligationCtxt::new(self.infcx);
let Ok(normalized_ty) = ocx.structurally_normalize(
let Ok(normalized_ty) = ocx.structurally_normalize_ty(
&traits::ObligationCause::misc(self.span, self.body_id),
self.param_env,
ty,

View file

@ -5,7 +5,7 @@ use rustc_hir as hir;
use rustc_hir::Node;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode};
use rustc_middle::ty::{self, TyCtxt, TypingMode};
use rustc_session::config::EntryFnType;
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_span::{Span, sym};
@ -18,7 +18,6 @@ use crate::errors;
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
match tcx.entry_fn(()) {
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
_ => {}
}
}
@ -192,83 +191,3 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
});
}
}
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_def_id = start_def_id.expect_local();
let start_id = tcx.local_def_id_to_hir_id(start_def_id);
let start_span = tcx.def_span(start_def_id);
let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() {
ty::FnDef(..) => {
if let Node::Item(it) = tcx.hir_node(start_id) {
if let hir::ItemKind::Fn { sig, generics, .. } = &it.kind {
let mut error = false;
if !generics.params.is_empty() {
tcx.dcx().emit_err(errors::StartFunctionParameters { span: generics.span });
error = true;
}
if generics.has_where_clause_predicates {
tcx.dcx().emit_err(errors::StartFunctionWhere {
span: generics.where_clause_span,
});
error = true;
}
if sig.header.asyncness.is_async() {
let span = tcx.def_span(it.owner_id);
tcx.dcx().emit_err(errors::StartAsync { span });
error = true;
}
let attrs = tcx.hir().attrs(start_id);
for attr in attrs {
if attr.has_name(sym::track_caller) {
tcx.dcx().emit_err(errors::StartTrackCaller {
span: attr.span,
start: start_span,
});
error = true;
}
if attr.has_name(sym::target_feature)
// Calling functions with `#[target_feature]` is
// not unsafe on WASM, see #84988
&& !tcx.sess.target.is_like_wasm
&& !tcx.sess.opts.actually_rustdoc
{
tcx.dcx().emit_err(errors::StartTargetFeature {
span: attr.span,
start: start_span,
});
error = true;
}
}
if error {
return;
}
}
}
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
tcx.types.isize,
false,
hir::Safety::Safe,
ExternAbi::Rust,
));
let _ = check_function_signature(
tcx,
ObligationCause::new(
start_span,
start_def_id,
ObligationCauseCode::StartFunctionType,
),
start_def_id.into(),
expected_sig,
);
}
_ => {
span_bug!(start_span, "start has a non-function type: found `{}`", start_t);
}
}
}

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