about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-07 20:01:18 +0000
committerbors <bors@rust-lang.org>2024-05-07 20:01:18 +0000
commitfaefc618cf48bd794cbc808448df1bf3f59f36af (patch)
tree589ee8f0dc044a65ebaff64bfcf463ae711dae1b
parentb923ea4924fede68af127ac1857dcb0382e4caf9 (diff)
parent446f78d05192ada54441f0a4ff237064d086e0e8 (diff)
downloadrust-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.rs14
-rw-r--r--tests/crashes/122989.rs8
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs21
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr179
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`.