Rollup merge of #64937 - estebank:dedup-closure-err, r=Centril

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`.
This commit is contained in:
Mazdak Farrokhzad 2019-10-01 09:55:39 +02:00 committed by GitHub
commit 46bf6ad416
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 153 deletions

View file

@ -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),

View file

@ -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()],

View file

@ -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

View file

@ -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

View file

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

View file

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