tidy run
update invalid crate attributes, improve error
update test outputs
de-capitalise error
update tests
Update invalid crate attributes, add help message
Update - generate span without using BytePos
Add correct dependancies
Update - generate suggestion without BytePos
Tidy run
update tests
Generate Suggestion without BytePos
Add all builtin attributes
add err builtin inner attr at top of crate
fix tests
add err builtin inner attr at top of crate
tidy fix
add err builtin inner attr at top of crate
As discovered in #85461, the MSVC linker treats weak symbols slightly
differently than unix-y linkers do. This causes link.exe to fail with
LNK1227 "conflicting weak extern definition" where as other targets are
able to link successfully.
This changes the dead functions from being generated as weak/hidden to
private/default which, as the LLVM reference says:
> Global values with “private” linkage are only directly accessible by
objects in the current module. In particular, linking code into a module
with a private global value may cause the private to be renamed as
necessary to avoid collisions. Because the symbol is private to the
module, all references can be updated. This doesn’t show up in any
symbol table in the object file.
This fixes the conflicting weak symbols but doesn't address the reason
*why* we have conflicting symbols for these dead functions. The test
cases added in this commit contain a minimal repro of the fundamental
issue which is that the logic used to decide what dead code functions
should be codegen'd in the current CGU doesn't take into account that
functions can be duplicated across multiple CGUs (for instance, in the
case of `#[inline(always)]` functions).
Fixing that is likely to be a more complex change (see
https://github.com/rust-lang/rust/issues/85461#issuecomment-985005805).
Fixes#85461
Revert "Auto merge of #91354 - fee1-dead:const_env, r=spastorino"
This reverts commit 18bb8c61a9, reversing
changes made to d9baa36190.
Reverts #91354 in order to address #91489. We would need to place this changes in a more granular way and would also be nice to address the small perf regression that was also introduced.
r? `@oli-obk`
cc `@fee1-dead`
Optimize `rustc_lexer`
The `cursor.first()` method in `rustc_lexer` now calls the `chars.next()` method instead of `chars.nth_char(0)`.
This allows LLVM to optimize the code better. The biggest win is that `eat_while()` is now fully inlined and generates better assembly. This improves the lexer's performance by 35% in a micro-benchmark I made (Lexing all 18MB of code in the compiler directory). But lexing is only a small part of the overall compilation time, so I don't know how significant it is.
Big thanks to criterion and `cargo asm`.
Fix ICE #91268 by checking that the snippet ends with a `)`
Fix#91268
Previously it was assumed that the last character of `snippet` will be a `)`, so using `snippet.len() - 1` as an index should be safe. However as we see in the test, it is possible to enter that branch without a closing `)`, and it will trigger the panic if the last character happens to be multibyte.
The fix is to ensure that the snippet ends with `)`, and skip the suggestion otherwise.
Implement write() method for Box<MaybeUninit<T>>
This adds method similar to `MaybeUninit::write` main difference being
it returns owned `Box`. This can be used to elide copy from stack
safely, however it's not currently tested that the optimization actually
occurs.
Analogous methods are not provided for `Rc` and `Arc` as those need to
handle the possibility of sharing. Some version of them may be added in
the future.
This was discussed in #63291 which this change extends.
Looks like Generator drop shims already have `post_borrowck_cleanup` run
on them. That's a bit surprising, since it means they're getting const-
and maybe borrow-checked? This merits further investigation, but for now
just preserve the status quo.
Rollup of 12 pull requests
Successful merges:
- #89954 (Fix legacy_const_generic doc arguments display)
- #91321 (Handle placeholder regions in NLL type outlive constraints)
- #91329 (Fix incorrect usage of `EvaluatedToOk` when evaluating `TypeOutlives`)
- #91364 (Improve error message for incorrect field accesses through raw pointers)
- #91387 (Clarify and tidy up explanation of E0038)
- #91410 (Move `#![feature(const_precise_live_drops)]` checks earlier in the pipeline)
- #91435 (Improve diagnostic for missing half of binary operator in `if` condition)
- #91444 (disable tests in Miri that take too long)
- #91457 (Add additional test from rust issue number 91068)
- #91460 (Document how `last_os_error` should be used)
- #91464 (Document file path case sensitivity)
- #91466 (Improve the comments in `Symbol::interner`.)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Improve diagnostic for missing half of binary operator in `if` condition
Fixes#91421. I've also changed it so that it doesn't consume the `else` token in the error case, because it will try to consume it again afterwards, leading to this incorrect error message (where the `else` reported as missing is actually there):
```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found `{`
--> src/main.rs:4:12
|
4 | } else { 4 };
| ^ expected one of `.`, `;`, `?`, `else`, or an operator
```
r? `@lcnr`
Move `#![feature(const_precise_live_drops)]` checks earlier in the pipeline
Should mitigate the issues found during MCP on #73255.
Once this is done, we should clean up the queries a bit, since I think `mir_drops_elaborated_and_const_checked` can be merged back into `mir_promoted`.
Fixes#90770.
cc ``@rust-lang/wg-const-eval``
r? ``@nikomatsakis`` (since they reviewed #71824)
Clarify and tidy up explanation of E0038
I ran into E0038 (specifically the `Self:Sized` constraint on object-safety) the other day and it seemed to me that the explanations I found floating around the internet were a bit .. wrong. Like they didn't make sense. And then I went and checked the official explanation here and it didn't make sense either.
As far as I can tell (reading through the history of the RFCs), two totally different aspects of object-safety have got tangled up in much of the writing on the subject:
- Object-safety related to "not even theoretically possible" issues. This includes things like "methods that take or return Self by value", which obviously will never work for an unsized type in a world with fixed-size stack frames (and it'd be an opaque type anyways, which, ugh). This sort of thing was originally decided method-by-method, with non-object-safe methods stripped from objects; but in [RFC 0255](https://rust-lang.github.io/rfcs/0255-object-safety.html) this sort of per-impossible-method reasoning was made into a per-trait safety property (with the escape hatch left in where users could mark methods `where Self:Sized` to have them stripped before the trait's object safety is considered).
- Object-safety related to "totally possible but ergonomically a little awkward" issues. Specifically in a trait with `Trait:Sized`, there's no a priori reason why this constraint makes the trait impossible to make into an object -- imagine it had nothing but harmless `&self`-taking methods. No problem! Who cares if the Trait requires its implementing types to be sized? As far as I can tell reading the history here, in both RFC 0255 and then later in [RFC 0546](https://rust-lang.github.io/rfcs/0546-Self-not-sized-by-default.html) it seems that the motivation for making `Trait:Sized` be non-object-safe has _nothing to do_ with the impossibility of making objects out of such types, and everything to do with enabling "[a trait object SomeTrait to implement the trait SomeTrait](https://rust-lang.github.io/rfcs/0546-Self-not-sized-by-default.html#motivation)". That is, since `dyn Trait` is unsized, if `Trait:Sized` then you can never have the automatic (and reasonable) ergonomic implicit `impl Trait for dyn Trait`. And the authors of that RFC really wanted that automatic implicit implementation of `Trait` for `dyn Trait`. So they just defined `Trait:Sized` as non-object safe -- no `dyn Trait` can ever exist that the compiler can't synthesize such an impl for. Well enough!
However, I noticed in my reading-and-reconstruction that lots of documentation on the internet, including forum and Q&A site answers and (most worrying) the compiler explanation all kinda grasp at something like the first ("not theoretically possible") explanation, and fail to mention the second ("just an ergonomic constraint") explanation. So I figured I'd clean up the docs to clarify, maybe confuse the next person less (unless of course I'm misreading the history here and misunderstanding motives -- please let me know if so!)
While here I also did some cleanups:
- Rewrote the preamble, trying to help the user get a little better oriented (I found the existing preamble a bit scattered).
- Modernized notation (using `dyn Trait`)
- Changed the section headings to all be written with the same logical sense: to all be written as "conditions that violate object safety" rather than a mix of that and the negated form "conditions that must not happen in order to ensure object safety".
I think there's a fair bit more to clean up in this doc -- the later sections get a bit rambly and I suspect there should be a completely separated-out section covering the `where Self:Sized` escape hatch for instructing the compiler to "do the old thing" and strip methods off traits when turning them into objects (it's a bit buried as a digression in the individual sub-error sections). But I did what I had time for now.
Fix incorrect usage of `EvaluatedToOk` when evaluating `TypeOutlives`
A global predicate is not guarnatenteed to outlive all regions.
If the predicate involves late-bound regions, then it may fail
to outlive other regions (e.g. `for<'b> &'b bool: 'static` does not
hold)
We now only produce `EvaluatedToOk` when a global predicate has no
late-bound regions - in that case, the ony region that can be present
in the type is 'static
This adds method similar to `MaybeUninit::write` main difference being
it returns owned `Box`. This can be used to elide copy from stack
safely, however it's not currently tested that the optimization actually
occurs.
Analogous methods are not provided for `Rc` and `Arc` as those need to
handle the possibility of sharing. Some version of them may be added in
the future.
This was discussed in #63291 which this change extends.
Issue 90702 fix: Stop treating some crate loading failures as fatal errors
Surface mulitple `extern crate` resolution errors at a time.
This is achieved by creating a dummy crate, instead of aborting directly after the resolution error. The `ExternCrateError` has been added to allow propagating the resolution error from `rustc_metadata` crate to the `rustc_resolve` with a minimal public surface. The `import_extern_crate` function is a block that was factored out from `build_reduced_graph_for_item` for better organization. The only added functionality made to it where the added error handling in the `process_extern_crate` call. The remaining bits in this function are the same as before.
Resolves#90702
r? `@petrochenkov`
Disallow non-c-like but "fieldless" ADTs from being casted to integer if they use arbitrary enum discriminant
Code like
```rust
#[repr(u8)]
enum Enum {
Foo /* = 0 */,
Bar(),
Baz{}
}
let x = Enum::Bar() as u8;
```
seems to be unintentionally allowed so we couldn't disallow them now ~~, but we could disallow them if arbitrary enum discriminant is used before 1.56 hits stable~~ (stabilization was reverted).
Related: #88621
`@rustbot` label +T-lang
Cleanup: Eliminate ConstnessAnd
This is almost a behaviour-free change and purely a refactoring. "almost" because we appear to be using the wrong ParamEnv somewhere already, and this is now exposed by failing a test using the unstable `~const` feature.
We most definitely need to review all `without_const` and at some point should probably get rid of many of them by using `TraitPredicate` instead of `TraitRef`.
This is a continuation of https://github.com/rust-lang/rust/pull/90274.
r? `@oli-obk`
cc `@spastorino` `@ecstatic-morse`
... if they use arbitrary enum discriminant. Code like
```rust
enum Enum {
Foo = 1,
Bar(),
Baz{}
}
```
seems to be unintentionally allowed so we couldn't disallow them now,
but we could disallow them if arbitrary enum discriminant is used before
1.56 hits stable.
Include lint errors in error count for `-Ztreat-err-as-bug`
This was a regression from https://github.com/rust-lang/rust/pull/87337;
the `panic_if_treat_err_as_bug` function only checked the number of hard
errors, not the number of lint errors.
r? `@oli-obk`
expand: Turn `ast::Crate` into a first class expansion target
And stop creating a fake `mod` item for the crate root when expanding a crate, thus addressing FIXMEs left in https://github.com/rust-lang/rust/pull/82238, and making a step towards a proper support for crate-level macro attributes (cc #54726).
I haven't added token collection support for the whole crate in this PR, maybe later.
r? `@Aaron1011`
This was a regression from https://github.com/rust-lang/rust/pull/87337;
the `panic_if_treat_err_as_bug` function only checked the number of hard
errors, not the number of lint errors.
Fix bad `NodeId` limit checking.
`Resolver::next_node_id` converts a `u32` to a `usize` (which is
possibly bigger), does a checked add, and then converts the result back
to a `u32`. The `usize` conversion completely subverts the checked add!
This commit removes the conversion to/from `usize`.
Improve error message for `E0659` if the source is not available
Fixes#91028. The fix is similar to those in #89233 and #87088. With this change, instead of the dangling
```
note: `Option` could also refer to the enum defined here
```
I get
```
note: `Option` could also refer to an enum from prelude
```
If the standard library source code _is_ available, the output does not change.
Add support for LLVM coverage mapping format versions 5 and 6
This PR cherry-pick's Swatinem's initial commit in unsubmitted PR #90047.
My additional commit augments Swatinem's great starting point, but adds full support for LLVM
Coverage Mapping Format version 6, conditionally, if compiling with LLVM 13.
Version 6 requires adding the compilation directory when file paths are
relative, and since Rustc coverage maps use relative paths, we should
add the expected compilation directory entry.
Note, however, that with the compilation directory, coverage reports
from `llvm-cov show` can now report file names (when the report includes
more than one file) with the full absolute path to the file.
This would be a problem for test results, but the workaround (for the
rust coverage tests) is to include an additional `llvm-cov show`
parameter: `--compilation-dir=.`
When recovering from a `:` in a pattern, use adequate AST pattern
If the suggestion to use `::` instead of `:` in the pattern isn't correct, a second resolution error will be emitted.
`Resolver::next_node_id` converts a `u32` to a `usize` (which is
possibly bigger), does a checked add, and then converts the result back
to a `u32`. The `usize` conversion completely subverts the checked add!
This commit removes the conversion to/from `usize`.
Instead we run `RemoveFalseEdges` and `RemoveUninitDrops` at the
appropriate time. The extra `SimplifyCfg` avoids visiting unreachable
blocks during `RemoveUninitDrops`.
Otherwise dataflow state will propagate along false edges and cause
things to be marked as maybe init unnecessarily. These should be
separate, since `SimplifyBranches` also makes `if true {} else {}` into
a `goto`, which means we wouldn't lint anything in the `else` block.
This commit augments Swatinem's initial commit in uncommitted PR #90047,
which was a great starting point, but did not fully support LLVM
Coverage Mapping Format version 6.
Version 6 requires adding the compilation directory when file paths are
relative, and since Rustc coverage maps use relative paths, we should
add the expected compilation directory entry.
Note, however, that with the compilation directory, coverage reports
from `llvm-cov show` can now report file names (when the report includes
more than one file) with the full absolute path to the file.
This would be a problem for test results, but the workaround (for the
rust coverage tests) is to include an additional `llvm-cov show`
parameter: `--compilation-dir=.`
CTFE: support assert_zero_valid and assert_uninit_valid
This ensures the implementation of all three type-based assert_ intrinsics remains consistent in Miri.
`assert_inhabited` recently got stabilized in https://github.com/rust-lang/rust/pull/90896 (meaning stable `const fn` can call it), so do the same with these other intrinsics.
Cc ```@rust-lang/wg-const-eval```
Refactor EmitterWriter::emit_suggestion_default
Makes progress towards https://github.com/rust-lang/rust/issues/89979
Split into 2 commits:
* the first commit is purely a refactor and I verified that `./x.py test src/test/ui --stage 1` and `./x.py test src/test/rustdoc-ui --stage 1` continue to pass on this commit.
* ~~the second commit removes the empty trailing line from diff style suggestions.~~ - I discovered an issue with this so its just the refactor now.
r? diagnostics
This commit is intended to follow the stabilization disposition of the
FCP that has now finished in #84223. This stabilizes the ability to flag
thread local initializers as `const` expressions which enables the macro
to generate more efficient code for accessing it, notably removing
runtime checks for initialization.
More information can also be found in #84223 as well as the tests where
the feature usage was removed in this PR.
Closes#84223
Take a LocalDefId in expect_*item.
Items and item-likes are always HIR owners.
When trying to find such nodes, there is no ambiguity, the `LocalDefId` and the `HirId::owner` always match.
In such cases, `local_def_id_to_hir_id` does not carry any meaningful information, so we can just skip calling it altogether.
Nothing else makes sense, and there is no "danger" in doing so, as it only does something if there are const bounds, which are unstable. This used to happen implicitly via the inferctxt before, which was much more fragile.
Accumulate all values of `-C remark` option
When `-C remark=...` option is specified multiple times,
accumulate all values instead of using only the last one.
r? `@nikic`
Emit LLVM optimization remarks when enabled with `-Cremark`
The default diagnostic handler considers all remarks to be disabled by
default unless configured otherwise through LLVM internal flags:
`-pass-remarks`, `-pass-remarks-missed`, and `-pass-remarks-analysis`.
This behaviour makes `-Cremark` ineffective on its own.
Fix this by configuring a custom diagnostic handler that enables
optimization remarks based on the value of `-Cremark` option. With
`-Cremark=all` enabling all remarks.
Fixes#90924.
r? `@nikic`
A global predicate is not guarnatenteed to outlive all regions.
If the predicate involves late-bound regions, then it may fail
to outlive other regions (e.g. `for<'b> &'b bool: 'static` does not
hold)
We now only produce `EvaluatedToOk` when a global predicate has no
late-bound regions - in that case, the ony region that can be present
in the type is 'static
Fix ICE when lowering `trait A where for<'a> Self: 'a`
Fixes#88586.
r? `@jackh726`
Jack, this fix is much smaller in scope than what I think you were proposing in the issue. Let me know if you had a vision for a larger refactor here.
cc `@JohnTitor`
Perform Sync check on static items in wf-check instead of during const checks
r? `@RalfJung`
This check is solely happening on the signature of the static item and not on its body, therefor it belongs into wf-checking instead of const checking.
Make `TypeFolder::fold_*` return `Result`
Implements rust-lang/compiler-team#432.
Initially this is just a rebase of `@LeSeulArtichaut's` work in #85469 (abandoned; see https://github.com/rust-lang/rust/pull/85485#issuecomment-908781112). At that time, it caused a regression in performance that required some further exploration... with this rebased PR bors can hopefully report some perf analysis from which we can investigate further (if the regression is indeed still present).
r? `@jackh726` cc `@nikomatsakis`
Only check for errors in predicate when skipping impl assembly
Prior to PR #91205, checking for errors in the overall obligation
would check checking the `ParamEnv`, due to an incorrect
`super_visit_with` impl. With this bug fixed, we will now
bail out of impl candidate assembly if the `ParamEnv` contains
any error types.
In practice, this appears to be overly conservative - when an error
occurs early in compilation, we end up giving up early for some
predicates that we could have successfully evaluated without overflow.
By only checking for errors in the predicate itself, we avoid causing
additional spurious 'type annotations needed' errors after a 'real'
error has already occurred.
With this PR, the diagnostic changes caused by PR #91205 are reverted.
Prior to PR #91205, checking for errors in the overall obligation
would check checking the `ParamEnv`, due to an incorrect
`super_visit_with` impl. With this bug fixed, we will now
bail out of impl candidate assembly if the `ParamEnv` contains
any error types.
In practice, this appears to be overly conservative - when an error
occurs early in compilation, we end up giving up early for some
predicates that we could have successfully evaluated without overflow.
By only checking for errors in the predicate itself, we avoid causing
additional spurious 'type annotations needed' errors after a 'real'
error has already occurred.
With this PR, the diagnostic changes caused by PR #91205 are reverted.
Account for incorrect `where T::Assoc = Ty` bound
Provide suggestoin to constrain trait bound for associated type.
Revert incorrect changes to `missing-bounds` test.
Address part of #20041.
Rollup of 4 pull requests
Successful merges:
- #91169 (Change cg_ssa's get_param to borrow the builder mutably)
- #91176 (If the thread does not get the lock in the short term, yield the CPU)
- #91212 (Fix ICE due to out-of-bounds statement index when reporting borrowck error)
- #91225 (Fix invalid scrollbar display on source code page)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Fix ICE due to out-of-bounds statement index when reporting borrowck error
Replace an `[index]` with a `.get` when `statement_index` points to a basic-block terminator (and is therefore out-of-bounds in the statements list).
Fixes#91206
Cc ``@camsteffen``
r? ``@oli-obk``
Change cg_ssa's get_param to borrow the builder mutably
This is a small change to make `get_param` more flexible for codegens that may need to modify things when retrieving function parameters.
This will currently only be used by [rustc_codegen_nvvm](https://github.com/Rust-GPU/Rust-CUDA) (my own project), but may be useful to more codegens in the future.
This is needed because cg_nvvm needs to remap certain types to libnvvm-friendly types, such as `i128` -> `<2 x i64>`. Because cg_ssa does not give mutable access to the builder, i resorted to using a mutex:
```rs
fn get_param(&self, index: usize) -> Self::Value {
let val = llvm::get_param(self.llfn(), index as c_uint);
trace!("Get param `{:?}`", val);
unsafe {
let llfnty = LLVMRustGetFunctionType(self.llfn());
let map = self.remapped_integer_args.borrow();
if let Some((_, key)) = map.get(llfnty) {
if let Some((_, new_ty)) = key.iter().find(|t| t.0 == index) {
trace!("Casting irregular param {:?} to {:?}", val, new_ty);
return transmute_llval(
*self.llbuilder.lock().unwrap(),
&self.cx,
val,
*new_ty,
);
}
}
val
}
}
```
However, i predict this is pretty bad for performance, considering how much builders are called during codegen, so i would greatly appreciate having a more flexible API for this.
Fix stack overflow in `usefulness.rs`
Fix#88747
Applied the suggestion from `@nbdd0121,` not sure if this has any drawbacks. The first call to `ensure_sufficient_stack` is not needed to fix the test case, but I added it to be safe.
Visit `param_env` field in Obligation's `TypeFoldable` impl
This oversight appears to have gone unnoticed for a long time
without causing issues, but it should still be fixed.
Diagnostic tweaks
* On type mismatch caused by assignment, point at the source of the expectation
* Hide redundant errors
* Suggest `while let` when `let` is missing in some cases
* Do not emit unnecessary E0308 after E0070
* Show fewer errors on `while let` missing `let`
* Hide redundant E0308 on `while let` missing `let`
* Point at binding definition when possible on invalid assignment
* do not point at closure twice
* do not suggest `if let` for literals in lhs
* account for parameter types
Do not visit attributes in `ItemLowerer`.
By default, AST visitors visit expressions that appear in key-value attributes.
Those expressions should not be lowered to HIR, as they do not correspond to actually compiled code.
Since an attribute cannot produce meaningful HIR, just skip them altogether.
Fixes https://github.com/rust-lang/rust/issues/81886
Fixes https://github.com/rust-lang/rust/issues/90873
r? `@michaelwoerister`
Print associated types on opaque `impl Trait` types
This PR generalizes #91021, printing associated types for all opaque `impl Trait` types instead of just special-casing for future.
before:
```
error[E0271]: type mismatch resolving `<impl Iterator as Iterator>::Item == u32`
```
after:
```
error[E0271]: type mismatch resolving `<impl Iterator<Item = usize> as Iterator>::Item == u32`
```
---
Questions:
1. I'm kinda lost in binders hell with this one. Is all of the `rebind`ing necessary?
2. Is there a map collection type that will give me a stable iteration order? Doesn't seem like TraitRef is Ord, so I can't just sort later..
3. I removed the logic that suppresses printing generator projection types. It creates outputs like this [gist](https://gist.github.com/compiler-errors/d6f12fb30079feb1ad1d5f1ab39a3a8d). Should I put that back?
4. I also added spaces between traits, `impl A+B` -> `impl A + B`. I quite like this change, but is there a good reason to keep it like that?
r? ````@estebank````
Link with default MACOSX_DEPLOYMENT_TARGET if not otherwise specified.
This PR sets the MACOSX_DEPLOYMENT_TARGET environment variable during the linking stage to our default, if it is not specified. This way it matches the deployment target we pass to llvm. If not set the the linker uses Xcode or Xcode commandline tools default which varies by version.
Fixes#90342, #91082.
Drive-by fixes to make Rust behave more like clang:
* Default to 11.0 deployment target for ARM64 which is the earliest version that had support for it.
* Set the llvm target to `arm64-apple-macosx<deployment target>` instead of `aarch64-apple-macosx<deployment target>`.
Various fixes for const_trait_impl
A few problems I found while making `Iterator` easier to const-implement.
1. More generous `~const Drop` check.
We check for nested fields with caller bounds.
For example, an ADT type with fields of types `A`, `B`, `C`, check if all of them are either:
- Bounded (`A: ~const Drop`, `B: Copy`)
- Known to be able to destruct at compile time (`C = i32`, `struct C(i32)`, `C = some_fn`)
2. Don't treat trait functions marked with `#[default_method_body_is_const]` as stable const fns when checking `const_for` and `const_try` feature gates.
I think anyone can review this, so no r? this time.
Tokenize emoji as if they were valid identifiers
In the lexer, consider emojis to be valid identifiers and reject
them later to avoid knock down parse errors.
Partially address #86102.
Restrict aarch64 outline atomics to glibc for now.
The introduced dependency on `getauxval` causes linking problems with musl, making compiling any binaries for `aarch64-unknown-linux-musl` impossible without workarounds such as using lld or adding liblibc.rlib again to the linker invocation, see #89626.
This is a workaround until libc>0.2.108 is merged.
Optimize live point computation
This refactors the live-point computation to lower per-MIR-instruction costs by operating on a largely per-block level. This doesn't fundamentally change the number of operations necessary, but it greatly improves the practical performance by aggregating bit manipulation into ranges rather than single-bit; this scales much better with larger blocks.
On the benchmark provided in #90445, with 100,000 array elements, walltime for a check build is improved from 143 seconds to 15.
I consider the tiny losses here acceptable given the many small wins on real world benchmarks and large wins on stress tests. The new code scales much better, but on some subset of inputs the slightly higher constant overheads decrease performance somewhat. Overall though, this is expected to be a big win for pathological cases (as illustrated by the test case motivating this work) and largely not material for non-pathological cases. I consider the new code somewhat easier to follow, too.
fix(doctest): detect extern crate items in statement doctests
This partially reverts #91026, because rustdoc needs to detect the extern statements, even when they appear inside implicit `main()`. It does not entirely revert it, so the old bug is still fixed, by duplicating some of the logic from `parse_mod` instead of trying to use it directly.
Fixes#91134
By default, AST visitors visit expressions that appear in key-value attributes.
Those expressions should not be lowered to HIR, as they do not correspond to actually compiled code.
Since an attribute cannot produce meaningful HIR, just skip them altogether.
Rollup of 6 pull requests
Successful merges:
- #90856 (Suggestion to wrap inner types using 'allocator_api' in tuple)
- #91103 (Inhibit clicks on summary's children)
- #91137 (Give people a single link they can click in the contributing guide)
- #91140 (Split inline const to two feature gates and mark expression position inline const complete)
- #91148 (Use `derive_default_enum` in the compiler)
- #91153 (kernel_copy: avoid panic on unexpected OS error)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Split inline const to two feature gates and mark expression position inline const complete
This PR splits inline const in pattern position into its own `#![feature(inline_const_pat)]` feature gate, and make the usage in expression position complete.
I think I have resolved most outstanding issues related to `inline_const` with #89561 and other PRs. The only thing left that I am aware of is #90150 and the lack of lifetime checks when inline const is used in pattern position (FIXME in #89561). Implementation-wise when used in pattern position it has to be lowered during MIR building while in expression position it's evaluated only when monomorphizing (just like normal consts), so it makes some sense to separate it into two feature gates so one can progress without being blocked by another.
``@rustbot`` label: T-compiler F-inline_const
Suggestion to wrap inner types using 'allocator_api' in tuple
This PR provides a suggestion to wrap the inner types in tuple when being along with 'allocator_api'.
Closes https://github.com/rust-lang/rust/issues/83250
```rust
fn main() {
let _vec: Vec<u8, _> = vec![]; //~ ERROR use of unstable library feature 'allocator_api'
}
```
```diff
error[E0658]: use of unstable library feature 'allocator_api'
--> $DIR/suggest-vec-allocator-api.rs:2:23
|
LL | let _vec: Vec<u8, _> = vec![];
- | ^
+ | ----^
+ | |
+ | help: consider wrapping the inner types in tuple: `(u8, _)`
|
= note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
= help: add `#![feature(allocator_api)]` to the crate attributes to enable
```
Mark places as initialized when mutably borrowed
Fixes the example in #90752, but does not handle some corner cases involving raw pointers and unsafe. See [this comment](https://github.com/rust-lang/rust/issues/90752#issuecomment-965822895) for more information, or the second test.
Although I talked about both `MaybeUninitializedPlaces` and `MaybeInitializedPlaces` in #90752, this PR only changes the latter. That's because "maybe uninitialized" is the conservative choice, and marking them as definitely initialized (`!maybe_uninitialized`) when a mutable borrow is created could lead to problems if `addr_of_mut` to an uninitialized local is allowed. Additionally, places cannot become uninitialized via a mutable reference, so if a place is definitely initialized, taking a mutable reference to it should not change that.
I think it's correct to ignore interior mutability as nbdd0121 suggests below. Their analysis doesn't work inside of `core::cell`, which *does* have access to `UnsafeCell`'s field, but that won't be an issue unless we explicitly instantiate one with an `enum` within that module.
r? `@wesleywiser`
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.
This partially reverts #91026, because rustdoc needs to detect the extern statements,
even when they appear inside implicit `main()`. It does not entirely revert it,
so the old bug is still fixed, by duplicating some of the logic from `parse_mod`
instead of trying to use it directly.
Fixes#91134
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.
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.