about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-08-10 00:00:32 +0200
committerGitHub <noreply@github.com>2022-08-10 00:00:32 +0200
commit2be32e8e9b92c7d3d1b984ade5ed062afd1b1f6c (patch)
treeb70f0c8ec1f3f6c1e828427fc549eeae6418918a
parent4add5148a577ac5c146eabab5b094025bb8b14eb (diff)
parent75cc9cddf7ebcbf00213bbdf6a9e2c78bc0876f1 (diff)
downloadrust-2be32e8e9b92c7d3d1b984ade5ed062afd1b1f6c.tar.gz
rust-2be32e8e9b92c7d3d1b984ade5ed062afd1b1f6c.zip
Rollup merge of #100261 - luqmana:suggestions-overflow, r=lcnr
Set tainted errors bit before emitting coerce suggestions.

Fixes #100246.

#89576 basically got 99% of the way there but the match typechecking code (which calls `coerce_inner`) also needed a similar fix.
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs4
-rw-r--r--src/test/ui/typeck/issue-100246.rs30
-rw-r--r--src/test/ui/typeck/issue-100246.stderr13
3 files changed, 47 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index 540a8c3a83d..49dc5532abd 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -1479,6 +1479,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 }
             }
             Err(coercion_error) => {
+                // Mark that we've failed to coerce the types here to suppress
+                // any superfluous errors we might encounter while trying to
+                // emit or provide suggestions on how to fix the initial error.
+                fcx.set_tainted_by_errors();
                 let (expected, found) = if label_expression_as_expected {
                     // In the case where this is a "forced unit", like
                     // `break`, we want to call the `()` "expected"
diff --git a/src/test/ui/typeck/issue-100246.rs b/src/test/ui/typeck/issue-100246.rs
new file mode 100644
index 00000000000..8f0b34bab0c
--- /dev/null
+++ b/src/test/ui/typeck/issue-100246.rs
@@ -0,0 +1,30 @@
+#![recursion_limit = "5"] // To reduce noise
+
+//expect incompatible type error when ambiguous traits are in scope
+//and not an overflow error on the span in the main function.
+
+struct Ratio<T>(T);
+
+pub trait Pow {
+    fn pow(self) -> Self;
+}
+
+impl<'a, T> Pow for &'a Ratio<T>
+where
+    &'a T: Pow,
+{
+    fn pow(self) -> Self {
+        self
+    }
+}
+
+fn downcast<'a, W: ?Sized>() -> std::io::Result<&'a W> {
+    todo!()
+}
+
+struct Other;
+
+fn main() -> std::io::Result<()> {
+    let other: Other = downcast()?;//~ERROR 28:24: 28:35: `?` operator has incompatible types
+    Ok(())
+}
diff --git a/src/test/ui/typeck/issue-100246.stderr b/src/test/ui/typeck/issue-100246.stderr
new file mode 100644
index 00000000000..8b77de94e89
--- /dev/null
+++ b/src/test/ui/typeck/issue-100246.stderr
@@ -0,0 +1,13 @@
+error[E0308]: `?` operator has incompatible types
+  --> $DIR/issue-100246.rs:28:24
+   |
+LL |     let other: Other = downcast()?;
+   |                        ^^^^^^^^^^^ expected struct `Other`, found reference
+   |
+   = note: `?` operator cannot convert from `&_` to `Other`
+   = note: expected struct `Other`
+           found reference `&_`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.