From 030fa9a337cb7f224c1d74fda04304c69e07787a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 13 Nov 2019 23:22:48 +0900 Subject: [PATCH] Avoid using same code --- src/librustc_typeck/check/pat.rs | 119 ++++++++++++++++--------------- 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index e7ec176614d33..9421dbc2b2c76 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -362,66 +362,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || ty.is_char() || ty.references_error() }; - let lhs_compat = numeric_or_char(lhs_ty); - let rhs_compat = numeric_or_char(rhs_ty); - - if !lhs_compat || !rhs_compat { - let span = if !lhs_compat && !rhs_compat { - span - } else if !lhs_compat { - begin.span - } else { - end.span - }; + let lhs_fail = !numeric_or_char(lhs_ty); + let rhs_fail = !numeric_or_char(rhs_ty); - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0029, - "only char and numeric types are allowed in range patterns" + if lhs_fail || rhs_fail { + self.emit_err_pat_range( + span, begin.span, end.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty ); - if !lhs_compat && !rhs_compat { - err.span_label( - begin.span, - &format!("this is of type `{}` but it should be `char` or numeric", lhs_ty) - ); - err.span_label( - end.span, - &format!("this is of type `{}` but it should be `char` or numeric", rhs_ty) - ); - } else if !lhs_compat { - err.span_label( - begin.span, - &format!("this is of type `{}` but it should be `char` or numeric", lhs_ty) - ); - if !rhs_ty.references_error() { - err.span_label( - end.span, - &format!("this is of type `{}`", rhs_ty) - ); - } - } else { - err.span_label( - end.span, - &format!("this is of type `{}` but it should be `char` or numeric", rhs_ty) - ); - if !lhs_ty.references_error() { - err.span_label( - begin.span, - &format!("this is of type `{}`", lhs_ty) - ); - } - } - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "In a match expression, only numbers and characters can be matched \ - against a range. This is because the compiler checks that the range \ - is non-empty at compile-time, and is unable to evaluate arbitrary \ - comparison functions. If you want to capture values of an orderable \ - type between two end-points, you can use a guard." - ); - } - err.emit(); return None; } @@ -435,6 +382,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(common_type) } + fn emit_err_pat_range( + &self, + span: Span, + begin_span: Span, + end_span: Span, + lhs_fail: bool, + rhs_fail: bool, + lhs_ty: Ty<'tcx>, + rhs_ty: Ty<'tcx>, + ) { + let span = if lhs_fail && rhs_fail { + span + } else if lhs_fail { + begin_span + } else { + end_span + }; + + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0029, + "only char and numeric types are allowed in range patterns" + ); + let msg = |ty| { + format!("this is of type `{}` but it should be `char` or numeric", ty) + }; + let mut one_side_err = |first_span, first_ty, second_span, second_ty: Ty<'_>| { + err.span_label(first_span, &msg(first_ty)); + if !second_ty.references_error() { + err.span_label( + second_span, + &format!("this is of type `{}`", second_ty) + ); + } + }; + if lhs_fail && rhs_fail { + err.span_label(begin_span, &msg(lhs_ty)); + err.span_label(end_span, &msg(rhs_ty)); + } else if lhs_fail { + one_side_err(begin_span, lhs_ty, end_span, rhs_ty); + } else { + one_side_err(end_span, rhs_ty, begin_span, lhs_ty); + } + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note( + "In a match expression, only numbers and characters can be matched \ + against a range. This is because the compiler checks that the range \ + is non-empty at compile-time, and is unable to evaluate arbitrary \ + comparison functions. If you want to capture values of an orderable \ + type between two end-points, you can use a guard." + ); + } + err.emit(); + } + fn check_pat_ident( &self, pat: &Pat,