Since RFC 3052 soft deprecated the authors field anyway, hiding it from
crates.io, docs.rs, and making Cargo not add it by default, and it is
not generally up to date/useful information, we should remove it from
crates in this repo.
Make const panic!("..") work in Rust 2021.
During const eval, this replaces calls to core::panicking::panic_fmt and std::panicking::being_panic_fmt with a call to a new const fn: core::panicking::const_panic_fmt. That function uses fmt::Arguments::as_str() to get the str and calls panic_str with that instead.
panic!() invocations with formatting arguments are still not accepted, as the creation of such a fmt::Arguments cannot be done in constant functions right now.
r? `@RalfJung`
During const eval, this replaces calls to core::panicking::panic_fmt and
std::panicking::being_panic_fmt with a call to a new const fn:
core::panicking::const_panic_fmt. That function uses
fmt::Arguments::as_str() to get the str and calls panic_str with that
instead.
panic!() invocations with formatting arguments are still not accepted,
as the creation of such a fmt::Arguments cannot be done in constant
functions right now.
get rid of NoMirFor error variant
The only place where we throw that error, it is very quickly caught again and turned into a different error. So raise that other error immediately.
Fix help message for modification to &T created by &{t}
Previous:
```rust
error[E0594]: cannot assign to `*x` which is behind a `&` reference
--> src/main.rs:3:5
|
2 | let x: &usize = &mut{0};
| ------- help: consider changing this to be a mutable reference: `&mut mut{0}`
3 | *x = 1;
| ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
```
rename const checking visitor module to check_consts::check
This avoids naming ambiguities with "const validation" which is in `interpret/validity.rs` and checks *values*.
r? `@oli-obk`
MIR opt: separate constant predecessors of a switch
For each block S ending with a switch, this pass copies S for each of S's predecessors that seem to assign the value being switched over as a const. This is done using a somewhat simple heuristic to determine what seems to be a const transitively.
More precisely, this is what the pass does:
- find a block that ends in a switch
- track if there is an unique place set before the current basic block that determines the result of the switch (this is the part that resolves switching over discriminants)
- if there is, iterate over the parents that have a reasonable terminator and find if the found determining place is likely to be (transitively) set from a const within that parent block
- if so, add the corresponding edge to a vector of edges to duplicate
- once this is done, iterate over the found edges: copy the target block and replace the reference to the target block in the origin block with the new block
This pass is not optimal and could probably duplicate in more cases, but the intention was mostly to address cases like in #85133 or #85365, to avoid creating new enums that get destroyed immediately afterwards (notably making the new try v2 `?` desugar zero-cost).
A benefit of this pass working the way it does is that it is easy to ensure its correctness: the worst that can happen is for it to needlessly copy a basic block, which is likely to be destroyed by cleanup passes afterwards. The complex parts where aliasing matters are only heuristics and the hard work is left to further passes like ConstProp.
# LLVM blocker
Unfortunately, I believe it would be unwise to enable this optimization by default for now. Indeed, currently switch lowering passes like SimplifyCFG in LLVM lose the information on the set of possible variant values, which means it tends to actually generate worse code with this optimization enabled. A fix would have to be done in LLVM itself. This is something I also want to look into. I have opened [a bug report at the LLVM bug tracker](https://bugs.llvm.org/show_bug.cgi?id=50455).
When this is done, I hope we can enable this pass by default. It should be fairly fast and I think it is beneficial in many cases. Notably, it should be a sound alternative to simplify-arm-identity. By the way, ConstProp only seems to pick up the optimization in functions that are not generic. This is however most likely an issue in ConstProp that I will look into afterwards.
This is my first contribution to rustc, and I would like to thank everyone on the Zulip mir-opt chat for the help and support, and especially `@scottmcm` for the guidance.
Refactor vtable format for upcoming trait_upcasting feature.
This modifies vtable format:
1. reordering occurrence order of methods coming from different traits
2. include `VPtr`s for supertraits where this vtable cannot be directly reused during trait upcasting.
Also, during codegen, the vtables corresponding to these newly included `VPtr` will be requested and generated.
For the cases where this vtable can directly used, now the super trait vtable has exactly the same content to some prefix of this one.
r? `@bjorn3`
cc `@RalfJung`
cc `@rust-lang/wg-traits`
Get back the more precise suggestion spans of old regionck
I noticed that when you turn on nll, the structured suggestion replaces a snippet instead of appending a snippet. It seems clearer to the user to only highlight the newly added characters instead of the entire `impl Trait` (and old regionck already does it this way).
r? ``@estebank``
CTFE/Miri engine Pointer type overhaul
This fixes the long-standing problem that we are using `Scalar` as a type to represent pointers that might be integer values (since they point to a ZST). The main problem is that with int-to-ptr casts, there are multiple ways to represent the same pointer as a `Scalar` and it is unclear if "normalization" (i.e., the cast) already happened or not. This leads to ugly methods like `force_mplace_ptr` and `force_op_ptr`.
Another problem this solves is that in Miri, it would make a lot more sense to have the `Pointer::offset` field represent the full absolute address (instead of being relative to the `AllocId`). This means we can do ptr-to-int casts without access to any machine state, and it means that the overflow checks on pointer arithmetic are (finally!) accurate.
To solve this, the `Pointer` type is made entirely parametric over the provenance, so that we can use `Pointer<AllocId>` inside `Scalar` but use `Pointer<Option<AllocId>>` when accessing memory (where `None` represents the case that we could not figure out an `AllocId`; in that case the `offset` is an absolute address). Moreover, the `Provenance` trait determines if a pointer with a given provenance can be cast to an integer by simply dropping the provenance.
I hope this can be read commit-by-commit, but the first commit does the bulk of the work. It introduces some FIXMEs that are resolved later.
Fixes https://github.com/rust-lang/miri/issues/841
Miri PR: https://github.com/rust-lang/miri/pull/1851
r? `@oli-obk`
During well-formed checking, we walk through all types 'nested' in
generic arguments. For example, WF-checking `Option<MyStruct<u8>>`
will cause us to check `MyStruct<u8>` and `u8`. However, this is done
on a `rustc_middle::ty::Ty`, which has no span information. As a result,
any errors that occur will have a very general span (e.g. the
definintion of an associated item).
This becomes a problem when macros are involved. In general, an
associated type like `type MyType = Option<MyStruct<u8>>;` may
have completely different spans for each nested type in the HIR. Using
the span of the entire associated item might end up pointing to a macro
invocation, even though a user-provided span is available in one of the
nested types.
This PR adds a framework for HIR-based well formed checking. This check
is only run during error reporting, and is used to obtain a more precise
span for an existing error. This is accomplished by individually
checking each 'nested' type in the HIR for the type, allowing us to
find the most-specific type (and span) that produces a given error.
The majority of the changes are to the error-reporting code. However,
some of the general trait code is modified to pass through more
information.
Since this has no soundness implications, I've implemented a minimal
version to begin with, which can be extended over time. In particular,
this only works for HIR items with a corresponding `DefId` (e.g. it will
not work for WF-checking performed within function bodies).
This resolves all the problems we had around "normalizing" the representation of a Scalar in case it carries a Pointer value: we can just use Pointer if we want to have a value taht we are sure is already normalized.
Improve error reporting for modifications behind `&` references
I had a look at #84210 and noticed that #85823 has effectively already fixed#84210.
However, the string matching in #85823 is _very_ crude and already breaks down when a variable name starts with `mut`. I have made this a bit more robust; further improvements could definitely be made but are complicated by the lack of information provided by an earlier pass:
ce331ee6ee/compiler/rustc_mir_build/src/build/matches/mod.rs (L2103-L2107)
I have also fixed a missing comma in the error message.
Use #[track_caller] in const panic diagnostics.
This change stops const panic diagnostics from reporting inside #[track_caller] functions by skipping over them.
- Add `:Sized` assertion in interpreter impl
- Use `Scalar::from_bool` instead of `ScalarInt: From<bool>`
- Remove unneeded comparison in intrinsic typeck
- Make this UB to call with undef, not just return undef in that case
Query-ify global limit attribute handling
Currently, we read various 'global limits' from inner attributes the crate root (`recursion_limit`, `move_size_limit`, `type_length_limit`, `const_eval_limit`). These limits are then stored in `Sessions`, allowing them to be access from a `TyCtxt` without registering a dependency on the crate root attributes.
This PR moves the calculation of these global limits behind queries, so that we properly track dependencies on crate root attributes. During the setup of macro expansion (before we've created a `TyCtxt`), we need to access the recursion limit, which is now done by directly calling into the code shared by the normal query implementations.
Hack: Ignore inference variables in certain queries
Fixes#84841Fixes#86753
Some queries are not built to accept types with inference variables, which can lead to ICEs. These queries probably ought to be converted to canonical form, but as a quick workaround, we can return conservative results in the case that inference variables are found.
We should file a follow-up issue (and update the FIXMEs...) to do the proper refactoring.
cc `@arora-aman`
r? `@oli-obk`
Support allocation failures when interpreting MIR
This closes#79601 by handling the case where memory allocation fails during MIR interpretation, and translates that failure into an `InterpError`. The error message is "tried to allocate more memory than available to compiler" to make it clear that the memory shortage is happening at compile-time by the compiler itself, and that it is not a runtime issue.
Now that memory allocation can fail, it would be neat if Miri could simulate low-memory devices to make it easy to see how much memory a Rust program needs.
Note that this breaks Miri because it assumes that allocation can never fail.
Introduce -Zprofile-closures to evaluate the impact of 2229
This creates a CSV with name "closure_profile_XXXXX.csv", where the
variable part is the process id of the compiler.
To profile a cargo project you can run one of the following depending on
if you're compiling a library or a binary:
```
cargo +nightly rustc --lib -- -Zprofile-closures
cargo +nightly rustc --bin {binary_name} -- -Zprofile-closures
```
r? `@nikomatsakis`
This creates a CSV with name "closure_profile_XXXXX.csv", where the
variable part is the process id of the compiler.
To profile a cargo project you can run one of the following depending on
if you're compiling a library or a binary:
```
cargo +stage1 rustc --lib -- -Zprofile-closures
cargo +stage1 rustc --bin -- -Zprofile-closures
```
Use HTTPS links where possible
While looking at #86583, I wondered how many other (insecure) HTTP links were in `rustc`. This changes most other `http` links to `https`. While most of the links are in comments or documentation, there are a few other HTTP links that are used by CI that are changed to HTTPS.
Notes:
- I didn't change any to or in licences
- Some links don't support HTTPS :(
- Some `http` links were dead, in those cases I upgraded them to their new places (all of which used HTTPS)
Fix `unused_unsafe` around `await`
Enables `unused_unsafe` lint for `unsafe { future.await }`.
The existing test for this is `unsafe { println!() }`, so I assume that `println!` used to contain compiler-generated unsafe but this is no longer true, and so the existing test is broken. I replaced the test with `unsafe { ...await }`. I believe `await` is currently the only instance of compiler-generated unsafe.
Reverts some parts of #85421, but the issue predates that PR.
Add MIR pass to lower call to `core::slice::len` into `Len` operand
During some larger experiment with range analysis I've found that code like `let l = slice.len()` produces different MIR then one found in bound checks. This optimization pass replaces terminators that are calls to `core::slice::len` with just a MIR operand and Goto terminator.
It uses some heuristics to remove the outer borrow that is made to call `core::slice::len`, but I assume it can be eliminated, just didn't find how.
Would like to express my gratitude to `@oli-obk` who helped me a lot on Zullip
Remove some last remants of {push,pop}_unsafe!
These macros have already been removed, but there was still some code handling these macros. That code is now removed.
Use better error message for hard errors in CTFE
I noticed this while working on #86255: currently the same message is used for hard errors and soft errors in CTFE. This changes the error messages to make hard errors use a message that indicates the reality of the situation correctly, since usage of the constant is never allowed when there was a hard error evaluating it. This doesn't affect the behaviour of these error messages, only the content.
This changes the error logic to check if the error should be hard or soft where it is generated, instead of where it is emitted, to allow this distinction in error messages.
Replace parent substs of associated types with inference vars in borrow checker
Fixes https://github.com/rust-lang/rust/issues/83190
Fixes https://github.com/rust-lang/rust/issues/78450
When we normalize an associated type that refers to an opaque type, it can happen that the substs of the associated type do not occur in the projection (they are parent substs). We previously didn't replace those substs with inference vars, which left a concrete region after all regions should have already been replaced with inference vars and triggered a `delay_span_bug`. After we normalize the opaque type, we now try to replace any remaining concrete regions with inference vars.
Stop returning a value from `report_assert_as_lint`
This function only ever returns `None`. Make that explicity by not returning a value at all.
`@rustbot` modify labels +C-cleanup +T-compiler
Refactor vtable codegen
This refactor the codegen of vtables of miri interpreter, llvm, cranelift codegen backends.
This is preparation for the implementation of trait upcasting feature. cc #65991
Note that aside from code reorganization, there's an internal behavior change here that now InstanceDef::Virtual's index now include the three metadata slots, and now the first method is with index 3.
cc `@RalfJung` `@bjorn3`
Currently the same message is used for hard errors and soft errors. This
makes hard errors use a message that indicates the reality of the
situation correctly, since usage of the constant is never allowed when
there was a hard error evaluating it.
Detect incorrect vtable alignment during const eval
This PR fixes#86132 by detecting invalid alignment values for trait objects in the interpreter, and emitting an error about this conversion failure, to avoid the ICE.
I've noticed that the error emitted at a50d72158e/compiler/rustc_mir/src/interpret/traits.rs (L163-L166) doesn't seem to be present in the const-ub tests, so I've tried adding a test that triggers both of these cases: one for the invalid size, and another for the invalid alignment that #86132 tracks (I have found different magic values triggering different `Align::from_bytes` errors than the "power of 2" one, if need be).
However, when doing that, I *cannot* for the life of me figure out the correct incantation to make these 2 errors trigger with the "it is undefined behavior to use this value" message rather than the "any use of this value will cause an error" lint.
I've tried Oli's suggestions of different values, tuples and arrays, using the transparent wrapper trick from the other tests and I was only able to trigger the regular const-ub errors about the size of the vtable, or that the drop pointer was invalid. Maybe these "type validation failed" errors happen before this part of the interpreter is reached and there just needs some magic incorrect values to bypass them, I don't know.
Since this fixes an ICE, and if the constants are indeed used, these 2 tests will turn into a hard error, I thought I'd open the PR anyways. And if ```@RalfJung``` you know of a way I could manage that (if you think that these tests are worth checking that the `throw_ub_format!` does indeed create const-ub errors as we expect) I'd be grateful.
For that reason, r? ```@RalfJung``` and cc ```@oli-obk.```