about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-01-03 19:39:39 +0000
committerMichael Goulet <michael@errs.io>2025-01-03 19:39:39 +0000
commite4193e2de8b1643361656d2cd10bc7402137f8e9 (patch)
tree2edd7d30e85d3411e28e8aa4ef69d410703927f8
parent6c8347b9588a302afebb81a1ae6daa64ec37abd0 (diff)
downloadrust-e4193e2de8b1643361656d2cd10bc7402137f8e9.tar.gz
rust-e4193e2de8b1643361656d2cd10bc7402137f8e9.zip
Do not ICE when encountering predicates from other items in method error reporting
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs10
-rw-r--r--tests/ui/methods/bad-wf-when-selecting-method.rs18
-rw-r--r--tests/ui/methods/bad-wf-when-selecting-method.stderr54
3 files changed, 79 insertions, 3 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 0b008fd10b5..7875f6710e9 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1067,7 +1067,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     )
                 ) {
                     continue;
-                };
+                }
 
                 match self.tcx.hir().get_if_local(item_def_id) {
                     // Unmet obligation comes from a `derive` macro, point at it once to
@@ -1181,8 +1181,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         entry.1.insert((cause_span, "unsatisfied trait bound introduced here"));
                         entry.2.push(p);
                     }
-                    Some(node) => unreachable!("encountered `{node:?}` due to `{cause:#?}`"),
-                    None => (),
+                    _ => {
+                        // It's possible to use well-formedness clauses to get obligations
+                        // which point arbitrary items like ADTs, so there's no use in ICEing
+                        // here if we find that the obligation originates from some other
+                        // node that we don't handle.
+                    }
                 }
             }
             let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
diff --git a/tests/ui/methods/bad-wf-when-selecting-method.rs b/tests/ui/methods/bad-wf-when-selecting-method.rs
new file mode 100644
index 00000000000..638d1ffa982
--- /dev/null
+++ b/tests/ui/methods/bad-wf-when-selecting-method.rs
@@ -0,0 +1,18 @@
+trait Wf {
+    type Assoc;
+}
+
+struct Wrapper<T: Wf<Assoc = U>, U>(T);
+
+trait Trait {
+    fn needs_sized(self);
+}
+
+fn test<T>(t: T) {
+    Wrapper(t).needs_sized();
+    //~^ ERROR the trait bound `T: Wf` is not satisfied
+    //~| ERROR the trait bound `T: Wf` is not satisfied
+    //~| the method `needs_sized` exists for struct `Wrapper<T, _>`, but its trait bounds were not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/methods/bad-wf-when-selecting-method.stderr b/tests/ui/methods/bad-wf-when-selecting-method.stderr
new file mode 100644
index 00000000000..e6d50034967
--- /dev/null
+++ b/tests/ui/methods/bad-wf-when-selecting-method.stderr
@@ -0,0 +1,54 @@
+error[E0277]: the trait bound `T: Wf` is not satisfied
+  --> $DIR/bad-wf-when-selecting-method.rs:12:13
+   |
+LL |     Wrapper(t).needs_sized();
+   |     ------- ^ the trait `Wf` is not implemented for `T`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `Wrapper`
+  --> $DIR/bad-wf-when-selecting-method.rs:5:19
+   |
+LL | struct Wrapper<T: Wf<Assoc = U>, U>(T);
+   |                   ^^^^^^^^^^^^^ required by this bound in `Wrapper`
+help: consider restricting type parameter `T` with trait `Wf`
+   |
+LL | fn test<T: Wf>(t: T) {
+   |          ++++
+
+error[E0277]: the trait bound `T: Wf` is not satisfied
+  --> $DIR/bad-wf-when-selecting-method.rs:12:5
+   |
+LL |     Wrapper(t).needs_sized();
+   |     ^^^^^^^^^^ the trait `Wf` is not implemented for `T`
+   |
+note: required by a bound in `Wrapper`
+  --> $DIR/bad-wf-when-selecting-method.rs:5:19
+   |
+LL | struct Wrapper<T: Wf<Assoc = U>, U>(T);
+   |                   ^^^^^^^^^^^^^ required by this bound in `Wrapper`
+help: consider restricting type parameter `T` with trait `Wf`
+   |
+LL | fn test<T: Wf>(t: T) {
+   |          ++++
+
+error[E0599]: the method `needs_sized` exists for struct `Wrapper<T, _>`, but its trait bounds were not satisfied
+  --> $DIR/bad-wf-when-selecting-method.rs:12:16
+   |
+LL | struct Wrapper<T: Wf<Assoc = U>, U>(T);
+   | ----------------------------------- method `needs_sized` not found for this struct
+...
+LL |     Wrapper(t).needs_sized();
+   |                ^^^^^^^^^^^ method cannot be called on `Wrapper<T, _>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `T: Wf`
+help: consider restricting the type parameter to satisfy the trait bound
+   |
+LL | fn test<T>(t: T) where T: Wf {
+   |                  +++++++++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0599.
+For more information about an error, try `rustc --explain E0277`.