diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-12-14 14:07:59 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-14 14:07:59 +0100 |
| commit | 752f79a018e5852d3eb15f031610003bafb1b368 (patch) | |
| tree | ea21e5c735b5278df49c42f41686828107fc2ad2 | |
| parent | 352e3232b91ff87fb7f11866a4912593a7bbd0be (diff) | |
| parent | d15315cf9d2fbe3c2d348267567feacaddf89c50 (diff) | |
| download | rust-752f79a018e5852d3eb15f031610003bafb1b368.tar.gz rust-752f79a018e5852d3eb15f031610003bafb1b368.zip | |
Rollup merge of #134279 - jieyouxu:return-adjustment-target, r=compiler-errors
(Re-)return adjustment target if adjust kind is never-to-any
This PR fixes #134162 where we ICE'd on
```rs
fn main() {
struct X;
let _ = [X] == [panic!(); 2];
}
```
In https://github.com/rust-lang/rust/pull/121208#discussion_r1494187622, there was a change
```diff
- if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
- let reported = self.dcx().span_delayed_bug(
- expr.span,
- "expression with never type wound up being adjusted",
- );
- return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] {
- target.to_owned()
- } else {
- Ty::new_error(self.tcx(), reported)
- };
- }
+ if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
+ self.dcx()
+ .span_bug(expr.span, "expression with never type wound up being adjusted");
+ }
```
It turned out returning the adjustment target if the adjustment kind is `NeverToAny` is necessary, as otherwise we will go through a series of `delay_bug`s and eventually find that we constructed a `TyKind::Error` without having actually emitted an error.
This PR addresses that by re-returning the adjustment target if the adjustment kind is `NeverToAny`, partially reverting this change from #121208.
This PR has two commits:
1. The first commit adds a regression test for #134162, which will ICE (on stable 1.83.0, beta and nightly 2024-12-13).
2. The second commit is the partial revert, which will fix the ICE.
cc `@nnethercote` FYI as this is related to #121208 changes. The changes from #121208 exposed that we lacked test coverage for the code pattern reported in #134162.
| -rw-r--r-- | compiler/rustc_hir_typeck/src/expr.rs | 9 | ||||
| -rw-r--r-- | tests/crashes/134162.rs | 8 | ||||
| -rw-r--r-- | tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/typeck/rhs-ty-hint-134162.rs | 18 |
6 files changed, 58 insertions, 10 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 65345048bfc..66978399efb 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -72,12 +72,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.try_structurally_resolve_type(expr.span, ty).is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) { - if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) { + if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) { let reported = self.dcx().span_delayed_bug( expr.span, "expression with never type wound up being adjusted", ); - return Ty::new_error(self.tcx(), reported); + + return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] { + target.to_owned() + } else { + Ty::new_error(self.tcx(), reported) + }; } let adj_ty = self.next_ty_var(expr.span); diff --git a/tests/crashes/134162.rs b/tests/crashes/134162.rs deleted file mode 100644 index 9e5a4a1cb0b..00000000000 --- a/tests/crashes/134162.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #134162 - -fn main() { - struct X; - - let xs = [X, X, X]; - let eq = xs == [panic!("panic evaluated"); 2]; -} diff --git a/tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr b/tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr new file mode 100644 index 00000000000..ff189e36ba0 --- /dev/null +++ b/tests/ui/typeck/rhs-ty-hint-134162.e2018.stderr @@ -0,0 +1,11 @@ +error[E0369]: binary operation `==` cannot be applied to type `[X; 1]` + --> $DIR/rhs-ty-hint-134162.rs:16:17 + | +LL | let _ = [X] == [panic!(); 2]; + | --- ^^ ------------- [_; 2] + | | + | [X; 1] + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr b/tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr new file mode 100644 index 00000000000..ff189e36ba0 --- /dev/null +++ b/tests/ui/typeck/rhs-ty-hint-134162.e2021.stderr @@ -0,0 +1,11 @@ +error[E0369]: binary operation `==` cannot be applied to type `[X; 1]` + --> $DIR/rhs-ty-hint-134162.rs:16:17 + | +LL | let _ = [X] == [panic!(); 2]; + | --- ^^ ------------- [_; 2] + | | + | [X; 1] + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr b/tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr new file mode 100644 index 00000000000..ff189e36ba0 --- /dev/null +++ b/tests/ui/typeck/rhs-ty-hint-134162.e2024.stderr @@ -0,0 +1,11 @@ +error[E0369]: binary operation `==` cannot be applied to type `[X; 1]` + --> $DIR/rhs-ty-hint-134162.rs:16:17 + | +LL | let _ = [X] == [panic!(); 2]; + | --- ^^ ------------- [_; 2] + | | + | [X; 1] + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/typeck/rhs-ty-hint-134162.rs b/tests/ui/typeck/rhs-ty-hint-134162.rs new file mode 100644 index 00000000000..a14b4bcfd26 --- /dev/null +++ b/tests/ui/typeck/rhs-ty-hint-134162.rs @@ -0,0 +1,18 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/134162>. +//! +//! <https://github.com/rust-lang/rust/pull/110877> introduced RHS type hints for when a ty doesn't +//! support a bin op. In the suggestion path, there was a `delay_bug`. +//! <https://github.com/rust-lang/rust/pull/121208> converted this `delay_bug` to `bug`, which did +//! not trigger any test failures as we did not have test coverage for this particular case. This +//! manifested in an ICE as reported in <https://github.com/rust-lang/rust/issues/134162>. + +//@ revisions: e2018 e2021 e2024 +//@[e2018] edition: 2018 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 + +fn main() { + struct X; + let _ = [X] == [panic!(); 2]; + //[e2018,e2021,e2024]~^ ERROR binary operation `==` cannot be applied to type `[X; 1]` +} |
