about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/mod.rs5
-rw-r--r--src/librustc/traits/error_reporting.rs8
-rw-r--r--src/test/ui/anonymous-higher-ranked-lifetime.rs11
-rw-r--r--src/test/ui/anonymous-higher-ranked-lifetime.stderr141
-rw-r--r--src/test/ui/mismatched_types/issue-36053-2.rs1
-rw-r--r--src/test/ui/mismatched_types/issue-36053-2.stderr10
6 files changed, 23 insertions, 153 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 750ca4e32a6..b06b63455ba 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -23,7 +23,7 @@ use crate::ty::relate::RelateResult;
 use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
 use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, InferConst};
 use crate::ty::{FloatVid, IntVid, TyVid, ConstVid};
-use crate::util::nodemap::FxHashMap;
+use crate::util::nodemap::{FxHashMap, FxHashSet};
 
 use errors::DiagnosticBuilder;
 use rustc_data_structures::sync::Lrc;
@@ -155,6 +155,8 @@ pub struct InferCtxt<'a, 'tcx> {
     /// avoid reporting the same error twice.
     pub reported_trait_errors: RefCell<FxHashMap<Span, Vec<ty::Predicate<'tcx>>>>,
 
+    pub reported_closure_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
+
     /// When an error occurs, we want to avoid reporting "derived"
     /// errors that are due to this original failure. Normally, we
     /// handle this with the `err_count_on_creation` count, which
@@ -538,6 +540,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
                 selection_cache: Default::default(),
                 evaluation_cache: Default::default(),
                 reported_trait_errors: Default::default(),
+                reported_closure_mismatch: Default::default(),
                 tainted_by_errors_flag: Cell::new(false),
                 err_count_on_creation: tcx.sess.err_count(),
                 in_snapshot: Cell::new(false),
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 05b561a1ed5..a1c97d6c687 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -886,6 +886,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.tcx.hir().span_if_local(did)
                 ).map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def
 
+                if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) {
+                    // We check closures twice, with obligations flowing in different directions,
+                    // but we want to complain about them only once.
+                    return;
+                }
+
+                self.reported_closure_mismatch.borrow_mut().insert((span, found_span));
+
                 let found = match found_trait_ref.skip_binder().substs.type_at(1).kind {
                     ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
                     _ => vec![ArgKind::empty()],
diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.rs b/src/test/ui/anonymous-higher-ranked-lifetime.rs
index 8a1744ed5f8..898fe22fa23 100644
--- a/src/test/ui/anonymous-higher-ranked-lifetime.rs
+++ b/src/test/ui/anonymous-higher-ranked-lifetime.rs
@@ -1,26 +1,15 @@
 fn main() {
     f1(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     f2(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     f3(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     f4(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     f5(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     g1(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     g2(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     g3(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     g4(|_: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
     h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
 }
 
 // Basic
diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
index fbe2d192d0c..9be44c7f448 100644
--- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
@@ -10,18 +10,7 @@ LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
    |    --                   ------------ required by this bound in `f1`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
-   |
-LL |     f1(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), &()) -> _`
-...
-LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
-   |    --                   ------------ required by this bound in `f1`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5
    |
 LL |     f2(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
@@ -34,17 +23,6 @@ LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
    |
-LL |     f2(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&'a (), &()) -> _`
-...
-LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
-   |    --                           --------------- required by this bound in `f2`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
-   |
 LL |     f3(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
@@ -54,18 +32,7 @@ LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
    |    --                       --------------- required by this bound in `f3`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
-   |
-LL |     f3(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), &()) -> _`
-...
-LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
-   |    --                       --------------- required by this bound in `f3`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5
    |
 LL |     f4(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
@@ -76,18 +43,7 @@ LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
    |    --                   ----------------------- required by this bound in `f4`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
-   |
-LL |     f4(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), &'r ()) -> _`
-...
-LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
-   |    --                           --------------- required by this bound in `f4`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
    |
 LL |     f5(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
@@ -98,18 +54,7 @@ LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
    |    --                   -------------------------- required by this bound in `f5`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
-   |
-LL |     f5(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&'r (), &'r ()) -> _`
-...
-LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
-   |    --                           ------------------ required by this bound in `f5`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5
    |
 LL |     g1(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
@@ -120,18 +65,7 @@ LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
    |    --                   ------------------------- required by this bound in `g1`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
-   |
-LL |     g1(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
-...
-LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
-   |    --                   ------------------------- required by this bound in `g1`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
    |
 LL |     g2(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
@@ -142,18 +76,7 @@ LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
    |    --                   ---------------- required by this bound in `g2`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
-   |
-LL |     g2(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
-...
-LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
-   |    --                   ---------------- required by this bound in `g2`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
    |
 LL |     g3(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
@@ -164,18 +87,7 @@ LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
    |    --                   ------------------------------------ required by this bound in `g3`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
-   |
-LL |     g3(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
-...
-LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
-   |    --                           ---------------------------- required by this bound in `g3`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
    |
 LL |     g4(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
@@ -186,18 +98,7 @@ LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
    |    --                   --------------------------- required by this bound in `g4`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
-   |
-LL |     g4(|_: (), _: ()| {});
-   |     ^^ -------------- found signature of `fn((), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
-...
-LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
-   |    --                   --------------------------- required by this bound in `g4`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
    |
 LL |     h1(|_: (), _: (), _: (), _: ()| {});
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
@@ -208,18 +109,7 @@ LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
    |    --                   -------------------------------------------- required by this bound in `h1`
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
-   |
-LL |     h1(|_: (), _: (), _: (), _: ()| {});
-   |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &(), for<'r, 's> fn(&'r (), &'s ())) -> _`
-...
-LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
-   |    --                   -------------------------------------------- required by this bound in `h1`
-
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
+  --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
    |
 LL |     h2(|_: (), _: (), _: (), _: ()| {});
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
@@ -229,16 +119,5 @@ LL |     h2(|_: (), _: (), _: (), _: ()| {});
 LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
    |    --                   --------------------------------------------------------- required by this bound in `h2`
 
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
-   |
-LL |     h2(|_: (), _: (), _: (), _: ()| {});
-   |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
-   |     |
-   |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _`
-...
-LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
-   |    --                            ------------------------------------------------ required by this bound in `h2`
-
-error: aborting due to 22 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/mismatched_types/issue-36053-2.rs b/src/test/ui/mismatched_types/issue-36053-2.rs
index 9edfebcd494..9035e3380b0 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.rs
+++ b/src/test/ui/mismatched_types/issue-36053-2.rs
@@ -7,5 +7,4 @@ fn main() {
     once::<&str>("str").fuse().filter(|a: &str| true).count();
     //~^ ERROR no method named `count`
     //~| ERROR type mismatch in closure arguments
-    //~| ERROR type mismatch in closure arguments
 }
diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index 89c7b098115..72f3220cc1a 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -16,14 +16,6 @@ LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
    |                                |
    |                                expected signature of `for<'r> fn(&'r &str) -> _`
 
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/issue-36053-2.rs:7:32
-   |
-LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
-   |                                ^^^^^^ -------------- found signature of `for<'r> fn(&'r str) -> _`
-   |                                |
-   |                                expected signature of `fn(&&str) -> _`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0599`.