Skip to content

Commit 7ca64cc

Browse files
authored
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`.
2 parents 3ff0f33 + 13e9b3d commit 7ca64cc

File tree

6 files changed

+23
-153
lines changed

6 files changed

+23
-153
lines changed

src/librustc/infer/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::ty::relate::RelateResult;
2323
use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
2424
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, InferConst};
2525
use crate::ty::{FloatVid, IntVid, TyVid, ConstVid};
26-
use crate::util::nodemap::FxHashMap;
26+
use crate::util::nodemap::{FxHashMap, FxHashSet};
2727

2828
use errors::DiagnosticBuilder;
2929
use rustc_data_structures::sync::Lrc;
@@ -155,6 +155,8 @@ pub struct InferCtxt<'a, 'tcx> {
155155
/// avoid reporting the same error twice.
156156
pub reported_trait_errors: RefCell<FxHashMap<Span, Vec<ty::Predicate<'tcx>>>>,
157157

158+
pub reported_closure_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
159+
158160
/// When an error occurs, we want to avoid reporting "derived"
159161
/// errors that are due to this original failure. Normally, we
160162
/// handle this with the `err_count_on_creation` count, which
@@ -538,6 +540,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
538540
selection_cache: Default::default(),
539541
evaluation_cache: Default::default(),
540542
reported_trait_errors: Default::default(),
543+
reported_closure_mismatch: Default::default(),
541544
tainted_by_errors_flag: Cell::new(false),
542545
err_count_on_creation: tcx.sess.err_count(),
543546
in_snapshot: Cell::new(false),

src/librustc/traits/error_reporting.rs

+8
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
885885
self.tcx.hir().span_if_local(did)
886886
).map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def
887887

888+
if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) {
889+
// We check closures twice, with obligations flowing in different directions,
890+
// but we want to complain about them only once.
891+
return;
892+
}
893+
894+
self.reported_closure_mismatch.borrow_mut().insert((span, found_span));
895+
888896
let found = match found_trait_ref.skip_binder().substs.type_at(1).kind {
889897
ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
890898
_ => vec![ArgKind::empty()],

src/test/ui/anonymous-higher-ranked-lifetime.rs

-11
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
11
fn main() {
22
f1(|_: (), _: ()| {}); //~ ERROR type mismatch
3-
//~^ ERROR type mismatch
43
f2(|_: (), _: ()| {}); //~ ERROR type mismatch
5-
//~^ ERROR type mismatch
64
f3(|_: (), _: ()| {}); //~ ERROR type mismatch
7-
//~^ ERROR type mismatch
85
f4(|_: (), _: ()| {}); //~ ERROR type mismatch
9-
//~^ ERROR type mismatch
106
f5(|_: (), _: ()| {}); //~ ERROR type mismatch
11-
//~^ ERROR type mismatch
127
g1(|_: (), _: ()| {}); //~ ERROR type mismatch
13-
//~^ ERROR type mismatch
148
g2(|_: (), _: ()| {}); //~ ERROR type mismatch
15-
//~^ ERROR type mismatch
169
g3(|_: (), _: ()| {}); //~ ERROR type mismatch
17-
//~^ ERROR type mismatch
1810
g4(|_: (), _: ()| {}); //~ ERROR type mismatch
19-
//~^ ERROR type mismatch
2011
h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
21-
//~^ ERROR type mismatch
2212
h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
23-
//~^ ERROR type mismatch
2413
}
2514

2615
// Basic

src/test/ui/anonymous-higher-ranked-lifetime.stderr

+10-131
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,7 @@ LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
1010
| -- ------------ required by this bound in `f1`
1111

1212
error[E0631]: type mismatch in closure arguments
13-
--> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
14-
|
15-
LL | f1(|_: (), _: ()| {});
16-
| ^^ -------------- found signature of `fn((), ()) -> _`
17-
| |
18-
| expected signature of `fn(&(), &()) -> _`
19-
...
20-
LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
21-
| -- ------------ required by this bound in `f1`
22-
23-
error[E0631]: type mismatch in closure arguments
24-
--> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
13+
--> $DIR/anonymous-higher-ranked-lifetime.rs:3:5
2514
|
2615
LL | f2(|_: (), _: ()| {});
2716
| ^^ -------------- found signature of `fn((), ()) -> _`
@@ -34,17 +23,6 @@ LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
3423
error[E0631]: type mismatch in closure arguments
3524
--> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
3625
|
37-
LL | f2(|_: (), _: ()| {});
38-
| ^^ -------------- found signature of `fn((), ()) -> _`
39-
| |
40-
| expected signature of `fn(&'a (), &()) -> _`
41-
...
42-
LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
43-
| -- --------------- required by this bound in `f2`
44-
45-
error[E0631]: type mismatch in closure arguments
46-
--> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
47-
|
4826
LL | f3(|_: (), _: ()| {});
4927
| ^^ -------------- found signature of `fn((), ()) -> _`
5028
| |
@@ -54,18 +32,7 @@ LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
5432
| -- --------------- required by this bound in `f3`
5533

5634
error[E0631]: type mismatch in closure arguments
57-
--> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
58-
|
59-
LL | f3(|_: (), _: ()| {});
60-
| ^^ -------------- found signature of `fn((), ()) -> _`
61-
| |
62-
| expected signature of `fn(&(), &()) -> _`
63-
...
64-
LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
65-
| -- --------------- required by this bound in `f3`
66-
67-
error[E0631]: type mismatch in closure arguments
68-
--> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
35+
--> $DIR/anonymous-higher-ranked-lifetime.rs:5:5
6936
|
7037
LL | f4(|_: (), _: ()| {});
7138
| ^^ -------------- found signature of `fn((), ()) -> _`
@@ -76,18 +43,7 @@ LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
7643
| -- ----------------------- required by this bound in `f4`
7744

7845
error[E0631]: type mismatch in closure arguments
79-
--> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
80-
|
81-
LL | f4(|_: (), _: ()| {});
82-
| ^^ -------------- found signature of `fn((), ()) -> _`
83-
| |
84-
| expected signature of `fn(&(), &'r ()) -> _`
85-
...
86-
LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
87-
| -- --------------- required by this bound in `f4`
88-
89-
error[E0631]: type mismatch in closure arguments
90-
--> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
46+
--> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
9147
|
9248
LL | f5(|_: (), _: ()| {});
9349
| ^^ -------------- found signature of `fn((), ()) -> _`
@@ -98,18 +54,7 @@ LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
9854
| -- -------------------------- required by this bound in `f5`
9955

10056
error[E0631]: type mismatch in closure arguments
101-
--> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
102-
|
103-
LL | f5(|_: (), _: ()| {});
104-
| ^^ -------------- found signature of `fn((), ()) -> _`
105-
| |
106-
| expected signature of `fn(&'r (), &'r ()) -> _`
107-
...
108-
LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
109-
| -- ------------------ required by this bound in `f5`
110-
111-
error[E0631]: type mismatch in closure arguments
112-
--> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
57+
--> $DIR/anonymous-higher-ranked-lifetime.rs:7:5
11358
|
11459
LL | g1(|_: (), _: ()| {});
11560
| ^^ -------------- found signature of `fn((), ()) -> _`
@@ -120,18 +65,7 @@ LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
12065
| -- ------------------------- required by this bound in `g1`
12166

12267
error[E0631]: type mismatch in closure arguments
123-
--> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
124-
|
125-
LL | g1(|_: (), _: ()| {});
126-
| ^^ -------------- found signature of `fn((), ()) -> _`
127-
| |
128-
| expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
129-
...
130-
LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
131-
| -- ------------------------- required by this bound in `g1`
132-
133-
error[E0631]: type mismatch in closure arguments
134-
--> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
68+
--> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
13569
|
13670
LL | g2(|_: (), _: ()| {});
13771
| ^^ -------------- found signature of `fn((), ()) -> _`
@@ -142,18 +76,7 @@ LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
14276
| -- ---------------- required by this bound in `g2`
14377

14478
error[E0631]: type mismatch in closure arguments
145-
--> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
146-
|
147-
LL | g2(|_: (), _: ()| {});
148-
| ^^ -------------- found signature of `fn((), ()) -> _`
149-
| |
150-
| expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
151-
...
152-
LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
153-
| -- ---------------- required by this bound in `g2`
154-
155-
error[E0631]: type mismatch in closure arguments
156-
--> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
79+
--> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
15780
|
15881
LL | g3(|_: (), _: ()| {});
15982
| ^^ -------------- found signature of `fn((), ()) -> _`
@@ -164,18 +87,7 @@ LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
16487
| -- ------------------------------------ required by this bound in `g3`
16588

16689
error[E0631]: type mismatch in closure arguments
167-
--> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
168-
|
169-
LL | g3(|_: (), _: ()| {});
170-
| ^^ -------------- found signature of `fn((), ()) -> _`
171-
| |
172-
| expected signature of `fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
173-
...
174-
LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
175-
| -- ---------------------------- required by this bound in `g3`
176-
177-
error[E0631]: type mismatch in closure arguments
178-
--> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
90+
--> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
17991
|
18092
LL | g4(|_: (), _: ()| {});
18193
| ^^ -------------- found signature of `fn((), ()) -> _`
@@ -186,18 +98,7 @@ LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
18698
| -- --------------------------- required by this bound in `g4`
18799

188100
error[E0631]: type mismatch in closure arguments
189-
--> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
190-
|
191-
LL | g4(|_: (), _: ()| {});
192-
| ^^ -------------- found signature of `fn((), ()) -> _`
193-
| |
194-
| expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
195-
...
196-
LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
197-
| -- --------------------------- required by this bound in `g4`
198-
199-
error[E0631]: type mismatch in closure arguments
200-
--> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
101+
--> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
201102
|
202103
LL | h1(|_: (), _: (), _: (), _: ()| {});
203104
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
@@ -208,18 +109,7 @@ LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
208109
| -- -------------------------------------------- required by this bound in `h1`
209110

210111
error[E0631]: type mismatch in closure arguments
211-
--> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
212-
|
213-
LL | h1(|_: (), _: (), _: (), _: ()| {});
214-
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
215-
| |
216-
| expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &(), for<'r, 's> fn(&'r (), &'s ())) -> _`
217-
...
218-
LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
219-
| -- -------------------------------------------- required by this bound in `h1`
220-
221-
error[E0631]: type mismatch in closure arguments
222-
--> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
112+
--> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
223113
|
224114
LL | h2(|_: (), _: (), _: (), _: ()| {});
225115
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
@@ -229,16 +119,5 @@ LL | h2(|_: (), _: (), _: (), _: ()| {});
229119
LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
230120
| -- --------------------------------------------------------- required by this bound in `h2`
231121

232-
error[E0631]: type mismatch in closure arguments
233-
--> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
234-
|
235-
LL | h2(|_: (), _: (), _: (), _: ()| {});
236-
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
237-
| |
238-
| expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _`
239-
...
240-
LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
241-
| -- ------------------------------------------------ required by this bound in `h2`
242-
243-
error: aborting due to 22 previous errors
122+
error: aborting due to 11 previous errors
244123

src/test/ui/mismatched_types/issue-36053-2.rs

-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@ fn main() {
77
once::<&str>("str").fuse().filter(|a: &str| true).count();
88
//~^ ERROR no method named `count`
99
//~| ERROR type mismatch in closure arguments
10-
//~| ERROR type mismatch in closure arguments
1110
}

src/test/ui/mismatched_types/issue-36053-2.stderr

+1-9
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
1616
| |
1717
| expected signature of `for<'r> fn(&'r &str) -> _`
1818

19-
error[E0631]: type mismatch in closure arguments
20-
--> $DIR/issue-36053-2.rs:7:32
21-
|
22-
LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
23-
| ^^^^^^ -------------- found signature of `for<'r> fn(&'r str) -> _`
24-
| |
25-
| expected signature of `fn(&&str) -> _`
26-
27-
error: aborting due to 3 previous errors
19+
error: aborting due to 2 previous errors
2820

2921
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)