get_fn_like_arguments: avoid .unwrap

This commit is contained in:
Mazdak Farrokhzad 2020-04-03 03:00:24 +02:00
parent 9c0826902f
commit 08a724967e
2 changed files with 33 additions and 37 deletions

View File

@ -65,7 +65,7 @@ fn report_selection_error(
/// returns a span and `ArgKind` information that describes the
/// arguments it expects. This can be supplied to
/// `report_arg_count_mismatch`.
fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>);
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)>;
/// Reports an error when the number of arguments needed by a
/// trait match doesn't match the number that the expression
@ -611,10 +611,10 @@ fn report_selection_error(
)
} else {
let (closure_span, found) = found_did
.and_then(|did| self.tcx.hir().get_if_local(did))
.map(|node| {
let (found_span, found) = self.get_fn_like_arguments(node);
(Some(found_span), found)
.and_then(|did| {
let node = self.tcx.hir().get_if_local(did)?;
let (found_span, found) = self.get_fn_like_arguments(node)?;
Some((Some(found_span), found))
})
.unwrap_or((found_span, found));
@ -672,43 +672,38 @@ fn report_selection_error(
/// returns a span and `ArgKind` information that describes the
/// arguments it expects. This can be supplied to
/// `report_arg_count_mismatch`.
fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>) {
match node {
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)> {
let sm = self.tcx.sess.source_map();
let hir = self.tcx.hir();
Some(match node {
Node::Expr(&hir::Expr {
kind: hir::ExprKind::Closure(_, ref _decl, id, span, _),
..
}) => (
self.tcx.sess.source_map().guess_head_span(span),
self.tcx
.hir()
.body(id)
sm.guess_head_span(span),
hir.body(id)
.params
.iter()
.map(|arg| {
if let hir::Pat { kind: hir::PatKind::Tuple(ref args, _), span, .. } =
*arg.pat
{
ArgKind::Tuple(
Some(ArgKind::Tuple(
Some(span),
args.iter()
.map(|pat| {
let snippet = self
.tcx
.sess
.source_map()
.span_to_snippet(pat.span)
.unwrap();
(snippet, "_".to_owned())
sm.span_to_snippet(pat.span)
.ok()
.map(|snippet| (snippet, "_".to_owned()))
})
.collect::<Vec<_>>(),
)
.collect::<Option<Vec<_>>>()?,
))
} else {
let name =
self.tcx.sess.source_map().span_to_snippet(arg.pat.span).unwrap();
ArgKind::Arg(name, "_".to_owned())
let name = sm.span_to_snippet(arg.pat.span).ok()?;
Some(ArgKind::Arg(name, "_".to_owned()))
}
})
.collect::<Vec<ArgKind>>(),
.collect::<Option<Vec<ArgKind>>>()?,
),
Node::Item(&hir::Item { span, kind: hir::ItemKind::Fn(ref sig, ..), .. })
| Node::ImplItem(&hir::ImplItem {
@ -721,7 +716,7 @@ fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>) {
kind: hir::TraitItemKind::Fn(ref sig, _),
..
}) => (
self.tcx.sess.source_map().guess_head_span(span),
sm.guess_head_span(span),
sig.decl
.inputs
.iter()
@ -735,16 +730,12 @@ fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>) {
.collect::<Vec<ArgKind>>(),
),
Node::Ctor(ref variant_data) => {
let span = variant_data
.ctor_hir_id()
.map(|hir_id| self.tcx.hir().span(hir_id))
.unwrap_or(DUMMY_SP);
let span = self.tcx.sess.source_map().guess_head_span(span);
let span = variant_data.ctor_hir_id().map(|id| hir.span(id)).unwrap_or(DUMMY_SP);
let span = sm.guess_head_span(span);
(span, vec![ArgKind::empty(); variant_data.fields().len()])
}
_ => panic!("non-FnLike node found: {:?}", node),
}
})
}
/// Reports an error when the number of arguments needed by a

View File

@ -432,18 +432,23 @@ fn sig_of_closure_with_mismatched_number_of_arguments(
body: &hir::Body<'_>,
expected_sig: ExpectedSig<'tcx>,
) -> ClosureSignatures<'tcx> {
let expr_map_node = self.tcx.hir().get_if_local(expr_def_id).unwrap();
let hir = self.tcx.hir();
let expr_map_node = hir.get_if_local(expr_def_id).unwrap();
let expected_args: Vec<_> = expected_sig
.sig
.inputs()
.iter()
.map(|ty| ArgKind::from_expected_ty(ty, None))
.collect();
let (closure_span, found_args) = self.get_fn_like_arguments(expr_map_node);
let expected_span = expected_sig.cause_span.unwrap_or(closure_span);
let (closure_span, found_args) = match self.get_fn_like_arguments(expr_map_node) {
Some((sp, args)) => (Some(sp), args),
None => (None, Vec::new()),
};
let expected_span =
expected_sig.cause_span.unwrap_or_else(|| hir.span_if_local(expr_def_id).unwrap());
self.report_arg_count_mismatch(
expected_span,
Some(closure_span),
closure_span,
expected_args,
found_args,
true,