Skip to content
Permalink
Browse files

Deduplicate closure type errors

Closure typing obligations flow in both direcitons to properly infer
types. Because of this, we will get 2 type errors whenever there's
an unfulfilled obligation. To avoid this, we deduplicate them in the
`InferCtxt`.
  • Loading branch information...
estebank committed Oct 1, 2019
1 parent 22bc9e1 commit 13e9b3deb43b228264c6ae6ccf8fb3126790ee80
@@ -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),
@@ -885,6 +885,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()],
@@ -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
@@ -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

@@ -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
}
@@ -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`.

0 comments on commit 13e9b3d

Please sign in to comment.
You can’t perform that action at this time.