about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-09-23 00:36:36 +0200
committerGitHub <noreply@github.com>2019-09-23 00:36:36 +0200
commitb66e7323e63027a29af213abb031c584bb5c2767 (patch)
treeea661b10a798c8387eba6dfad106c19729d20018
parentda58e11d0265ee8412a21d63cf972955754769b6 (diff)
parentdaed67481511b65475069214cd8325ca9d018509 (diff)
downloadrust-b66e7323e63027a29af213abb031c584bb5c2767.tar.gz
rust-b66e7323e63027a29af213abb031c584bb5c2767.zip
Rollup merge of #64674 - estebank:knock-down-the-wall, r=Centril
Propagate `types.err` in locals further to avoid spurious knock-down errors

Fix #33575, fix #44504.
-rw-r--r--src/librustc_typeck/check/coercion.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs22
-rw-r--r--src/test/ui/issues/issue-33575.rs4
-rw-r--r--src/test/ui/issues/issue-33575.stderr9
4 files changed, 35 insertions, 8 deletions
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index ee4f0a868c1..d98e1f3e128 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -163,7 +163,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         // Just ignore error types.
         if a.references_error() || b.references_error() {
-            return success(vec![], b, vec![]);
+            return success(vec![], self.fcx.tcx.types.err, vec![]);
         }
 
         if a.is_never() {
@@ -821,7 +821,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let (adjustments, _) = self.register_infer_ok_obligations(ok);
         self.apply_adjustments(expr, adjustments);
-        Ok(target)
+        Ok(if expr_ty.references_error() {
+            self.tcx.types.err
+        } else {
+            target
+        })
     }
 
     /// Same as `try_coerce()`, but without side-effects.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c96eab86298..de3ed96b033 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -153,7 +153,7 @@ use self::method::{MethodCallee, SelfSource};
 use self::TupleArgumentsFlag::*;
 
 /// The type of a local binding, including the revealed type for anon types.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct LocalTy<'tcx> {
     decl_ty: Ty<'tcx>,
     revealed_ty: Ty<'tcx>
@@ -3754,15 +3754,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some(ref init) = local.init {
             let init_ty = self.check_decl_initializer(local, &init);
-            if init_ty.references_error() {
-                self.write_ty(local.hir_id, init_ty);
-            }
+            self.overwrite_local_ty_if_err(local, t, init_ty);
         }
 
         self.check_pat_top(&local.pat, t, None);
         let pat_ty = self.node_ty(local.pat.hir_id);
-        if pat_ty.references_error() {
-            self.write_ty(local.hir_id, pat_ty);
+        self.overwrite_local_ty_if_err(local, t, pat_ty);
+    }
+
+    fn overwrite_local_ty_if_err(&self, local: &'tcx hir::Local, decl_ty: Ty<'tcx>, ty: Ty<'tcx>) {
+        if ty.references_error() {
+            // Override the types everywhere with `types.err` to avoid knock down errors.
+            self.write_ty(local.hir_id, ty);
+            self.write_ty(local.pat.hir_id, ty);
+            let local_ty = LocalTy {
+                decl_ty,
+                revealed_ty: ty,
+            };
+            self.locals.borrow_mut().insert(local.hir_id, local_ty);
+            self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
         }
     }
 
diff --git a/src/test/ui/issues/issue-33575.rs b/src/test/ui/issues/issue-33575.rs
new file mode 100644
index 00000000000..09c499452ad
--- /dev/null
+++ b/src/test/ui/issues/issue-33575.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let baz = ().foo(); //~ ERROR no method named `foo` found for type `()` in the current scope
+    <i32 as std::str::FromStr>::from_str(&baz); // No complaints about `str` being unsized
+}
diff --git a/src/test/ui/issues/issue-33575.stderr b/src/test/ui/issues/issue-33575.stderr
new file mode 100644
index 00000000000..e6b74d262c3
--- /dev/null
+++ b/src/test/ui/issues/issue-33575.stderr
@@ -0,0 +1,9 @@
+error[E0599]: no method named `foo` found for type `()` in the current scope
+  --> $DIR/issue-33575.rs:2:18
+   |
+LL |     let baz = ().foo();
+   |                  ^^^ method not found in `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.