Skip to content

Commit d15f070

Browse files
committed
Fix wrong report on closure args mismatch when a
ref is expected but not found Fixes rust-lang#42143 Adds E0604 for closure argument type mismatch
1 parent 1b41019 commit d15f070

File tree

2 files changed

+47
-37
lines changed

2 files changed

+47
-37
lines changed

src/librustc/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,4 +1943,5 @@ register_diagnostics! {
19431943
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
19441944
E0566, // conflicting representation hints
19451945
E0587, // conflicting packed and align representation hints
1946+
E0604, // closure arguments mismatch
19461947
}

src/librustc/traits/error_reporting.rs

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -684,44 +684,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
684684
expected_found.found,
685685
expected_trait_ty.is_closure())
686686
} else if let &TypeError::Sorts(ref expected_found) = e {
687-
let expected_len = if let ty::TyTuple(tys, _) = expected_found.expected.sty {
688-
tys.len()
689-
} else if let ty::TyRef(_,ty::TypeAndMut{ty,..}) = expected_found.expected.sty {
690-
if let ty::TyTuple(tys,_) = ty.sty {
691-
tys.len()
692-
} else {
693-
1
694-
}
695-
} else {
696-
1
697-
};
698-
let found_len = if let ty::TyTuple(tys, _) = expected_found.found.sty {
699-
tys.len()
700-
} else if let ty::TyRef(_,ty::TypeAndMut{ty,..}) = expected_found.found.sty {
701-
if let ty::TyTuple(tys,_) = ty.sty {
702-
tys.len()
703-
} else {
704-
1
687+
let mut count_mismatch = None;
688+
if let ty::TyTuple(expected_tys, _) = expected_found.expected.sty {
689+
if let ty::TyTuple(found_tys, _) = expected_found.found.sty {
690+
if expected_tys.len() != found_tys.len() {
691+
// Expected `|| { }`, found `|x, y| { }`
692+
// Expected `fn(x) -> ()`, found `|| { }`
693+
count_mismatch = Some(self.report_arg_count_mismatch(span,
694+
found_span,
695+
expected_tys.len(),
696+
found_tys.len(),
697+
expected_trait_ty.is_closure()));
698+
}
705699
}
700+
}
701+
702+
//} else if false {
703+
// self.report_type_argument_mismatch(span,
704+
// found_span,
705+
// expected_trait_ty,
706+
// expected_trait_ref,
707+
// actual_trait_ref,
708+
// e)
709+
if count_mismatch.is_none() {
710+
self.report_closure_arg_mismatch(span,
711+
found_span,
712+
expected_trait_ty,
713+
expected_trait_ref,
714+
actual_trait_ref,
715+
e)
706716
} else {
707-
1
708-
};
709-
710-
if expected_len != found_len {
711-
// Expected `|| { }`, found `|x, y| { }`
712-
// Expected `fn(x) -> ()`, found `|| { }`
713-
self.report_arg_count_mismatch(span,
714-
found_span,
715-
expected_len,
716-
found_len,
717-
expected_trait_ty.is_closure())
718-
} else {
719-
self.report_type_argument_mismatch(span,
720-
found_span,
721-
expected_trait_ty,
722-
expected_trait_ref,
723-
actual_trait_ref,
724-
e)
717+
count_mismatch.unwrap()
725718
}
726719
} else {
727720
self.report_type_argument_mismatch(span,
@@ -767,7 +760,23 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
767760

768761
err
769762
}
770-
763+
fn report_closure_arg_mismatch(&self,
764+
span: Span,
765+
found_span: Option<Span>,
766+
expected: Ty<'tcx>,
767+
expected_ref: ty::PolyTraitRef<'tcx>,
768+
found: ty::PolyTraitRef<'tcx>,
769+
_type_error: &TypeError<'tcx>) -> DiagnosticBuilder<'tcx>
770+
{
771+
let mut err = struct_span_err!(self.tcx.sess, span, E0604,
772+
"type mismatch in closure arguments");
773+
if let Some(sp) = found_span {
774+
err.span_label(span, format!("expected closure that takes a `{}`", found.self_ty().subst().type_at(0)));
775+
err.span_label(sp, format!("takes a `{}`", expected_ref.0));
776+
}
777+
778+
err
779+
}
771780
fn report_arg_count_mismatch(&self,
772781
span: Span,
773782
found_span: Option<Span>,

0 commit comments

Comments
 (0)