Commit graph

4543 commits

Author SHA1 Message Date
est31
ab60a7df64 Also walk bindings created by if-let guards 2023-12-29 03:38:09 +01:00
Matthias Krüger
e8831b6df8
Rollup merge of #119380 - ShE3py:match-never-pat, r=petrochenkov
Don't suggest writing a bodyless arm if the pattern can never be a never pattern

#118527 enabled arms to be bodyless for never patterns ; this PR removes the `,` and `}` suggestions for patterns that could never be never patterns.
2023-12-28 18:48:02 +01:00
Matthias Krüger
77c23b3e94
Rollup merge of #119376 - msrd0:regression-test-106630, r=petrochenkov
Add regression test for #106630

This PR adds a regression test for #106630. I was unsure where exactly to place the test or how to test it locally so please let me know if I should change something.
2023-12-28 18:48:01 +01:00
Lieselotte
7d6cd6bf1f
Don't expect bodyless arms if the pattern can never be a never pattern 2023-12-28 15:02:17 +01:00
Dominic
a88c9a644c
Add regression test for #106630 2023-12-28 14:53:23 +01:00
bors
89e2160c4c Auto merge of #119105 - dtolnay:paren, r=WaffleLapkin
Fix parenthesization of subexprs containing statement boundary

This PR fixes a multitude of false negatives and false positives in the AST pretty printer's parenthesis insertion related to statement boundaries — statements which terminate unexpectedly early if there aren't parentheses.

Without this fix, the AST pretty printer (including both `stringify!` and `rustc -Zunpretty=expanded`) is prone to producing output which is not syntactically valid Rust. Invalid output is problematic because it means Rustfmt is unable to parse the output of `cargo expand`, for example, causing friction by forcing someone trying to debug a macro into reading poorly formatted code.

I believe the set of bugs fixed in this PR account for the most prevalent reason that `cargo expand` produces invalid output in real-world usage.

Fixes #98790.

## False negatives

The following is a correct program — `cargo check` succeeds.

```rust
macro_rules! m {
    ($e:expr) => {
        match () { _ => $e }
    };
}

fn main() {
    m!({ 1 } - 1);
}
```

But `rustc -Zunpretty=expanded main.rs` produces output that is invalid Rust syntax, because parenthesization is needed and not being done by the pretty printer.

```rust
fn main() { match () { _ => { 1 } - 1, }; }
```

Piping this expanded code to rustfmt, it fails to parse.

```console
error: unexpected `,` in pattern
 --> <stdin>:1:38
  |
1 | fn main() { match () { _ => { 1 } - 1, }; }
  |                                      ^
  |
help: try adding parentheses to match on a tuple...
  |
1 | fn main() { match () { _ => { 1 } (- 1,) }; }
  |                                   +    +
help: ...or a vertical bar to match on multiple alternatives
  |
1 | fn main() { match () { _ => { 1 } - 1 | }; }
  |                                   ~~~~~
```

Fixed output after this PR:

```rust
fn main() { match () { _ => ({ 1 }) - 1, }; }
```

## False positives

Less problematic, but worth fixing (just like #118726).

```rust
fn main() {
    let _ = match () { _ => 1 } - 1;
}
```

Output of `rustc -Zunpretty=expanded lib.rs` before this PR. There is no reason parentheses would need to be inserted there.

```rust
fn main() { let _ = (match () { _ => 1, }) - 1; }
```

After this PR:

```rust
fn main() { let _ = match () { _ => 1, } - 1; }
```

## Alternatives considered

In this PR I opted to parenthesize only the leading subexpression causing the statement boundary, rather than the entire statement. Example:

```rust
macro_rules! m {
    ($e:expr) => {
        $e
    };
}

fn main() {
    m!(loop { break [1]; }[0] - 1);
}
```

This PR produces the following pretty-printed contents for fn main:

```rust
(loop { break [1]; })[0] - 1;
```

A different equally correct output would be:

```rust
(loop { break [1]; }[0] - 1);
```

I chose the one I did because it is the *only* approach used by handwritten code in the standard library and compiler. There are 4 places where parenthesization is being used to prevent a statement boundary, and in all 4, the developer has chosen to parenthesize the smallest subexpression rather than the whole statement:

b37d43efd9/compiler/rustc_codegen_cranelift/example/alloc_system.rs (L102)

b37d43efd9/compiler/rustc_parse/src/errors.rs (L1021-L1029)

b37d43efd9/library/core/src/future/poll_fn.rs (L151)

b37d43efd9/library/core/src/ops/range.rs (L824-L828)
2023-12-27 21:27:26 +00:00
bors
88d69b72b4 Auto merge of #119099 - fmease:always-const-trait-bounds, r=fee1-dead
Introduce `const Trait` (always-const trait bounds)

Feature `const_trait_impl` currently lacks a way to express “always const” trait bounds. This makes it impossible to define generic items like fns or structs which contain types that depend on const method calls (\*). While the final design and esp. the syntax of effects / keyword generics isn't set in stone, some version of “always const” trait bounds will very likely form a part of it. Further, their implementation is trivial thanks to the `effects` backbone.

Not sure if this needs t-lang sign-off though.

(\*):

```rs
#![feature(const_trait_impl, effects, generic_const_exprs)]

fn compute<T: const Trait>() -> Type<{ T::generate() }> { /*…*/ }

struct Store<T: const Trait>
where
    Type<{ T::generate() }>:,
{
    field: Type<{ T::generate() }>,
}
```

Lastly, “always const” trait bounds are a perfect fit for `generic_const_items`.

```rs
#![feature(const_trait_impl, effects, generic_const_items)]

const DEFAULT<T: const Default>: T = T::default();
```

Previously, we (oli, fee1-dead and I) wanted to reinterpret `~const Trait` as `const Trait` in generic const items which would've been quite surprising and not very generalizable.
Supersedes #117530.

---

cc `@oli-obk`

As discussed
r? fee1-dead (or compiler)
2023-12-27 19:24:31 +00:00
bors
a861c8965e Auto merge of #117303 - sjwang05:issue-117245, r=estebank
Suggest `=>` --> `>=` in comparisons

Fixes #117245
2023-12-27 17:26:12 +00:00
León Orell Valerian Liehr
3eb48a35c8
Introduce const Trait (always-const trait bounds) 2023-12-27 12:51:32 +01:00
Matthias Krüger
d6382c785f
Rollup merge of #119175 - veera-sivarajan:fix-cast-to-slice, r=WaffleLapkin
fix: diagnostic for casting reference to slice

fixes:  #118790

Removes `if self.cast_ty.is_trait()` to produce the same diagnostic for cast to slice and trait.
2023-12-27 09:11:35 +01:00
sjwang05
97cf1c87bd
Suggest => --> >= in conditions 2023-12-26 20:59:14 -08:00
Esteban Küber
dc30eb1967 Suggest = to == in more cases, even in the face of reference mismatch
Given `foo: &String` and `bar: str`, suggest `==` when given `if foo = bar {}`:

```
error[E0308]: mismatched types
  --> $DIR/assignment-expected-bool.rs:37:8
   |
LL |     if foo = bar {}
   |        ^^^^^^^^^ expected `bool`, found `()`
   |
help: you might have meant to compare for equality
   |
LL |     if foo == bar {}
   |             +
```
2023-12-26 23:48:55 +00:00
bors
2df6406b88 Auto merge of #118431 - sjwang05:issue-44695, r=estebank
Emit better suggestions for `&T == T` and `T == &T`

Fixes #40660
Fixes #44695
2023-12-26 21:34:24 +00:00
bors
deace71034 Auto merge of #119324 - compiler-errors:rollup-c6eqcg9, r=compiler-errors
Rollup of 5 pull requests

Successful merges:

 - #119235 (Add missing feature gate for sanitizer CFI cfgs)
 - #119240 (Make some non-diagnostic-affecting `QPath::LangItem` into regular `QPath`s)
 - #119297 (Pass DeadItem and lint as consistent group in dead-code.)
 - #119307 (Clean up some lifetimes in `rustc_pattern_analysis`)
 - #119323 (add test for coercing never to infinite type)

r? `@ghost`
`@rustbot` modify labels: rollup
2023-12-26 19:28:49 +00:00
Michael Goulet
a5b3d139b3
Rollup merge of #119323 - lukas-code:test-never-to-infinite, r=compiler-errors
add test for coercing never to infinite type

Closes https://github.com/rust-lang/rust/issues/113197.

This was fixed in https://github.com/rust-lang/rust/pull/118308, probably https://github.com/rust-lang/rust/pull/118308/commits/1978168c136ba65b8da3f5a45834631c13d7c56f.
2023-12-26 13:29:14 -05:00
Michael Goulet
65aaece6c0
Rollup merge of #119297 - cjgillot:issue-119267, r=petrochenkov
Pass DeadItem and lint as consistent group in dead-code.

Fixes https://github.com/rust-lang/rust/issues/119267
2023-12-26 13:29:13 -05:00
Michael Goulet
e7bd402a38
Rollup merge of #119240 - compiler-errors:lang-item-more, r=petrochenkov
Make some non-diagnostic-affecting `QPath::LangItem` into regular `QPath`s

The rest of 'em affect diagnostics, so leave them alone... for now.

cc #115178
2023-12-26 13:29:13 -05:00
Michael Goulet
50e380c8f3
Rollup merge of #119235 - Urgau:missing-feature-gate-sanitizer-cfi-cfgs, r=Nilstrieb
Add missing feature gate for sanitizer CFI cfgs

Found during the review of https://github.com/rust-lang/rust/pull/118494 in https://github.com/rust-lang/rust/pull/118494#discussion_r1416079288.

cc `@rcvalle`
2023-12-26 13:29:13 -05:00
bors
a75fed74b6 Auto merge of #119042 - bvanjoi:fix-118697-2, r=compiler-errors
fallback `default` to `None` during ast-lowering for lifetime binder

Fixes #118697

This is another attempt. It has a fallback, setting `default` to `None` and emit an error for non-lifetime binders during ast lowering.

r? `@compiler-errors`
2023-12-26 17:30:42 +00:00
Lukas Markeffsky
29036045c3 add test for coercing never to infinite type 2023-12-26 17:57:33 +01:00
Lukas Markeffsky
cb2fc0967f rename tests 2023-12-26 17:50:30 +01:00
bors
e1fadb2c35 Auto merge of #119133 - scottmcm:assert-unchecked, r=thomcc
Add `hint::assert_unchecked`

Libs-API expressed interest, modulo bikeshedding, in https://github.com/rust-lang/libs-team/issues/315#issuecomment-1863159430

I think that means this is good for nightly, since we can always rename it before stabilization.

Tracking issue: https://github.com/rust-lang/rust/issues/119131
2023-12-26 15:31:44 +00:00
bors
2fe50cd72c Auto merge of #119129 - jyn514:verbose, r=compiler-errors,estebank
rework `-Zverbose`

implements the changes described in https://github.com/rust-lang/compiler-team/issues/706

the first commit is only a name change from `-Zverbose` to `-Zverbose-internals` and does not change behavior. the second commit changes diagnostics.

possible follow up work:
- `ty::pretty` could print more info with `--verbose` than it does currently. `-Z verbose-internals` shows too much info in a way that's not helpful to users. michael had ideas about this i didn't fully understand: https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/uplift.20some.20-Zverbose.20calls.20and.20rename.20to.E2.80.A6.20compiler-team.23706/near/408984200
- `--verbose` should imply `-Z write-long-types-to-disk=no`. the code in `ty_string_with_limit` should take `--verbose` into account (apparently this affects `Ty::sort_string`, i'm not familiar with this code). writing a file to disk should suggest passing `--verbose`.

r? `@compiler-errors` cc `@estebank`
2023-12-26 12:27:29 +00:00
bohan
e16efbd23a fallback default to None during ast-loweing for lifetime binder 2023-12-26 16:10:29 +08:00
bors
1ab783112a Auto merge of #119258 - compiler-errors:closure-kind, r=eholk
Make closures carry their own ClosureKind

Right now, we use the "`movability`" field of `hir::Closure` to distinguish a closure and a coroutine. This is paired together with the `CoroutineKind`, which is located not in the `hir::Closure`, but the `hir::Body`. This is strange and redundant.

This PR introduces `ClosureKind` with two variants -- `Closure` and `Coroutine`, which is put into `hir::Closure`. The `CoroutineKind` is thus removed from `hir::Body`, and `Option<Movability>` no longer needs to be a stand-in for "is this a closure or a coroutine".

r? eholk
2023-12-26 04:25:53 +00:00
Michael Goulet
7e00e9736d Make some non-diagnostic-affecting QPath::LangItem into regular qpaths 2023-12-26 04:07:38 +00:00
Michael Goulet
909dd864f1 Make closures carry their own ClosureKind, rather than deducing what it is from movability 2023-12-25 16:29:15 +00:00
bors
f8fe517144 Auto merge of #116274 - RalfJung:soft_unstable, r=cjgillot
make soft_unstable show up in future breakage reports

If we want to break these in the future, let's warn users of affected crates.
2023-12-25 16:26:15 +00:00
Camille GILLOT
8bb74c0187 Pass DeadItem and lint as consistent group in dead-code. 2023-12-25 13:15:28 +00:00
bors
f2348fb29a Auto merge of #119122 - matthewjasper:if-let-guard-scoping, r=TaKO8Ki
Give temporaries in if let guards correct scopes

Temporaries in if-let guards have scopes that escape the match arm, this causes problems because the drops might be for temporaries that are not storage live. This PR changes the scope of temporaries in if-let guards to be limited to the arm:

```rust
_ if let Some(s) = std::convert::identity(&Some(String::new())) => {}
//                Temporary for Some(String::new()) is dropped here ^
```

We also now deduplicate temporaries between copies of the guard created for or-patterns:

```rust
// Only create a single Some(String::new()) temporary variable
_ | _ if let Some(s) = std::convert::identity(&Some(String::new())) => {}
```

This changes MIR building to pass around `ExprId`s rather than `Expr`s so that we have a way to index different expressions.

cc #51114
Closes #116079
2023-12-25 04:06:58 +00:00
bors
471dcbdb09 Auto merge of #119274 - RalfJung:raw-ptr-pattern-ice, r=compiler-errors
fix ICE when using raw ptr in a pattern

Fixes https://github.com/rust-lang/rust/issues/119270
2023-12-25 00:03:59 +00:00
jyn
cb6d033316 don't elide shared parts of types in diagnostics when --verbose is passed
this also changes some parts of lifetime printing, which previously were not gated behind `-Z verbose`
2023-12-24 16:47:18 -05:00
bors
1a086e49f1 Auto merge of #118796 - Nadrieril:fix-exponential-id-match-2, r=cjgillot
Exhaustiveness: Improve complexity on some wide matches

https://github.com/rust-lang/rust/issues/118437 revealed an exponential case in exhaustiveness checking. While [exponential cases are unavoidable](https://compilercrim.es/rust-np/), this one only showed up after my https://github.com/rust-lang/rust/pull/117611 rewrite of the algorithm. I remember anticipating a case like this and dismissing it as unrealistic, but here we are :').

The tricky match is as follows:
```rust
match command {
    BaseCommand { field01: true, .. } => {}
    BaseCommand { field02: true, .. } => {}
    BaseCommand { field03: true, .. } => {}
    BaseCommand { field04: true, .. } => {}
    BaseCommand { field05: true, .. } => {}
    BaseCommand { field06: true, .. } => {}
    BaseCommand { field07: true, .. } => {}
    BaseCommand { field08: true, .. } => {}
    BaseCommand { field09: true, .. } => {}
    BaseCommand { field10: true, .. } => {}
    // ...20 more of the same

    _ => {}
}
```

To fix this, this PR formalizes a concept of "relevancy" (naming is hard) that was already used to decide what patterns to report. Now we track it for every row, which in wide matches like the above can drastically cut on the number of cases we explore. After this fix, the above match is checked with linear-many cases instead of exponentially-many.

Fixes https://github.com/rust-lang/rust/issues/118437

r? `@cjgillot`
2023-12-24 14:40:36 +00:00
bors
08cc634f1a Auto merge of #117176 - bvanjoi:fix-116796, r=jackh726
mark ty::Const::Error when meet unsupport ty for const generic params

Close #116796
2023-12-24 10:28:25 +00:00
Ralf Jung
41020d1337 fix ICE when using raw ptr in a pattern 2023-12-24 11:10:38 +01:00
bors
cdd6374f16 Auto merge of #119218 - Nadrieril:nested-opaque-reveal, r=compiler-errors
Exhaustiveness: Reveal empty opaques in depth

Follow-up to https://github.com/rust-lang/rust/pull/116821. As noted [there](https://github.com/rust-lang/rust/pull/116821#discussion_r1376673420), the current implementation doesn't detect emptiness of opaques when the opaque is nested inside a type. This doesn't matter for stable behavior (which ignores nested empty types anyway) but does matter for the [`exhaustive_patterns`](https://github.com/rust-lang/rust/issues/51085)/[`min_exhaustive_patterns`](https://github.com/rust-lang/rust/pull/118803) features.

This PR fixes this behavior by adding `InhabitedPredicate::apply_reveal_opaque` that considers opaque types when determining inhabitedness.

r? `@compiler-errors`
2023-12-23 23:00:08 +00:00
bohan
0f814e3899 add test for #116796 2023-12-24 01:58:13 +08:00
Deadbeef
3006814404 add a test for ICE #112822 2023-12-23 15:09:55 +00:00
Nadrieril
34307ab7c5 Reveal empty opaques in depth 2023-12-23 14:59:12 +01:00
bors
edcbcc768a Auto merge of #119072 - fee1-dead-contrib:effects-fixes, r=compiler-errors
Clean up `check_consts` and misc fixes

1. Remove most of the logic around erroring with trait methods. I have kept the part resolving it to a concrete impl, as that is used for const stability checks.
2. Turning on `effects` causes ICE with generic args, due to `~const Tr` when `Tr` is not `#[const_trait]` tripping up expectation in code that handles generic args, more specifically here:
8681e077b8/compiler/rustc_hir_analysis/src/astconv/generics.rs (L377)

We set `arg_count.correct` to `Err` to correctly signal that an error has already been reported.

3. UI test blesses.

Edit(fmease): Fixes #117244 (UI test is in #119099 for now).

r? compiler-errors
2023-12-23 12:26:22 +00:00
Nadrieril
71e83347bb Improve performance on wide matches 2023-12-23 13:11:38 +01:00
Michael Goulet
eef023c806
Rollup merge of #119222 - eholk:into-async-iterator, r=compiler-errors,dtolnay
Add `IntoAsyncIterator`

This introduces the `IntoAsyncIterator` trait and uses it in the desugaring of the unstable `for await` loop syntax. This is mostly added for symmetry with `Iterator` and `IntoIterator`.

r? `@compiler-errors`

cc `@rust-lang/libs-api,` `@rust-lang/wg-async`
2023-12-22 21:41:04 -05:00
Michael Goulet
7dd095598b
Rollup merge of #119077 - tmiasko:lint, r=cjgillot
Separate MIR lints from validation

Add a MIR lint pass, enabled with -Zlint-mir, which identifies undefined or
likely erroneous behaviour.

The initial implementation mostly migrates existing checks of this nature from
MIR validator, where they did not belong (those checks have false positives and
there is nothing inherently invalid about MIR with undefined behaviour).

Fixes #104736
Fixes #104843
Fixes #116079
Fixes #116736
Fixes #118990
2023-12-22 21:41:03 -05:00
Urgau
cc6cbaad4b Add missing CFI sanitizer cfgs feature gate 2023-12-23 00:52:42 +01:00
bors
d6d7a93866 Auto merge of #118824 - aliemjay:perf-region-cons, r=compiler-errors
use Vec for region constraints instead of BTreeMap

~1% perf gain

Diagnostic regressions need more investigation.

r? `@ghost`
2023-12-22 20:28:48 +00:00
Eric Holk
aaa3e7642b
Update test outputs 2023-12-22 11:01:07 -08:00
Matthias Krüger
b24e8784de
Rollup merge of #119215 - mu001999:fix/119209, r=Nilstrieb
Emits error if has bound regions

Fixes #119209
2023-12-22 19:01:28 +01:00
r0cky
d3f466a3a7 Update test 2023-12-23 00:09:37 +08:00
r0cky
4830325a14 Emits error if has bound regions 2023-12-22 23:25:54 +08:00
bors
208dd2032b Auto merge of #118847 - eholk:for-await, r=compiler-errors
Add support for `for await` loops

This adds support for `for await` loops. This includes parsing, desugaring in AST->HIR lowering, and adding some support functions to the library.

Given a loop like:
```rust
for await i in iter {
    ...
}
```
this is desugared to something like:
```rust
let mut iter = iter.into_async_iter();
while let Some(i) = loop {
    match core::pin::Pin::new(&mut iter).poll_next(cx) {
        Poll::Ready(i) => break i,
        Poll::Pending => yield,
    }
} {
    ...
}
```

This PR also adds a basic `IntoAsyncIterator` trait. This is partly for symmetry with the way `Iterator` and `IntoIterator` work. The other reason is that for async iterators it's helpful to have a place apart from the data structure being iterated over to store state. `IntoAsyncIterator` gives us a good place to do this.

I've gated this feature behind `async_for_loop` and opened #118898 as the feature tracking issue.

r? `@compiler-errors`
2023-12-22 14:17:10 +00:00