Avoid generating empty closures for fieldless enum variants
For many enums, this avoids generating lots of tiny stubs that need to be codegen'd and then inlined and removed by LLVM. perf shows this to be a fairly small, but significant, win on rustc bootstrap time -- with minimal impact on runtime performance (which is at times even positive).
Manually outline error on incremental_verify_ich
This reduces codegen for rustc_query_impl by 169k lines of LLVM IR, representing
a 1.2% improvement. This code should be fairly cold, so hopefully this has minimal
performance impact.
add codegen option for using LLVM stack smash protection
LLVM has built-in heuristics for adding stack canaries to functions. These
heuristics can be selected with LLVM function attributes. This PR adds a codegen
option `-C stack-protector={basic,strong,all}` which controls the use of these
attributes. This gives rustc the same stack smash protection support as clang
offers through options `-fstack-protector`, `-fstack-protector-strong`, and
`-fstack-protector-all`. The protection this can offer is demonstrated in
test/ui/abi/stack-protector.rs. This fills a gap in the current list of rustc
exploit mitigations (https://doc.rust-lang.org/rustc/exploit-mitigations.html),
originally discussed in #15179.
Stack smash protection adds runtime overhead and is therefore still off by
default, but now users have the option to trade performance for security as they
see fit. An example use case is adding Rust code in an existing C/C++ code base
compiled with stack smash protection. Without the ability to add stack smash
protection to the Rust code, the code base artifacts could be exploitable in
ways not possible if the code base remained pure C/C++.
Stack smash protection support is present in LLVM for almost all the current
tier 1/tier 2 targets: see
test/assembly/stack-protector/stack-protector-target-support.rs. The one
exception is nvptx64-nvidia-cuda. This PR follows clang's example, and adds a
warning message printed if stack smash protection is used with this target (see
test/ui/stack-protector/warn-stack-protector-unsupported.rs). Support for tier 3
targets has not been checked.
Since the heuristics are applied at the LLVM level, the heuristics are expected
to add stack smash protection to a fraction of functions comparable to C/C++.
Some experiments demonstrating how Rust code is affected by the different
heuristics can be found in
test/assembly/stack-protector/stack-protector-heuristics-effect.rs. There is
potential for better heuristics using Rust-specific safety information. For
example it might be reasonable to skip stack smash protection in functions which
transitively only use safe Rust code, or which uses only a subset of functions
the user declares safe (such as anything under `std.*`). Such alternative
heuristics could be added at a later point.
LLVM also offers a "safestack" sanitizer as an alternative way to guard against
stack smashing (see #26612). This could possibly also be included as a
stack-protection heuristic. An alternative is to add it as a sanitizer (#39699).
This is what clang does: safestack is exposed with option
`-fsanitize=safe-stack`.
The options are only supported by the LLVM backend, but as with other codegen
options it is visible in the main codegen option help menu. The heuristic names
"basic", "strong", and "all" are hopefully sufficiently generic to be usable in
other backends as well.
Avoid documenting top-level private imports
PR #88447 aimed to make rustdoc's `--document-private-items` mode only document imports that are visible outside the importing module. Unfortunately, I inadvertently set things up so that imports at the crate top-level are always documented, regardless of their visibility. This behavior was unintended and is [not desirable](https://github.com/rust-lang/rust/issues/90865#issuecomment-971172649).
This PR treats top-level imports as never being visible outside their parent module. In practice, the only way a top-level import can be visible externally is if it's fully public, and there's a seperate check for that.
It's worth calling attention to the fact that this change means that `pub(crate)` imports will be visible in lower level modules, but not at the top-level. This is because, at the top level of the crate, `pub(crate)` means the same thing as `pub(self)`.
It turned out that there were existing tests checking for the only behavior, which I didn't notice at the time of my previous PR. I have updated them to check for the new behavior and substantially extended them to handle differences between the top-level module and lower level modules. I may have gone overboard, so please tell me if there's anything I should cut.
r? `@jyn514`
Fixes#90865.
Update cargo
7 commits in ad50d0d266213e0cc4f6e526a39d96faae9a3842..e1fb17631eb1b3665cdbe45b1c186111577ef512
2021-11-17 18:36:37 +0000 to 2021-11-22 16:53:06 +0000
- re-enable lto_build test on 32-bit MSVC (rust-lang/cargo#10110)
- Fix a couple issues with cyclic features and dev-dependencies (rust-lang/cargo#10103)
- Add --message-format for install command (rust-lang/cargo#10107)
- Update curl dependency, remove M1 macOS build error note (rust-lang/cargo#10106)
- Make clippy happy (rust-lang/cargo#10105)
- Give a hard error if `-Zrustdoc-scrape-examples` is missing a flag (rust-lang/cargo#10043)
- silly fix, pointer to the empty slice (rust-lang/cargo#10097)
Update books
## reference
3 commits in a01d151a7250a540a9cb7ccce5956f020c677c21..c0f222da23568477155991d391c9ce918e381351
2021-10-22 22:34:13 +0900 to 2021-11-22 10:30:57 -0800
- Byte literal and string syntax: add missing quote escapes (rust-lang/reference#1101)
- fix crate_name attribute description (rust-lang/reference#1109)
- Update list of types with magic Copy impls (rust-lang/reference#1104)
## book
19 commits in 5c5dbc5b196c9564422b3193264f3288d2a051ce..a5e0c5b2c5f9054be3b961aea2c7edfeea591de8
2021-11-09 19:30:43 -0500 to 2021-11-19 17:06:19 -0500
- Propagate edits to chapter 4 back
- Edits to the edits of chapter 4
- ch 4 from nostarch
- Fix install links
- Snapshot of chapter 10
- Fix quotes
- Add more explanation of Self in chapter 10. Fixesrust-lang/book#2222.
- We've defined the signatures, not behaviors. Fixesrust-lang/book#2917
- Remove 'most distinctive' claim. Fixesrust-lang/book#2861.
- Clarify that traits must be brought into scope to use their methods
- Explain why lifetimes are part of the function contract better
- Further edits to rust-lang/book#2895
- Clarify generic types in mixin
- Change 'either' to 'at least one of'. See rust-lang/book#2885
- Clarify explanation of lifetime annotations a bit
- Further edits to clarify code explanation
- Clarify the meaning of a sentence in ch10-03
- Clarify this code is demonstrating usage of the library from a binary. Fixesrust-lang/book#1445.
- Clarify generics in method definitions and impls. Fixesrust-lang/book#2679.
## rust-by-example
1 commits in e9d45342d7a6c1def4731f1782d87ea317ba30c3..43f82530210b83cf888282b207ed13d5893da9b2
2021-11-02 13:33:03 -0500 to 2021-11-21 22:31:50 -0300
- Update `Development dependencies` page. (rust-lang/rust-by-example#1478)
## rustc-dev-guide
7 commits in 196ef69aa68f2cef44f37566ee7db37daf00301b..a2fc9635029c04e692474965a6606f8e286d539a
2021-11-07 07:48:47 -0600 to 2021-11-18 13:31:13 -0500
- Describe drop elaboration (rust-lang/rustc-dev-guide#1240)
- Fix an invalid link on Diagnostic Items (rust-lang/rustc-dev-guide#1261)
- Fix broken links related to `rustc_borrowck` (rust-lang/rustc-dev-guide#1259)
- Unify `x.py` usage (rust-lang/rustc-dev-guide#1258)
- Spelling fixes
- Fix compare-mode documentation
- Fix broken link in "Bootstrapping"
## edition-guide
1 commits in 27f4a84d3852e9416cae5861254fa53a825c56bd..8e0ec8c77d8b28b86159fdee9d33a758225ecf9c
2021-11-08 10:13:20 -0500 to 2021-11-12 06:30:23 -0800
- Fix a broken link in the Disjoint Capture in Closure chapter (rust-lang/edition-guide#273)
## embedded-book
1 commits in 51739471276b1776dea27cf562b974ef07e24685..8c395bdd8073deb20ca67e1ed4b14a3a7e315a37
2021-10-17 16:48:42 +0000 to 2021-11-14 11:38:31 +0000
- added math chapter (rust-embedded/book#308)
Set color for <a> in a more straightforward way.
Previously, we set the default color for <a> tags to black, and then had an override with a bunch of not() clauses to set anchors in
docblocks to blue.
Instead, we should set the default color for <a> to blue (or equivalent in other themes), and override it for places like the sidebar or search results, where we don't want them to be styled as links.
Demo at https://rustdoc.crud.net/jsha/theme-anchor/std/string/struct.String.html. This should result in no visible changes.
r? `@GuillaumeGomez`
LLVM has built-in heuristics for adding stack canaries to functions. These
heuristics can be selected with LLVM function attributes. This patch adds a
rustc option `-Z stack-protector={none,basic,strong,all}` which controls the use
of these attributes. This gives rustc the same stack smash protection support as
clang offers through options `-fno-stack-protector`, `-fstack-protector`,
`-fstack-protector-strong`, and `-fstack-protector-all`. The protection this can
offer is demonstrated in test/ui/abi/stack-protector.rs. This fills a gap in the
current list of rustc exploit
mitigations (https://doc.rust-lang.org/rustc/exploit-mitigations.html),
originally discussed in #15179.
Stack smash protection adds runtime overhead and is therefore still off by
default, but now users have the option to trade performance for security as they
see fit. An example use case is adding Rust code in an existing C/C++ code base
compiled with stack smash protection. Without the ability to add stack smash
protection to the Rust code, the code base artifacts could be exploitable in
ways not possible if the code base remained pure C/C++.
Stack smash protection support is present in LLVM for almost all the current
tier 1/tier 2 targets: see
test/assembly/stack-protector/stack-protector-target-support.rs. The one
exception is nvptx64-nvidia-cuda. This patch follows clang's example, and adds a
warning message printed if stack smash protection is used with this target (see
test/ui/stack-protector/warn-stack-protector-unsupported.rs). Support for tier 3
targets has not been checked.
Since the heuristics are applied at the LLVM level, the heuristics are expected
to add stack smash protection to a fraction of functions comparable to C/C++.
Some experiments demonstrating how Rust code is affected by the different
heuristics can be found in
test/assembly/stack-protector/stack-protector-heuristics-effect.rs. There is
potential for better heuristics using Rust-specific safety information. For
example it might be reasonable to skip stack smash protection in functions which
transitively only use safe Rust code, or which uses only a subset of functions
the user declares safe (such as anything under `std.*`). Such alternative
heuristics could be added at a later point.
LLVM also offers a "safestack" sanitizer as an alternative way to guard against
stack smashing (see #26612). This could possibly also be included as a
stack-protection heuristic. An alternative is to add it as a sanitizer (#39699).
This is what clang does: safestack is exposed with option
`-fsanitize=safe-stack`.
The options are only supported by the LLVM backend, but as with other codegen
options it is visible in the main codegen option help menu. The heuristic names
"basic", "strong", and "all" are hopefully sufficiently generic to be usable in
other backends as well.
Reviewed-by: Nikita Popov <nikic@php.net>
Extra commits during review:
- [address-review] make the stack-protector option unstable
- [address-review] reduce detail level of stack-protector option help text
- [address-review] correct grammar in comment
- [address-review] use compiler flag to avoid merging functions in test
- [address-review] specify min LLVM version in fortanix stack-protector test
Only for Fortanix test, since this target specifically requests the
`--x86-experimental-lvi-inline-asm-hardening` flag.
- [address-review] specify required LLVM components in stack-protector tests
- move stack protector option enum closer to other similar option enums
- rustc_interface/tests: sort debug option list in tracking hash test
- add an explicit `none` stack-protector option
Revert "set LLVM requirements for all stack protector support test revisions"
This reverts commit a49b74f92a4e7d701d6f6cf63d207a8aff2e0f68.
Mention std::io::Error::from(ErrorKind) in Error::new() docs
This conversion is not very discoverable for the cases
where an error is required without extra payload.
Previously, we set the default color for <a> tags to black, and then
had an override with a bunch of not() clauses to set anchors in
docblocks to blue.
Instead, we should set the default color for <a> to blue (or equivalent
in other themes), and override it for places like the sidebar or search
results, where we don't want them to be styled as links.
Check for duplicate attributes.
This adds some checks for duplicate attributes. In many cases, the duplicates were being ignored without error or warning. This adds several kinds of checks (see `AttributeDuplicates` enum).
The motivation here is to issue unused warnings with similar reasoning for any unused lint, and to error for cases where there are conflicts.
This also adds a check for empty attribute lists in a few attributes where this causes the attribute to be ignored.
Closes#55112.
Simplify `for` loop desugar
Basically two intermediate bindings are inlined. I could have left one intermediate binding in place as this would simplify some diagnostic logic, but I think the difference in that regard would be negligible, so it is better to have a minimal HIR.
For checking that the pattern is irrefutable, I added a special case when the `match` is found to be non-exhaustive.
The reordering of the arms is purely stylistic. I don't *think* there are any perf implications.
```diff
match IntoIterator::into_iter($head) {
mut iter => {
$label: loop {
- let mut __next;
match Iterator::next(&mut iter) {
- Some(val) => __next = val,
None => break,
+ Some($pat) => $block,
}
- let $pat = __next;
- $block
}
}
}
```
libcore: assume the input of `next_code_point` and `next_code_point_reverse` is UTF-8-like
The functions are now `unsafe` and they use `Option::unwrap_unchecked` instead of `unwrap_or_0`
`unwrap_or_0` was added in 42357d772b. I guess `unwrap_unchecked` was not available back then.
Given this example:
```rust
pub fn first_char(s: &str) -> Option<char> {
s.chars().next()
}
```
Previously, the following assembly was produced:
```asm
_ZN7example10first_char17ha056ddea6bafad1cE:
.cfi_startproc
test rsi, rsi
je .LBB0_1
movzx edx, byte ptr [rdi]
test dl, dl
js .LBB0_3
mov eax, edx
ret
.LBB0_1:
mov eax, 1114112
ret
.LBB0_3:
lea r8, [rdi + rsi]
xor eax, eax
mov r9, r8
cmp rsi, 1
je .LBB0_5
movzx eax, byte ptr [rdi + 1]
add rdi, 2
and eax, 63
mov r9, rdi
.LBB0_5:
mov ecx, edx
and ecx, 31
cmp dl, -33
jbe .LBB0_6
cmp r9, r8
je .LBB0_9
movzx esi, byte ptr [r9]
add r9, 1
and esi, 63
shl eax, 6
or eax, esi
cmp dl, -16
jb .LBB0_12
.LBB0_13:
cmp r9, r8
je .LBB0_14
movzx edx, byte ptr [r9]
and edx, 63
jmp .LBB0_16
.LBB0_6:
shl ecx, 6
or eax, ecx
ret
.LBB0_9:
xor esi, esi
mov r9, r8
shl eax, 6
or eax, esi
cmp dl, -16
jae .LBB0_13
.LBB0_12:
shl ecx, 12
or eax, ecx
ret
.LBB0_14:
xor edx, edx
.LBB0_16:
and ecx, 7
shl ecx, 18
shl eax, 6
or eax, ecx
or eax, edx
ret
```
After this change, the assembly is reduced to:
```asm
_ZN7example10first_char17h4318683472f884ccE:
.cfi_startproc
test rsi, rsi
je .LBB0_1
movzx ecx, byte ptr [rdi]
test cl, cl
js .LBB0_3
mov eax, ecx
ret
.LBB0_1:
mov eax, 1114112
ret
.LBB0_3:
mov eax, ecx
and eax, 31
movzx esi, byte ptr [rdi + 1]
and esi, 63
cmp cl, -33
jbe .LBB0_4
movzx edx, byte ptr [rdi + 2]
shl esi, 6
and edx, 63
or edx, esi
cmp cl, -16
jb .LBB0_7
movzx ecx, byte ptr [rdi + 3]
and eax, 7
shl eax, 18
shl edx, 6
and ecx, 63
or ecx, edx
or eax, ecx
ret
.LBB0_4:
shl eax, 6
or eax, esi
ret
.LBB0_7:
shl eax, 12
or eax, edx
ret
```
The functions are now `unsafe` and they use `Option::unwrap_unchecked` instead of `unwrap_or_0`
`unwrap_or_0` was added in 42357d772b. I guess `unwrap_unchecked` was not available back then.
Given this example:
```rust
pub fn first_char(s: &str) -> Option<char> {
s.chars().next()
}
```
Previously, the following assembly was produced:
```asm
_ZN7example10first_char17ha056ddea6bafad1cE:
.cfi_startproc
test rsi, rsi
je .LBB0_1
movzx edx, byte ptr [rdi]
test dl, dl
js .LBB0_3
mov eax, edx
ret
.LBB0_1:
mov eax, 1114112
ret
.LBB0_3:
lea r8, [rdi + rsi]
xor eax, eax
mov r9, r8
cmp rsi, 1
je .LBB0_5
movzx eax, byte ptr [rdi + 1]
add rdi, 2
and eax, 63
mov r9, rdi
.LBB0_5:
mov ecx, edx
and ecx, 31
cmp dl, -33
jbe .LBB0_6
cmp r9, r8
je .LBB0_9
movzx esi, byte ptr [r9]
add r9, 1
and esi, 63
shl eax, 6
or eax, esi
cmp dl, -16
jb .LBB0_12
.LBB0_13:
cmp r9, r8
je .LBB0_14
movzx edx, byte ptr [r9]
and edx, 63
jmp .LBB0_16
.LBB0_6:
shl ecx, 6
or eax, ecx
ret
.LBB0_9:
xor esi, esi
mov r9, r8
shl eax, 6
or eax, esi
cmp dl, -16
jae .LBB0_13
.LBB0_12:
shl ecx, 12
or eax, ecx
ret
.LBB0_14:
xor edx, edx
.LBB0_16:
and ecx, 7
shl ecx, 18
shl eax, 6
or eax, ecx
or eax, edx
ret
```
After this change, the assembly is reduced to:
```asm
_ZN7example10first_char17h4318683472f884ccE:
.cfi_startproc
test rsi, rsi
je .LBB0_1
movzx ecx, byte ptr [rdi]
test cl, cl
js .LBB0_3
mov eax, ecx
ret
.LBB0_1:
mov eax, 1114112
ret
.LBB0_3:
mov eax, ecx
and eax, 31
movzx esi, byte ptr [rdi + 1]
and esi, 63
cmp cl, -33
jbe .LBB0_4
movzx edx, byte ptr [rdi + 2]
shl esi, 6
and edx, 63
or edx, esi
cmp cl, -16
jb .LBB0_7
movzx ecx, byte ptr [rdi + 3]
and eax, 7
shl eax, 18
shl edx, 6
and ecx, 63
or ecx, edx
or eax, ecx
ret
.LBB0_4:
shl eax, 6
or eax, esi
ret
.LBB0_7:
shl eax, 12
or eax, edx
ret
```
Rollup of 4 pull requests
Successful merges:
- #91008 (Adds IEEE 754-2019 minimun and maximum functions for f32/f64)
- #91070 (Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable`)
- #91097 (Add spaces in opaque `impl Trait` with more than one trait)
- #91098 (Don't suggest certain fixups (`.field`, `.await`, etc) when reporting errors while matching on arrays )
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Don't suggest certain fixups (`.field`, `.await`, etc) when reporting errors while matching on arrays
When we have a type mismatch with a `cause.code` that is an `ObligationCauseCode::Pattern`, skip suggesting fixes like adding `.await` or accessing a struct's `.field` if the pattern's `root_ty` differs from the `expected` ty. This occurs in situations like this:
```rust
struct S(());
fn main() {
let array = [S(())];
match array {
[()] => {}
_ => {}
}
}
```
I think what's happening here is a layer of `[_; N]` is peeled off of both types and we end up seeing the mismatch between just `S` and `()`, but when we suggest a fixup, that applies to the expression with type `root_ty`.
---
Questions:
1. Should this check live here, above all of the suggestions, or should I push this down into every suggestion when we match `ObligationCauseCode`?
2. Any other `ObligationCauseCode`s to check here?
3. Am I overlooking an easier way to get to this same conclusion without pattern matching on `ObligationCauseCode` and comparing `root_ty`?
Fixes#91058
Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable`
`Module::getOrInsertGlobal` returns a `Constant*`, which is a super
class of `GlobalVariable`, but if the given type doesn't match an
existing declaration, it returns a bitcast of that global instead.
This causes UB when we pass that to `LLVMGetVisibility` which
unconditionally casts the opaque argument to a `GlobalValue*`.
Instead, we can do our own get-or-insert without worrying whether
existing types match exactly. It's not relevant when we're just trying
to get/set the linkage and visibility, and if types are needed we can
bitcast or error nicely from `rustc_codegen_llvm` instead.
Fixes#91050, fixes#87933, fixes#87813.
Adds IEEE 754-2019 minimun and maximum functions for f32/f64
IEEE 754-2019 removed the `minNum` (`min` in Rust) and `maxNum` (`max` in Rust) operations in favor of the newly created `minimum` and `maximum` operations due to their [non-associativity](https://grouper.ieee.org/groups/msc/ANSI_IEEE-Std-754-2019/background/minNum_maxNum_Removal_Demotion_v3.pdf) that cannot be fix in a backwards compatible manner. This PR adds `fN::{minimun,maximum}` functions following the new rules.
### IEEE 754-2019 Rules
> **minimum(x, y)** is x if x < y, y if y < x, and a quiet NaN if either operand is a NaN, according to 6.2.
For this operation, −0 compares less than +0. Otherwise (i.e., when x = y and signs are the same)
it is either x or y.
> **maximum(x, y)** is x if x > y, y if y > x, and a quiet NaN if either operand is a NaN, according to 6.2.
For this operation, +0 compares greater than −0. Otherwise (i.e., when x = y and signs are the
same) it is either x or y.
"IEEE Standard for Floating-Point Arithmetic," in IEEE Std 754-2019 (Revision of IEEE 754-2008) , vol., no., pp.1-84, 22 July 2019, doi: 10.1109/IEEESTD.2019.8766229.
### Implementation
This implementation is inspired by the one in [`glibc` ](90f0ac10a7/math/s_fminimum_template.c) (it self derived from the C2X draft) expect that:
- it doesn't use `copysign` because it's not available in `core` and also because `copysign` is unnecessary (we only want to check the sign, no need to create a new float)
- it also prefer `other > self` instead of `self < other` like IEEE 754-2019 does
I originally tried to implement them [using intrinsics](1d8aa13bc3) but LLVM [error out](https://godbolt.org/z/7sMrxW49a) when trying to lower them to machine intructions, GCC doesn't yet have built-ins for them, only cranelift support them nativelly (as it doesn't support the nativelly the old sementics).
Helps with https://github.com/rust-lang/rust/issues/83984
Point at source of trait bound obligations in more places
Be more thorough in using `ItemObligation` and `BindingObligation` when
evaluating obligations so that we can point at trait bounds that
introduced unfulfilled obligations. We no longer incorrectly point at
unrelated trait bounds (`substs-ppaux.verbose.stderr`).
In particular, we now point at trait bounds on method calls.
We no longer point at "obvious" obligation sources (we no longer have a
note pointing at `Trait` saying "required by a bound in `Trait`", like
in `associated-types-no-suitable-supertrait*`).
We no longer point at associated items (`ImplObligation`), as they didn't
add any user actionable information, they just added noise.
Address part of #89418.