Fix `is_const_context`, update `check_for_cast`
A better version of #71477
Adds `fn enclosing_body_owner` and uses it in `is_const_context`.
`is_const_context` now uses the same mechanism as `mir_const_qualif` as it was previously incorrect.
Renames `is_const_context` to `is_inside_const_context`.
I also updated `check_for_cast` in the second commit, so r? @estebank
(I removed one lvl of indentation, so it might be easier to review by hiding whitespace changes)
Relate existential associated types with variance Invariant
Fixes#71550#72315
r? @nikomatsakis
The test case reported in that issue now errors with the following message ...
```
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in function call due to conflicting requirements
--> /tmp/test.rs:25:5
|
25 | bad(&Bar(PhantomData), x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 24:11...
--> /tmp/test.rs:24:11
|
24 | fn extend<'a, T>(x: &'a T) -> &'static T {
| ^^
note: ...so that reference does not outlive borrowed content
--> /tmp/test.rs:25:28
|
25 | bad(&Bar(PhantomData), x)
| ^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> /tmp/test.rs:25:9
|
25 | bad(&Bar(PhantomData), x)
| ^^^^^^^^^^^^^^^^^
= note: expected `&'static T`
found `&T`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
```
I could also add that test case if we want to have a weaponized one too.
Fixes#72839
In PR #72621, trait selection was modified to no longer bail out early
when an error type was encountered. This allowed us treat `ty::Error` as
`Sized`, causing us to avoid emitting a spurious "not sized" error after
a type error had already occured.
However, this means that we may now try to match an impl candidate
against the error type. Since the error type will unify with almost
anything, this can cause us to infinitely recurse (eventually triggering
an overflow) when trying to verify certain `where` clauses.
This commit causes us to skip generating any impl candidates when an
error type is involved.
Improve inline asm error diagnostics
Previously we were just using the raw LLVM error output (with line, caret, etc) as the diagnostic message, which ends up looking rather out of place with our existing diagnostics.
The new diagnostics properly format the diagnostics and also take advantage of LLVM's per-line `srcloc` attribute to map an error in inline assembly directly to the relevant line of source code.
Incidentally also fixes#71639 by disabling `srcloc` metadata during LTO builds since we don't know what crate it might have come from. We can only resolve `srcloc`s from the currently crate since it indexes into the source map for the current crate.
Fixes#72664Fixes#71639
r? @petrochenkov
### Old style
```rust
#![feature(llvm_asm)]
fn main() {
unsafe {
let _x: i32;
llvm_asm!(
"mov $0, $1
invalid_instruction $0, $1
mov $0, $1"
: "=&r" (_x)
: "r" (0)
:: "intel"
);
}
}
```
```
error: <inline asm>:3:14: error: invalid instruction mnemonic 'invalid_instruction'
invalid_instruction ecx, eax
^~~~~~~~~~~~~~~~~~~
--> src/main.rs:6:9
|
6 | / llvm_asm!(
7 | | "mov $0, $1
8 | | invalid_instruction $0, $1
9 | | mov $0, $1"
... |
12 | | :: "intel"
13 | | );
| |__________^
```
### New style
```rust
#![feature(asm)]
fn main() {
unsafe {
asm!(
"mov {0}, {1}
invalid_instruction {0}, {1}
mov {0}, {1}",
out(reg) _,
in(reg) 0i64,
);
}
}
```
```
error: invalid instruction mnemonic 'invalid_instruction'
--> test.rs:7:14
|
7 | invalid_instruction {0}, {1}
| ^
|
note: instantiated into assembly here
--> <inline asm>:3:14
|
3 | invalid_instruction rax, rcx
| ^^^^^^^^^^^^^^^^^^^
```
mir: adjust conditional in recursion limit check
Fixes#67552.
This PR adjusts the condition used in the recursion limit check of
the monomorphization collector, from `>` to `>=`.
In #67552, the test case had infinite indirect recursion, repeating a
handful of functions (from the perspective of the monomorphization
collector): `rec` -> `identity` -> `Iterator::count` -> `Iterator::fold`
-> `Iterator::next` -> `rec`.
During this process, `resolve_associated_item` was invoked for
`Iterator::fold` (during the construction of an `Instance`), and
ICE'd due to substitutions needing inference. However, previous
iterations of this recursion would have called this function for
`Iterator::fold` - and did! - and succeeded in doing so (trivially
checkable from debug logging, `()` is present where `_` is in the substs
of the failing execution).
The expected outcome of this test case would be a recursion limit error
(which is present when the `identity` fn indirection is removed), and
the recursion depth of `rec` is increasing (other functions finish
collecting their neighbours and thus have their recursion depths reset).
When the ICE occurs, the recursion depth of `rec` is 256 (which matches
the recursion limit), which suggests perhaps that a different part of
the compiler is using a `>=` comparison and returning a different result
on this recursion rather than what it returned in every previous
recursion, thus stopping the monomorphization collector from reporting
an error on the next recursion, where `recursion_depth_of_rec > 256`
would have been true.
With grep and some educated guesses, we can determine that
the recursion limit check at line 818 in
`src/librustc_trait_selection/traits/project.rs` is the other check that
is using a different comparison. Modifying either comparison to be `>` or
`>=` respectively will fix the error, but changing the monomorphization
collector produces the nicer error.
Fix ICE with explicit late-bound lifetimes
Rather than returning an explicit late-bound lifetime as a generic argument count mismatch (which is not necessarily true), this PR propagates the presence of explicit late-bound lifetimes.
This avoids an ICE that can occur due to the presence of explicit late-bound lifetimes when building generic substitutions by explicitly ignoring them.
r? @varkor
cc @davidtwco (this removes a check you introduced in #60892)
Resolves#72278
Fix diagnostics for `@ ..` binding pattern in tuples and tuple structs
Fixes#72574
Associated https://github.com/rust-lang/rust/pull/72534https://github.com/rust-lang/rust/issues/72373
Includes a new suggestion with `Applicability::MaybeIncorrect` confidence level.
### Before
#### tuple
```
error: `..` patterns are not allowed here
--> src/main.rs:4:19
|
4 | (_a, _x @ ..) => {}
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns
error[E0308]: mismatched types
--> src/main.rs:4:9
|
3 | match x {
| - this expression has type `({integer}, {integer}, {integer})`
4 | (_a, _x @ ..) => {}
| ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
|
= note: expected tuple `({integer}, {integer}, {integer})`
found tuple `(_, _)`
error: aborting due to 2 previous errors
```
#### tuple struct
```
error: `..` patterns are not allowed here
--> src/main.rs:6:25
|
6 | Binder(_a, _x @ ..) => {}
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns
error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
--> src/main.rs:6:9
|
1 | struct Binder(i32, i32, i32);
| ----------------------------- tuple struct defined here
...
6 | Binder(_a, _x @ ..) => {}
| ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2
error: aborting due to 2 previous errors
```
### After
*Note: final output edited during source review discussion, see thread for details*
#### tuple
```
error: `_x @` is not allowed in a tuple
--> src/main.rs:4:14
|
4 | (_a, _x @ ..) => {}
| ^^^^^^^ is only allowed in a slice
|
help: replace with `..` or use a different valid pattern
|
4 | (_a, ..) => {}
| ^^
error[E0308]: mismatched types
--> src/main.rs:4:9
|
3 | match x {
| - this expression has type `({integer}, {integer}, {integer})`
4 | (_a, _x @ ..) => {}
| ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 1 element
|
= note: expected tuple `({integer}, {integer}, {integer})`
found tuple `(_,)`
error: aborting due to 2 previous errors
```
#### tuple struct
```
error: `_x @` is not allowed in a tuple struct
--> src/main.rs:6:20
|
6 | Binder(_a, _x @ ..) => {}
| ^^^^^^^ is only allowed in a slice
|
help: replace with `..` or use a different valid pattern
|
6 | Binder(_a, ..) => {}
| ^^
error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields
--> src/main.rs:6:9
|
1 | struct Binder(i32, i32, i32);
| ----------------------------- tuple struct defined here
...
6 | Binder(_a, _x @ ..) => {}
| ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 1
error: aborting due to 2 previous errors
```
r? @estebank
This commit introduces a `Limit` type which is used to ensure that all
comparisons against limits within the compiler are consistent (which can
result in ICEs if they aren't).
Signed-off-by: David Wood <david@davidtw.co>
This commit adjusts the condition used in the recursion limit check of
the monomorphization collector, from `>` to `>=`.
In #67552, the test case had infinite indirect recursion, repeating a
handful of functions (from the perspective of the monomorphization
collector): `rec` -> `identity` -> `Iterator::count` -> `Iterator::fold`
-> `Iterator::next` -> `rec`.
During this process, `resolve_associated_item` was invoked for
`Iterator::fold` (during the construction of an `Instance`), and
ICE'd due to substitutions needing inference. However, previous
iterations of this recursion would have called this function for
`Iterator::fold` - and did! - and succeeded in doing so (trivially
checkable from debug logging, `()` is present where `_` is in the substs
of the failing execution).
The expected outcome of this test case would be a recursion limit error
(which is present when the `identity` fn indirection is removed), and
the recursion depth of `rec` is increasing (other functions finish
collecting their neighbours and thus have their recursion depths reset).
When the ICE occurs, the recursion depth of `rec` is 256 (which matches
the recursion limit), which suggests perhaps that a different part of
the compiler is using a `>=` comparison and returning a different result
on this recursion rather than what it returned in every previous
recursion, thus stopping the monomorphization collector from reporting
an error on the next recursion, where `recursion_depth_of_rec > 256`
would have been true.
With grep and some educated guesses, we can determine that
the recursion limit check at line 818 in
`src/librustc_trait_selection/traits/project.rs` is the other check that
is using a different comparison. Modifying either comparison to be `>` or
`>=` respectively will fix the error, but changing the monomorphization
collector produces the nicer error.
Signed-off-by: David Wood <david@davidtw.co>
Detect type parameter that might require lifetime constraint.
Do not name `ReVar`s in expected/found output.
Reword text suggesting to check the lifetimes.
add issue 72373 tests
fmt test
fix suggestion format
Replacement, not insertion of suggested string
implement review changes
refactor to span_suggestion_verbose, improve suggestion message, change id @ pattern space formatting
fmt
fix diagnostics spacing between ident and @
refactor reference
Add test for old compiler ICE when using `Borrow`
The original issue was caused by implementing `Borrow` on a local type and using the tokio-reactor crate which had this impl: https://github.com/tokio-rs/tokio/blob/tokio-0.1.4/tokio-reactor/src/poll_evented.rs#L547-L577
This causes an ICE on Rust 1.27.0:
```console
$ RUSTUP_TOOLCHAIN=1.27.0 rustc src/test/ui/issues/issue-50687-ice-on-borrow.rs
error: internal compiler error: librustc/traits/structural_impls.rs:180: impossible case reached
thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:554:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: aborting due to previous error
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.27.0 (3eda71b00 2018-06-19) running on x86_64-apple-darwin
```
Closes#50687
add a lint against references to packed fields
Creating a reference to an insufficiently aligned packed field is UB and should be disallowed, both inside and outside of `unsafe` blocks. However, currently there is no stable alternative (https://github.com/rust-lang/rust/issues/64490) so all we do right now is have a future incompatibility warning when doing this outside `unsafe` (https://github.com/rust-lang/rust/issues/46043).
This adds an allow-by-default lint. @retep998 suggested this can help early adopters avoid issues. It also means we can then do a crater run where this is deny-by-default as suggested by @joshtriplett.
I guess the main thing to bikeshed is the lint name. I am not particularly happy with "packed_references" as it sounds like the packed field has reference type. I chose this because it is similar to "safe_packed_borrows". What about "reference_to_packed" or "unaligned_reference" or so?
Ignore arguments when looking for `IndexMut` for subsequent `mut` obligation
Given code like `v[&field].boo();` where `field: String` and
`.boo(&mut self)`, typeck will have decided that `v` is accessed using
`Index`, but when `boo` adds a new `mut` obligation,
`convert_place_op_to_mutable` is called. When this happens, for *some
reason* the arguments' dereference adjustments are completely ignored
causing an error saying that `IndexMut` is not satisfied:
```
error[E0596]: cannot borrow data in an index of `Indexable` as mutable
--> src/main.rs:30:5
|
30 | v[&field].boo();
| ^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Indexable`
```
This is not true, but by changing `try_overloaded_place_op` to retry
when given `Needs::MutPlace` without passing the argument types, the
example successfully compiles.
I believe there might be more appropriate ways to deal with this.
Fix#72002.
Support coercion between (FnDef | Closure) and (FnDef | Closure)
Fixes#46742, fixes#48109
Inject `Closure` into the `FnDef x FnDef` coercion special case, which makes coercion of `(FnDef | Closure) x (FnDef | Closure)` possible, where closures should be **non-capturing**.
Incomplete features can also be unsound
Some incomplete features do not just ICE, they are also currently unsound (e.g. https://github.com/rust-lang/rust/pull/72029, and also `specialization` -- which is not yet marked incomplete but [should be](https://github.com/rust-lang/rust/pull/71420)). This makes the message reflect that.
While at it I also added a link to the tracking issue, which hopefully should explain what is incomplete/unsound about the feature.