fix normalizing in different `ParamEnv`s with the same `InferCtxt`
This PR changes the key of the projection cache from just `AliasTy` to `(AliasTy, ParamEnv)` to allow normalizing in different `ParamEnv`s without resetting caches. Previously, normalizing the same alias in different param envs would always reuse the cached result from the first normalization, which is incorrect if the projection clauses in the param env have changed.
Fixing this bug allows us to get rid of `InferCtxt::clear_caches`, which was only used by the `AutoTraitFinder`, because it requires normalizing in different param envs.
r? `@fmease`
Fix trait solver overflow with `non_local_definitions` lint
This PR fixes the trait solver overflow with the `non_local_definitions` lint reported in https://github.com/rust-lang/rust/issues/123573 using the suggestion from `@lcnr:` https://github.com/rust-lang/rust/issues/123573#issuecomment-2041348320 to use the next trait solver.
~~I have not (yet) tried to create a minimized repro~~ ``@compiler-errors`` did the minimization (thanks you) but I have manually tested on the `starlark-rust` project that it fixes the issue.
Fixes#123573
r? `@lcnr`
Flip spans for precise capturing syntax not capturing a ty/const param, and for implicit captures of lifetime params
Make the primary span point to the opaque, rather than the param which might be very far away (e.g. in an impl header hundreds of lines above).
This handles using deref patterns to choose the correct match arm. This
does not handle bindings or guards.
Co-authored-by: Deadbeef <ent3rm4n@gmail.com>
Fix capturing duplicated lifetimes via parent in `precise_captures` (`impl use<'...>`)
For technical reasons related to the way that `Self` and `T::Assoc` are lowered from HIR -> `rustc_middle::ty`, an opaque may mention in its bounds both the original early-bound lifetime from the parent `impl`/`fn`, *and* the *duplicated* early-bound lifetime on the opaque.
This is fine -- and has been fine since `@cjgillot` rewrote the way we handled opaque lifetime captures, and we went further to allow this behavior explicitly in https://github.com/rust-lang/rust/pull/115659. It's worthwhile to read this PR's technical section to recall how this duplication works and when it acts surprisingly.
The problem here is that the check that make sure that `impl use<'a, 'b>` lists all of the opaque's captured lifetimes wasn't smart enough to consider both these captured lifetimes and the original lifetimes they're duplicated from to be equal. This PR fixes that.
r? oli-obk
Implement Modified Condition/Decision Coverage
This is an implementation based on llvm backend support (>= 18) by `@evodius96` and branch coverage support by `@Zalathar.`
### Major changes:
* Add -Zcoverage-options=mcdc as switch. Now coverage options accept either `no-branch`, `branch`, or `mcdc`. `mcdc` also enables `branch` because it is essential to work.
* Add coverage mapping for MCDCBranch and MCDCDecision. Note that MCDCParameter evolves from llvm 18 to llvm 19. The mapping in rust side mainly references to 19 and is casted to 18 types in llvm wrapper.
* Add wrapper for mcdc instrinc functions from llvm. And inject associated statements to mir.
* Add BcbMappingKind::Decision, I'm not sure is it proper but can't find a better way temporarily.
* Let coverage-dump support parsing MCDCBranch and MCDCDecision from llvm ir.
* Add simple tests to check whether mcdc works.
* Same as clang, currently rustc does not generate instrument for decision with more than 6 condtions or only 1 condition due to considerations of resource.
### Implementation Details
1. To get information about conditions and decisions, `MCDCState` in `BranchInfoBuilder` is used during hir lowering to mir. For expressions with logical op we call `Builder::visit_coverage_branch_operation` to record its sub conditions, generate condition ids for them and save their spans (to construct the span of whole decision). This process mainly references to the implementation in clang and is described in comments over `MCDCState::record_conditions`. Also true marks and false marks introduced by branch coverage are used to detect where the decision evaluation ends: the next id of the condition == 0.
2. Once the `MCDCState::decision_stack` popped all recorded conditions, we can ensure that the decision is checked over and push it into `decision_spans`. We do not manually insert decision span to avoid complexity from then_else_break in nested if scopes.
3. When constructing CoverageSpans, add condition info to BcbMappingKind::Branch and decision info to BcbMappingKind::Decision. If the branch mapping has non-zero condition id it will be transformed to MCDCBranch mapping and insert `CondBitmapUpdate` statements to its evaluated blocks. While decision bcb mapping will insert `TestVectorBitmapUpdate` in all its end blocks.
### Usage
```bash
echo "[build]\nprofiler=true" >> config.toml
./x build --stage 1
./x test tests/coverage/mcdc_if.rs
```
to build the compiler and run tests.
```shell
export PATH=path/to/llvm-build:$PATH
rustup toolchain link mcdc build/host/stage1
cargo +mcdc rustc --bin foo -- -Cinstrument-coverage -Zcoverage-options=mcdc
cd target/debug
LLVM_PROFILE_FILE="foo.profraw" ./foo
llvm-profdata merge -sparse foo.profraw -o foo.profdata
llvm-cov show ./foo -instr-profile=foo.profdata --show-mcdc
```
to check "foo" code.
### Problems to solve
For now decision mapping will insert statements to its all end blocks, which may be optimized by inserting a final block of the decision. To do this we must also trace the evaluated value at each end of the decision and join them separately.
This implementation is not heavily tested so there should be some unrevealed issues. We are going to check our rust products in the next. Please let me know if you had any suggestions or comments.
Don't repeatedly duplicate TAIT lifetimes for each subsequently nested TAIT
Make it so that nested TAITs inherit the lifetimes from their parent item, not their parent TAIT. This is because we don't need to re-duplicate lifetimes for nested TAITs over and over, since the only lifetimes they can capture are from the parent item anyways.
This mirrors how RPITs work. This is **not** a functional change that should be observable, since the whole point of duplicating lifetimes and marking the shadowed ones (and uncaptured ones) as bivariant is designed to *not* be observable.
r? oli-obk
Don't inline integer literals when they overflow - new attempt
Basically #116633 but I implemented the suggested changes.
Fixes#115423. Fixes#116631.
This is my first contribution to this repo so please let me know if I'm supposed to change something :)
Properly handle emojis as literal prefix in macros
Do not accept the following
```rust
macro_rules! lexes {($($_:tt)*) => {}}
lexes!(🐛"foo");
```
Before, invalid emoji identifiers were gated during parsing instead of lexing in all cases, but this didn't account for macro pre-expansion of literal prefixes.
Fix#123696.
Match ergonomics 2024: miscellaneous code cleanups
- Store `ByRef` instead of `BindingAnnotation` in `PatInfo`
- Rename `BindingAnnotation` to `BindingMode`
r? ``@Nadrieril``
cc #123076
``@rustbot`` label A-patterns
Delay interning errors to after validation
fixes https://github.com/rust-lang/rust/issues/122398fixes#122548
This improves diagnostics since validation errors are usually more helpful compared with interning errors that just make broad statements about the entire constant
r? `@RalfJung`
Codegen ZSTs without an allocation
This makes sure that &[] is equivalent to unsafe code (from_raw_parts(dangling, 0)). No new stable guarantee is intended about whether or not we do this, this is just an optimization.
This regressed in #67000 (no comments I can see about that regression in the PR, though it did change the test modified here). We had previously performed this optimization since #63635.
Remove libc from rust_get_test_int uses
`rust_test_helpers.c` has a few unfortunate signatures which have made some of our UI tests _technically_ need the `libc` crate. This is my attempt to evict the need of `libc` for `rust_get_test_int`.
I've deleted `tests/ui/abi/foreign/foreign-no-abi.rs` because the test was originally written to check that `native mod` will compile without an ABI specifier. `native mod` was removed years before 1.0 and the test hasn't checked for anything for a long time.
Delay span bug when `Self` kw resolves to `DefKind::{Mod,Trait}`
Catch the case where `kw::Self` is recovered in the parser and causes us to subsequently resolve `&self`'s implicit type to something that's not a type.
This check could be made more accurate, though I'm not sure how hard we have to try here.
Fixes#123988
This makes sure that &[] is just as efficient as indirecting through
unsafe code (from_raw_parts). No new stable guarantee is intended about
whether or not we do this, this is just an optimization.
Co-authored-by: Ralf Jung <post@ralfj.de>
Use `/* value */` as a placeholder
The expression `value` isn't a valid suggestion; let's use `/* value */` as a placeholder (which is also invalid) since it more clearly signals to the user that they need to fill it in with something meaningful. This parallels the suggestions we have in a couple other places, like arguments.
We could also print the type name instead of `/* value */`, especially if it's suggestable, but I don't care strongly about that.
Taint const qualifs if a static is referenced that didn't pass wfcheck
It is correct to only check the signature here, as the ICE is caused by `USE_WITH_ERROR` trying to allocate memory to store the result of `WITH_ERROR` before evaluating it.
fixes#123153
Stabilize checking of cfgs at compile-time: `--check-cfg` option
This PR stabilize the `--check-cfg` CLI option of `rustc` (and `rustdoc`) 🎉.
In particular this PR does two things:
1. it makes the `--check-cfg` option stable
2. and it moves the documentation to the stable books
FCP: https://github.com/rust-lang/rust/issues/82450#issuecomment-1965328542Resolves#82450
``@rustbot`` labels +S-blocked +F-check-cfg
r? ``@petrochenkov``
Implement syntax for `impl Trait` to specify its captures explicitly (`feature(precise_capturing)`)
Implements `impl use<'a, 'b, T, U> Sized` syntax that allows users to explicitly list the captured parameters for an opaque, rather than inferring it from the opaque's bounds (or capturing *all* lifetimes under 2024-edition capture rules). This allows us to exclude some implicit captures, so this syntax may be used as a migration strategy for changes due to #117587.
We represent this list of captured params as `PreciseCapturingArg` in AST and HIR, resolving them between `rustc_resolve` and `resolve_bound_vars`. Later on, we validate that the opaques only capture the parameters in this list.
We artificially limit the feature to *require* mentioning all type and const parameters, since we don't currently have support for non-lifetime bivariant generics. This can be relaxed in the future.
We also may need to limit this to require naming *all* lifetime parameters for RPITIT, since GATs have no variance. I have to investigate this. This can also be relaxed in the future.
r? `@oli-obk`
Tracking issue:
- https://github.com/rust-lang/rust/issues/123432
Trait predicates for types which have errors may still
evaluate to OK leading to downstream ICEs. Now we return
a selection error for such types in candidate assembly and
thereby prevent such issues
Fix pretty HIR for anon consts in diagnostics
This removes the `NoAnn` printer which skips over nested bodies altogether, which is confusing, and requires users of `{ty|qpath|pat}_to_string` to pass in `&tcx` which now impleemnts `hir_pretty::PpAnn`.
There's one case where this "regresses" by actually printing out the body of the anon const -- we could suppress that, but I don't expect people to actually get anon consts like that unless they're fuzzing, tbh.
r? estebank
Don't even parse an intrinsic unless the feature gate is enabled
Don't return true in `tcx.is_intrinsic` if the function is defined locally and `#![feature(intrinsics)]` is not enabled. This is a slightly more general fix than #123526, since #123587 shows that we have simplifying assumptions about intrinsics elsewhere in the compiler.
This will make the code ICE again if the user **enables** `#[feature(intrinsics)]`, but I kind of feel like if we want to fix that, we should make the `INTERNAL_FEATURES` lint `Deny` again. Perhaps we could do that on non-nightly compilers. Or we should just stop compilation altogether if they have `#![feature]` enabled on a non-nightly compiler.
As for the UX of *real* cases of hitting these ICEs, I believe pretty strongly that if a compiler/stdlib dev is modifying internal intrinsics (intentionally, like when making a change to rustc) we have no guarantee to make the ICE better looking for them. Honestly, *not* spitting out a stack trace is probably a disservice to the people who hit those ICEs in that case.
r? `@Nilstrieb` `@estebank`
Use the rustc_private libc less in tests
I started looking into our use of `rustc_private` + `extern crate libc;` in tests because of https://github.com/rust-lang/rust/pull/123938 and it looks like some fraction of the users of libc simply don't need the libc crate anymore.
Fix various bugs in `ty_kind_suggestion`
Consolidates two implementations of `ty_kind_suggestion`
Fixes some misuse of the empty param-env
Fixes a problem where we suggested `(42)` instead of `(42,)` for tuple suggestions
Suggest a value when `return;`, making it consistent with `break;`
Fixes#123906
builtin-derive: tag → discriminant
As far as I can tell, all of this operates on the discriminant, not the tag. After all, with something like `Option<&T>`, the "tag" of the `Some` variant is basically just the reference value, which is never what you want to compare when figuring out which variant the enum is in.
See [here](https://rustc-dev-guide.rust-lang.org/appendix/glossary.html) for an explanation of the difference between tag and discriminant.
Discard overflow obligations in `impl_may_apply`
Hacky fix for #123493. Throws away obligations that are overflowing in `impl_may_apply` when we recompute if an impl applies, since those will lead to fatal overflow if processed during fulfillment.
Something about #114811 (I think it's the predicate reordering) caused us to evaluate predicates differently in error reporting leading to fatal overflow, though I believe the underlying overflow is possible to hit since this code was rewritten to use fulfillment.
Fixes#123493
Get rid of `USIZE_MARKER` in formatting infrastructure
An alternative to #123780.
The `USIZE_MARKER` function used to differentiate between placeholder and count arguments is never called anyway, so we can just replace the function-pointer-comparison hack with an `enum` and an `unreachable_unchecked`, hopefully without causing a regression.
CC `@RalfJung`
Add a test that fails if `#[unix_sigpipe = "inherit"]` wrongly results
in `SIGPIPE` being `SIG_DFL` if the parent has `SIG_IGN`. We have no
current test for this particular case.
Detect borrow checker errors where `.clone()` would be an appropriate user action
When a value is moved twice, suggest cloning the earlier move:
```
error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
--> $DIR/union-move.rs:49:18
|
LL | move_out(x.f1_nocopy);
| ^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `x.f1_nocopy` has type `ManuallyDrop<RefCell<i32>>`, which does not implement the `Copy` trait
|
help: consider cloning the value if the performance cost is acceptable
|
LL | move_out(x.f1_nocopy.clone());
| ++++++++
```
When a value is borrowed by an `fn` call, consider if cloning the result of the call would be reasonable, and suggest cloning that, instead of the argument:
```
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:53:14
|
LL | let a = AffineU32(1);
| - binding `a` declared here
LL | let x = bat(&a);
| -- borrow of `a` occurs here
LL | drop(a);
| ^ move out of `a` occurs here
LL | drop(x);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
|
LL | let x = bat(&a).clone();
| ++++++++
```
otherwise, suggest cloning the argument:
```
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:59:14
|
LL | let a = ClonableAffineU32(1);
| - binding `a` declared here
LL | let x = foo(&a);
| -- borrow of `a` occurs here
LL | drop(a);
| ^ move out of `a` occurs here
LL | drop(x);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
|
LL - let x = foo(&a);
LL + let x = foo(a.clone());
|
```
This suggestion doesn't attempt to square out the types between what's cloned and what the `fn` expects, to allow the user to make a determination on whether to change the `fn` call or `fn` definition themselves.
Special case move errors caused by `FnOnce`:
```
error[E0382]: use of moved value: `blk`
--> $DIR/once-cant-call-twice-on-heap.rs:8:5
|
LL | fn foo<F:FnOnce()>(blk: F) {
| --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait
LL | blk();
| ----- `blk` moved due to this call
LL | blk();
| ^^^ value used here after move
|
note: `FnOnce` closures can only be called once
--> $DIR/once-cant-call-twice-on-heap.rs:6:10
|
LL | fn foo<F:FnOnce()>(blk: F) {
| ^^^^^^^^ `F` is made to be an `FnOnce` closure here
LL | blk();
| ----- this value implements `FnOnce`, which causes it to be moved when called
```
Account for redundant `.clone()` calls in resulting suggestions:
```
error[E0507]: cannot move out of dereference of `S`
--> $DIR/needs-clone-through-deref.rs:15:18
|
LL | for _ in self.clone().into_iter() {}
| ^^^^^^^^^^^^ ----------- value moved due to this method call
| |
| move occurs because value has type `Vec<usize>`, which does not implement the `Copy` trait
|
note: `into_iter` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
LL | for _ in <Vec<usize> as Clone>::clone(&self).into_iter() {}
| ++++++++++++++++++++++++++++++ ~
```
We use the presence of `&mut` values in a move error as a proxy for the user caring about side effects, so we don't emit a clone suggestion in that case:
```
error[E0505]: cannot move out of `s` because it is borrowed
--> $DIR/borrowck-overloaded-index-move-index.rs:53:7
|
LL | let mut s = "hello".to_string();
| ----- binding `s` declared here
LL | let rs = &mut s;
| ------ borrow of `s` occurs here
...
LL | f[s] = 10;
| ^ move out of `s` occurs here
...
LL | use_mut(rs);
| -- borrow later used here
```
We properly account for `foo += foo;` errors where we *don't* suggest `foo.clone() += foo;`, instead suggesting `foo += foo.clone();`.
---
Each commit can be reviewed in isolation. There are some "cleanup" commits, but kept them separate in order to show *why* specific changes were being made, and their effect on tests' output.
Fix#49693, CC #64167.
Avoid more NonNull-raw-NonNull roundtrips in Vec
r? the8472
The standard library in general has a lot of these round-trips from niched types to their raw innards and back. Such round-trips have overhead in debug builds since https://github.com/rust-lang/rust/pull/120594. I removed some such round-trips in that initial PR and I've been meaning to come back and hunt down more such examples (this is the last item on https://github.com/rust-lang/rust/issues/120848).
Add `/System/iOSSupport` to the library search path on Mac Catalyst
On macOS, `/System/iOSSupport` contains iOS frameworks like UIKit, which is the whole idea of Mac Catalyst.
To link to these, we need to explicitly tell the linker about the support library stubs provided in the macOS SDK under the same path.
Concretely, when building a binary for Mac Catalyst, Xcode passes the following flags to the linker:
```
-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/iOSSupport/System/Library/Frameworks
-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/iOSSupport/usr/lib
```
This is not something that can be disabled (it's enabled as soon as you enable `SUPPORTS_MACCATALYST`), so I think it's pretty safe to say that we don't need an option to turn these off.
I've chosen to slightly deviate from what Xcode does and use `-F` instead of `-iframework`, since we don't need to change the header search path, and this way the flags nicely match on all the linkers. From what I could tell by reading Clang sources, there shouldn't be a difference when just running the linker.
CC `@BlackHoleFox,` `@shepmaster` (I accidentally let rustbot choose the reviewer).
typeck: fix `?` suggestion span
Noticed in <https://github.com/rust-lang/rust/pull/112043#issuecomment-2043565292>, if the
```
use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller
```
suggestion is applied to a macro that comes from a non-local crate (e.g. the stdlib), the suggestion span can become non-local, which will cause newer rustfix versions to fail.
This PR tries to remedy the problem by recursively probing ancestors of the expression span, trying to identify the most ancestor span that is (1) still local, and (2) still shares the same syntax context as the expression.
This is the same strategy used in https://github.com/rust-lang/rust/pull/112043.
The test unfortunately cannot `//@ run-rustfix` because there are two conflicting MaybeIncorrect suggestions that when collectively applied, cause the fixed source file to become non-compilable.
Also avoid running `//@ run-rustfix` for `tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.rs` because that also contains conflicting suggestions.
cc `@ehuss` who noticed this. This question mark span fix + not running rustfix on the tests containing conflicting MaybeIncorrect suggestions should hopefully unblock rustfix from updating.
The suggestion to use `let else` with an uninitialized refutable `let`
statement was erroneous: `let else` cannot be used with deferred
initialization.
Improve diagnostic by suggesting to remove visibility qualifier
Resolves#123529
This PR improve diagnostic by suggesting to remove visibility qualifier.
Fix invalid silencing of parsing error
Given
```rust
macro_rules! a {
( ) => {
impl<'b> c for d {
e::<f'g>
}
};
}
```
ensure an error is emitted.
Fix#123079.
Don't delay a bug if we suggest adding a semicolon to the RHS of an assign operator
It only makes sense to delay a bug based on the assumption that "[we] defer to the later error produced by `check_lhs_assignable`" *if* the expression we're erroring actually is an LHS; otherwise, we should still report the error since it's both useful and required.
Fixes#123722
Fix revisions syntax in cfg(ub_checks) test
`//@ revisions YES NO` doesn't do anything without the `:`. Thanks for pointing this out to me.
r? jieyouxu
Stop using `HirId` for fn-like parents since closures are not `OwnerNode`s
This is a minimal fix for #123273.
I'm overall pretty disappointed w/ the state of this code; although it's "just diagnostics", it still should be maintainable and understandable and neither of those are true. I believe this code really needs some major overhauling before anything more should be added to it, because there are subtle invariants that are being exercised and subsequently broken all over the place, and I don't think we should just paper over them (e.g.) by delaying bugs or things like that. I wouldn't be surprised if fixing up this code would also yield better diagnostics.
Silence `unused_imports` for redundant imports
Quick fix for https://github.com/rust-lang/rust/issues/121708#issuecomment-2048105393
r? `@petrochenkov` cc `@joshtriplett`
I think this is right, would like confirmation. I also think it's weird that we're using `=` to assign to `is_redundant` but using `per_ns` for the actual spans. Seems like this could be weirdly order dependent, but that's unrelated to this change.
Account for trait/impl difference when suggesting changing argument from ref to mut ref
Do not ICE when encountering a lifetime error involving an argument with an immutable reference of a method that differs from the trait definition.
Fix#123414.
We attempt to suggest an appropriate clone for move errors on expressions
like `S { ..s }` where a field isn't `Copy`. If we can't suggest, we still don't
emit the incorrect suggestion of `S { ..s }.clone()`.
```
error[E0509]: cannot move out of type `S<K>`, which implements the `Drop` trait
--> $DIR/borrowck-struct-update-with-dtor.rs:28:19
|
LL | let _s2 = S { a: 2, ..s0 };
| ^^^^^^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `s0.c` has type `K`, which does not implement the `Copy` trait
|
help: clone the value from the field instead of using the spread operator syntax
|
LL | let _s2 = S { a: 2, c: s0.c.clone(), ..s0 };
| +++++++++++++++++
```
```
error[E0509]: cannot move out of type `S<()>`, which implements the `Drop` trait
--> $DIR/borrowck-struct-update-with-dtor.rs:20:19
|
LL | let _s2 = S { a: 2, ..s0 };
| ^^^^^^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `s0.b` has type `B`, which does not implement the `Copy` trait
|
note: `B` doesn't implement `Copy` or `Clone`
--> $DIR/borrowck-struct-update-with-dtor.rs:4:1
|
LL | struct B;
| ^^^^^^^^
help: if `B` implemented `Clone`, you could clone the value from the field instead of using the spread operator syntax
|
LL | let _s2 = S { a: 2, b: s0.b.clone(), ..s0 };
| +++++++++++++++++
```
```
error[E0382]: use of moved value: `blk`
--> $DIR/once-cant-call-twice-on-heap.rs:8:5
|
LL | fn foo<F:FnOnce()>(blk: F) {
| --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait
LL | blk();
| ----- `blk` moved due to this call
LL | blk();
| ^^^ value used here after move
|
note: `FnOnce` closures can only be called once
--> $DIR/once-cant-call-twice-on-heap.rs:6:10
|
LL | fn foo<F:FnOnce()>(blk: F) {
| ^^^^^^^^ `F` is made to be an `FnOnce` closure here
LL | blk();
| ----- this value implements `FnOnce`, which causes it to be moved when called
```
```
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:28:14
|
LL | let a = AffineU32(1);
| - binding `a` declared here
LL | let x = foo(&a);
| -- borrow of `a` occurs here
LL | drop(a);
| ^ move out of `a` occurs here
LL | drop(x);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
|
LL | let x = foo(&a).clone();
| ++++++++
```
```
error[E0507]: cannot move out of `val`, a captured variable in an `FnMut` closure
--> $DIR/issue-87456-point-to-closure.rs:10:28
|
LL | let val = String::new();
| --- captured outer variable
LL |
LL | take_mut(|| {
| -- captured by this `FnMut` closure
LL |
LL | let _foo: String = val;
| ^^^ move occurs because `val` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
|
LL | let _foo: String = &val;
| +
help: consider cloning the value if the performance cost is acceptable
|
LL | let _foo: String = val.clone();
| ++++++++
```
```
error[E0507]: cannot move out of `*x` which is behind a shared reference
--> $DIR/borrowck-fn-in-const-a.rs:6:16
|
LL | return *x
| ^^ move occurs because `*x` has type `String`, which does not implement the `Copy` trait
|
help: consider cloning the value if the performance cost is acceptable
|
LL - return *x
LL + return x.clone()
|
```
Make the computation of `coroutine_captures_by_ref_ty` more sophisticated
Currently, we treat all the by-(mut/)ref borrows of a coroutine-closure as having a "closure env" borrowed lifetime.
When we have the given code:
```rust
let x: &'a i32 = ...;
let c = async || {
let _x = *x;
};
```
Then when we call:
```rust
c()
// which, because `AsyncFn` takes a `&self`, we insert an autoref:
(&c /* &'env {coroutine-closure} */)()
```
We will return a future whose captures contain `&'env i32` instead of `&'a i32`, which is way more restrictive than necessary. We should be able to drop `c` while the future is alive since it's not actually borrowing any data *originating from within* the closure's captures, but since the capture has that `'env` lifetime, this is not possible.
This wouldn't be true, for example, if the closure captured `i32` instead of `&'a i32`, because the `'env` lifetime is actually *necessary* since the data (`i32`) is owned by the closure.
This PR identifies two criteria where we *need* to take the borrow with the closure env lifetime:
1. If the closure borrows data from inside the closure's captures. This is not true if the parent capture is by-ref, OR if the parent capture is by-move and the child capture begins with a deref projection. This is the example described above.
2. If we're dealing with mutable references, since we cannot reborrow `&'env mut &'a mut i32` into `&'a mut i32`, *only* `&'env mut i32`.
See the documentation on `should_reborrow_from_env_of_parent_coroutine_closure` for more info.
**important:** As disclaimer states on that function, luckily, if this heuristic is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors.
Fixes#123241
Tweak value suggestions in `borrowck` and `hir_analysis`
Unify the output of `suggest_assign_value` and `ty_kind_suggestion`.
Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
Rework ptr-to-ref conversion suggestion for method calls
If we have a value `z` of type `*const u8` and try to call `z.to_string()`, the upstream compiler will show you a note suggesting to call `<*const u8>::as_ref` first.
This PR extends that:
- The note will only be shown when the method would exist on the corresponding reference type
- It can now suggest any of `<*const u8>::as_ref`, `<*mut u8>::as_ref` and `<*mut u8>::as_mut`, depending on what the method needs.
I didn't introduce a `help` message because that's not a good idea with `unsafe` functions (and you'd also need to unwrap the `Option<&_>` somehow).
People should check the safety requirements.
For the simplest case
```rust
fn main() {
let x = 8u8;
let z: *const u8 = &x;
// issue #21596
println!("{}", z.to_string()); //~ ERROR E0599
}
```
the output changes like this:
```diff
error[E0599]: `*const u8` doesn't implement `std::fmt::Display`
--> $DIR/suggest-convert-ptr-to-ref.rs:5:22
|
LL | println!("{}", z.to_string());
| ^^^^^^^^^ `*const u8` cannot be formatted with the default formatter
|
- = note: try using `<*const T>::as_ref()` to get a reference to the type behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
- = note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior
+note: the method `to_string` exists on the type `&u8`
+ --> $SRC_DIR/alloc/src/string.rs:LL:COL
+ = note: try using the unsafe method `<*const T>::as_ref` to get an optional reference to the value behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
= note: the following trait bounds were not satisfied:
`*const u8: std::fmt::Display`
which is required by `*const u8: ToString`
```
I removed the separate note about the safety requirements because it was incomplete and the linked doc page already has the information you need.
Fixes#83695, but that's more of a side effect. The upstream compiler already suggests the right method name here.
Provide suggestion to dereference closure tail if appropriate
When encoutnering a case like
```rust
use std::collections::HashMap;
fn main() {
let vs = vec![0, 0, 1, 1, 3, 4, 5, 6, 3, 3, 3];
let mut counts = HashMap::new();
for num in vs {
let count = counts.entry(num).or_insert(0);
*count += 1;
}
let _ = counts.iter().max_by_key(|(_, v)| v);
```
produce the following suggestion
```
error: lifetime may not live long enough
--> $DIR/return-value-lifetime-error.rs:13:47
|
LL | let _ = counts.iter().max_by_key(|(_, v)| v);
| ------- ^ returning this value requires that `'1` must outlive `'2`
| | |
| | return type of closure is &'2 &i32
| has type `&'1 (&i32, &i32)`
|
help: dereference the return value
|
LL | let _ = counts.iter().max_by_key(|(_, v)| **v);
| ++
```
Fix#50195.
Use `suggest_impl_trait` in return type suggestion on type error
Discovered while doing other refactoring. Review with whitespace disabled.
r? estebank
Use `fn` ptr signature instead of `{closure@..}` in infer error
When suggesting a type on inference error, do not use `{closure@..}`. Instead, replace with an appropriate `fn` ptr.
On the error message, use `short_ty_string` and write long types to disk.
```
error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>`
--> crates/lang/src/parser.rs:41:13
|
41 | let lit = select! {
| ^^^
42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()),
| ---- type must be known at this point
|
= note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt'
= note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan`
help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified
|
41 | let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! {
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```
instead of
```
error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>`
--> crates/lang/src/parser.rs:41:13
|
41 | let lit = select! {
| ^^^
42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()),
| ---- type must be known at this point
|
= note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan`
help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified
|
41 | let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! {
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```
Address #123630 (test missing).
Skip `unused_parens` report for `Paren(Path(..))` in macro.
fixes#120642
In following code, `unused_parens` suggest change `<($($rest),*)>::bar()` to `<$rest>::bar()` which will cause another err: `error: variable 'rest' is still repeating at this depth`:
```rust
trait Foo {
fn bar();
}
macro_rules! problem {
($ty:ident) => {
impl<$ty: Foo> Foo for ($ty,) {
fn bar() { <$ty>::bar() }
}
};
($ty:ident $(, $rest:ident)*) => {
impl<$ty: Foo, $($rest: Foo),*> Foo for ($ty, $($rest),*) {
fn bar() {
<$ty>::bar();
<($($rest),*)>::bar()
}
}
problem!($($rest),*);
}
}
```
I think maybe we can handle this by avoid warning for `Paren(Path(..))` in the macro. Is this reasonable approach?
`f16` and `f128` step 4: basic library support
This is the next step after https://github.com/rust-lang/rust/pull/121926, another portion of https://github.com/rust-lang/rust/pull/114607
Tracking issue: https://github.com/rust-lang/rust/issues/116909
This PR adds the most basic operations to `f16` and `f128` that get lowered as LLVM intrinsics. This is a very small step but it seemed reasonable enough to add unopinionated basic operations before the larger modules that are built on top of them.
r? ```@Amanieu``` since you were pretty involved in the RFC
cc ```@compiler-errors```
```@rustbot``` label +T-libs-api +S-blocked +F-f16_and_f128
Do not accept the following
```rust
macro_rules! lexes {($($_:tt)*) => {}}
lexes!(🐛"foo");
```
Before, invalid emoji identifiers were gated during parsing instead of lexing in all cases, but this didn't account for macro expansion of literal prefixes.
Fix#123696.
Propagate temporary lifetime extension into if and match.
This PR makes this work:
```rust
let a = if true {
..;
&temp() // used to error, but now gets lifetime extended
} else {
..;
&temp() // used to error, but now gets lifetime extended
};
```
and
```rust
let a = match () {
_ => {
..;
&temp() // used to error, but now gets lifetime extended
}
};
```
to make it consistent with:
```rust
let a = {
..;
&temp() // lifetime is extended
};
```
This is one small part of [the temporary lifetimes work](https://github.com/rust-lang/lang-team/issues/253).
This part is backwards compatible (so doesn't need be edition-gated), because all code affected by this change previously resulted in a hard error.
Further cleanup cfgs in the UI test suite
This PR does more cleanup of cfgs in our UI test suite, in preparation for adding automatic always on check-cfg (but is IMO worth landing even without that follow up).
To be more specific this PR:
- replaces (the last remaining) never true cfgs by the `FALSE` cfg
- fix `proc-macro/derive-helper-configured.rs` *(typo in directive)*
- and comment some current unused `#[cfg_attr]` *(missing revisions)*
Follow-up to https://github.com/rust-lang/rust/pull/123577.
Only assert for child/parent projection compatibility AFTER checking that theyre coming from the same place
This assertion doesn't make sense until we check that these captures are actually equivalent.
Fixes#123697
<sub>Some days I wonder how I even write code that works...</sub>
Add `REDUNDANT_LIFETIMES` lint to detect lifetimes which are semantically redundant
There already is a `UNUSED_LIFETIMES` lint which is fired when we detect where clause bounds like `where 'a: 'static`, however, it doesn't use the full power of lexical region resolution to detect failures.
Right now `UNUSED_LIFETIMES` is an `Allow` lint, though presumably we could bump it to warn? I can (somewhat) easily implement a structured suggestion so this can be rustfix'd automatically, since we can just walk through the HIR body, replacing instances of the redundant lifetime.
Fixes#118376
r? lcnr
Rollup of 7 pull requests
Successful merges:
- #121884 (Port exit-code run-make test to use rust)
- #122200 (Unconditionally show update nightly hint on ICE)
- #123568 (Clean up tests/ui by removing `does-nothing.rs`)
- #123609 (Don't use bytepos offsets when computing semicolon span for removal)
- #123612 (Set target-abi module flag for RISC-V targets)
- #123633 (Store all args in the unsupported Command implementation)
- #123668 (async closure coroutine by move body MirPass refactoring)
Failed merges:
- #123701 (Only assert for child/parent projection compatibility AFTER checking that theyre coming from the same place)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't use bytepos offsets when computing semicolon span for removal
Causes problems when we recover confusable characters w/ a different byte width
Fixes#123607
Clean up tests/ui by removing `does-nothing.rs`
In [a previous PR](https://github.com/rust-lang/rust/pull/123297#issuecomment-2039887806), it was suggested that this test be removed:
> it's testing a basic diagnostic for an unknown variable (added over a decade ago for https://github.com/rust-lang/rust/issues/154) that is already covered by probably dozens or hundreds of other tests.
It was then suggested that [opening a new PR](https://github.com/rust-lang/rust/pull/123563#discussion_r1554654102) for this would be more organized.
I'm setting this as a draft, as:
1. The tests/ui directory is rather disorganized, a large quantity of tests are not even contained inside their own directories. This PR could turn into "clean up the UI tests directory", if I were to place everything into categories (for example, everything related to CLI flags could get placed in a cli directory).
2. This will have a merge conflict with #123563 should that get merged. I trust that _this time_, I won't run into [The Incident](https://github.com/rust-lang/rust/pull/123297#issuecomment-2041137569) while rebasing. Edit: Yay, I did it properly!
Unconditionally show update nightly hint on ICE
Instead of trying to guess if a update nightly hint should be shown (by checking for system time, querying version and channel info etc.), just show the update nightly hint for nightly compilers. This avoids breaking tests that match on ICE test outputs on nightly/dev channels.
> Another issue is that the outdated nightly hint triggers for ICE tests, causing a mismatch with the test expectation. There doesn't seem to be any env var to suppress this.
See <https://rust-lang.zulipchat.com/#narrow/stream/326414-t-infra.2Fbootstrap/topic/stage0.20compiletest.20broken/near/425543681> for context.
When suggesting a type on inference error, do not use `{closure@..}`.
Instead, replace with an appropriate `fn` ptr.
On the error message, use `short_ty_string` and write long types to
disk.
```
error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>`
--> crates/lang/src/parser.rs:41:13
|
41 | let lit = select! {
| ^^^
42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()),
| ---- type must be known at this point
|
= note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt'
= note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan`
help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified
|
41 | let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! {
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```
instead of
```
error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>`
--> crates/lang/src/parser.rs:41:13
|
41 | let lit = select! {
| ^^^
42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()),
| ---- type must be known at this point
|
= note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan`
help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified
|
41 | let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! {
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```
Fix#123630.
Unify the output of `suggest_assign_value` and `ty_kind_suggestion`.
Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
This commit does three things:
1. replaces (the last remaining) never true cfgs by the FALSE cfg
2. fix derive-helper-configured.rs (typo in directive)
3. and comment some current unused #[cfg_attr] (missing revisions)