about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-11-13 14:28:15 -0800
committerEsteban Küber <esteban@kuber.com.ar>2019-11-13 14:28:15 -0800
commitbc1bd95e5a63643cfbbe1d84b2560117644bf8f4 (patch)
treedf15c31d279fac11c3db690b0481162036c88937
parent695fe965173795f9242dfcad6d1c07d7a17b106a (diff)
downloadrust-bc1bd95e5a63643cfbbe1d84b2560117644bf8f4.tar.gz
rust-bc1bd95e5a63643cfbbe1d84b2560117644bf8f4.zip
Do not ICE on recovery from unmet associated type bound obligation
-rw-r--r--src/librustc_typeck/check/mod.rs11
-rw-r--r--src/test/ui/issues/issue-66353.rs15
-rw-r--r--src/test/ui/issues/issue-66353.stderr18
3 files changed, 41 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 72b5018589c..be56157287c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -705,9 +705,14 @@ impl Inherited<'a, 'tcx> {
             span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
                       obligation);
         }
-        self.fulfillment_cx
-            .borrow_mut()
-            .register_predicate_obligation(self, obligation);
+        let _ = self.fulfillment_cx
+            .try_borrow_mut()
+            .map_err(|e| self.tcx.sess.delay_span_bug(obligation.cause.span, &format!(
+                "fullfillment context already borrowed: {:?} - {:?}",
+                e,
+                obligation,
+            )))
+            .map(|mut cx| cx.register_predicate_obligation(self, obligation));
     }
 
     fn register_predicates<I>(&self, obligations: I)
diff --git a/src/test/ui/issues/issue-66353.rs b/src/test/ui/issues/issue-66353.rs
new file mode 100644
index 00000000000..d8abdd5206e
--- /dev/null
+++ b/src/test/ui/issues/issue-66353.rs
@@ -0,0 +1,15 @@
+// #66353: ICE when trying to recover from incorrect associated type
+
+trait _Func<T> {
+    fn func(_: Self);
+}
+
+trait _A {
+    type AssocT;
+}
+
+fn main() {
+    _Func::< <() as _A>::AssocT >::func(());
+    //~^ ERROR the trait bound `(): _A` is not satisfied
+    //~| ERROR the trait bound `(): _Func<_>` is not satisfied
+}
diff --git a/src/test/ui/issues/issue-66353.stderr b/src/test/ui/issues/issue-66353.stderr
new file mode 100644
index 00000000000..8fd50300ca6
--- /dev/null
+++ b/src/test/ui/issues/issue-66353.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `(): _A` is not satisfied
+  --> $DIR/issue-66353.rs:12:14
+   |
+LL |     _Func::< <() as _A>::AssocT >::func(());
+   |              ^^^^^^^^^^^^^^^^^^ the trait `_A` is not implemented for `()`
+
+error[E0277]: the trait bound `(): _Func<_>` is not satisfied
+  --> $DIR/issue-66353.rs:12:41
+   |
+LL |     fn func(_: Self);
+   |     ----------------- required by `_Func::func`
+...
+LL |     _Func::< <() as _A>::AssocT >::func(());
+   |                                         ^^ the trait `_Func<_>` is not implemented for `()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.