Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deduplicate closure type errors #64937

Merged
merged 1 commit into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down
8 changes: 8 additions & 0 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()],
Expand Down
11 changes: 0 additions & 11 deletions src/test/ui/anonymous-higher-ranked-lifetime.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
141 changes: 10 additions & 131 deletions src/test/ui/anonymous-higher-ranked-lifetime.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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((), ()) -> _`
Expand All @@ -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((), ()) -> _`
| |
Expand All @@ -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((), ()) -> _`
Expand All @@ -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((), ()) -> _`
Expand All @@ -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((), ()) -> _`
Expand All @@ -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((), ()) -> _`
Expand All @@ -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((), ()) -> _`
Expand All @@ -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((), ()) -> _`
Expand All @@ -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((), (), (), ()) -> _`
Expand All @@ -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((), (), (), ()) -> _`
Expand All @@ -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

1 change: 0 additions & 1 deletion src/test/ui/mismatched_types/issue-36053-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 1 addition & 9 deletions src/test/ui/mismatched_types/issue-36053-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.