diff options
| author | bors <bors@rust-lang.org> | 2024-05-07 20:01:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-05-07 20:01:18 +0000 |
| commit | faefc618cf48bd794cbc808448df1bf3f59f36af (patch) | |
| tree | 589ee8f0dc044a65ebaff64bfcf463ae711dae1b | |
| parent | b923ea4924fede68af127ac1857dcb0382e4caf9 (diff) | |
| parent | 446f78d05192ada54441f0a4ff237064d086e0e8 (diff) | |
| download | rust-faefc618cf48bd794cbc808448df1bf3f59f36af.tar.gz rust-faefc618cf48bd794cbc808448df1bf3f59f36af.zip | |
Auto merge of #124219 - gurry:122989-ice-unexpected-anon-const, r=compiler-errors
Do not ICE on `AnonConst`s in `diagnostic_hir_wf_check`
Fixes #122989
Below is the snippet from #122989 that ICEs:
```rust
trait Traitor<const N: N<2> = 1, const N: N<2> = N> {
fn N(&N) -> N<2> {
M
}
}
trait N<const N: Traitor<2> = 12> {}
```
The `AnonConst` that triggers the ICE is the `2` in the param `const N: N<2> = 1`. The currently existing code in `diagnostic_hir_wf_check` deals only with `AnonConst`s that are default values of some param, but the `2` is not a default value. It is just an `AnonConst` HIR node inside a `TraitRef` HIR node corresponding to `N<2>`. Therefore the existing code cannot handle it and this PR ensures that it does.
| -rw-r--r-- | compiler/rustc_hir_analysis/src/hir_wf_check.rs | 14 | ||||
| -rw-r--r-- | tests/crashes/122989.rs | 8 | ||||
| -rw-r--r-- | tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs | 21 | ||||
| -rw-r--r-- | tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr | 179 |
4 files changed, 208 insertions, 14 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 7014b23ff07..d6ba5fa9b5b 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -163,15 +163,17 @@ fn diagnostic_hir_wf_check<'tcx>( kind: hir::GenericParamKind::Type { default: Some(ty), .. }, .. }) => vec![*ty], - hir::Node::AnonConst(_) - if let Some(const_param_id) = - tcx.hir().opt_const_param_default_param_def_id(hir_id) + hir::Node::AnonConst(_) => { + if let Some(const_param_id) = tcx.hir().opt_const_param_default_param_def_id(hir_id) && let hir::Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { ty, .. }, .. - }) = tcx.hir_node_by_def_id(const_param_id) => - { - vec![*ty] + }) = tcx.hir_node_by_def_id(const_param_id) + { + vec![*ty] + } else { + vec![] + } } ref node => bug!("Unexpected node {:?}", node), }, diff --git a/tests/crashes/122989.rs b/tests/crashes/122989.rs deleted file mode 100644 index 70ad7d3b65c..00000000000 --- a/tests/crashes/122989.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #122989 -trait Traitor<const N: N<2> = 1, const N: N<2> = N> { - fn N(&N) -> N<2> { - M - } -} - -trait N<const N: Traitor<2> = 12> {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs new file mode 100644 index 00000000000..2995f26af4a --- /dev/null +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs @@ -0,0 +1,21 @@ +// Regression test for ICE #122989 +trait Foo<const N: Bar<2>> { +//~^ WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +//~| ERROR cycle detected when computing type of `Foo::N` +//~| ERROR cycle detected when computing type of `Foo::N` +//~| ERROR the trait `Foo` cannot be made into an object +//~| ERROR the trait `Foo` cannot be made into an object +//~| ERROR the trait `Foo` cannot be made into an object +//~| ERROR `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter + fn func() { + } +} + +trait Bar<const M: Foo<2>> {} +//~^ WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +//~| ERROR the trait `Foo` cannot be made into an object +//~| ERROR `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter + +fn main() {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr new file mode 100644 index 00000000000..e6fdc440873 --- /dev/null +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr @@ -0,0 +1,179 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:20 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default +help: if this is an object-safe trait, use `dyn` + | +LL | trait Foo<const N: dyn Bar<2>> { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:20 + | +LL | trait Bar<const M: Foo<2>> {} + | ^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: if this is an object-safe trait, use `dyn` + | +LL | trait Bar<const M: dyn Foo<2>> {} + | +++ + +error[E0391]: cycle detected when computing type of `Foo::N` + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^^^^^^^^^^ + | +note: ...which requires computing type of `Bar::M`... + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:11 + | +LL | trait Bar<const M: Foo<2>> {} + | ^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `Foo::N`, completing the cycle +note: cycle used when computing explicit predicates of trait `Foo` + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:1 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of `Foo::N` + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^^^^^^^^^^ + | +note: ...which requires computing type of `Bar::M`... + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:11 + | +LL | trait Bar<const M: Foo<2>> {} + | ^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `Foo::N`, completing the cycle +note: cycle used when computing explicit predicates of trait `Foo` + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:1 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:24 + | +LL | trait Foo<const N: Bar<2>> { + | ^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8 + | +LL | trait Foo<const N: Bar<2>> { + | --- this trait cannot be made into an object... +... +LL | fn func() { + | ^^^^ ...because associated function `func` has no `self` parameter +help: consider turning `func` into a method by giving it a `&self` argument + | +LL | fn func(&self) { + | +++++ +help: alternatively, consider constraining `func` so it does not apply to trait objects + | +LL | fn func() where Self: Sized { + | +++++++++++++++++ + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8 + | +LL | trait Foo<const N: Bar<2>> { + | --- this trait cannot be made into an object... +... +LL | fn func() { + | ^^^^ ...because associated function `func` has no `self` parameter +help: consider turning `func` into a method by giving it a `&self` argument + | +LL | fn func(&self) { + | +++++ +help: alternatively, consider constraining `func` so it does not apply to trait objects + | +LL | fn func() where Self: Sized { + | +++++++++++++++++ + +error: `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:20 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:11 + | +LL | trait Bar<const M: Foo<2>> {} + | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8 + | +LL | trait Foo<const N: Bar<2>> { + | --- this trait cannot be made into an object... +... +LL | fn func() { + | ^^^^ ...because associated function `func` has no `self` parameter +help: consider turning `func` into a method by giving it a `&self` argument + | +LL | fn func(&self) { + | +++++ +help: alternatively, consider constraining `func` so it does not apply to trait objects + | +LL | fn func() where Self: Sized { + | +++++++++++++++++ + +error: `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:20 + | +LL | trait Bar<const M: Foo<2>> {} + | ^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11 + | +LL | trait Foo<const N: Bar<2>> { + | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8 + | +LL | trait Foo<const N: Bar<2>> { + | --- this trait cannot be made into an object... +... +LL | fn func() { + | ^^^^ ...because associated function `func` has no `self` parameter + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider turning `func` into a method by giving it a `&self` argument + | +LL | fn func(&self) { + | +++++ +help: alternatively, consider constraining `func` so it does not apply to trait objects + | +LL | fn func() where Self: Sized { + | +++++++++++++++++ + +error: aborting due to 8 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0038, E0391. +For more information about an error, try `rustc --explain E0038`. |
