Skip to content

Commit 030fa9a

Browse files
committed
Avoid using same code
1 parent 302cf6d commit 030fa9a

File tree

1 file changed

+61
-58
lines changed
  • src/librustc_typeck/check

1 file changed

+61
-58
lines changed

src/librustc_typeck/check/pat.rs

+61-58
Original file line numberDiff line numberDiff line change
@@ -362,66 +362,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362362
|| ty.is_char()
363363
|| ty.references_error()
364364
};
365-
let lhs_compat = numeric_or_char(lhs_ty);
366-
let rhs_compat = numeric_or_char(rhs_ty);
367-
368-
if !lhs_compat || !rhs_compat {
369-
let span = if !lhs_compat && !rhs_compat {
370-
span
371-
} else if !lhs_compat {
372-
begin.span
373-
} else {
374-
end.span
375-
};
365+
let lhs_fail = !numeric_or_char(lhs_ty);
366+
let rhs_fail = !numeric_or_char(rhs_ty);
376367

377-
let mut err = struct_span_err!(
378-
self.tcx.sess,
379-
span,
380-
E0029,
381-
"only char and numeric types are allowed in range patterns"
368+
if lhs_fail || rhs_fail {
369+
self.emit_err_pat_range(
370+
span, begin.span, end.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty
382371
);
383-
if !lhs_compat && !rhs_compat {
384-
err.span_label(
385-
begin.span,
386-
&format!("this is of type `{}` but it should be `char` or numeric", lhs_ty)
387-
);
388-
err.span_label(
389-
end.span,
390-
&format!("this is of type `{}` but it should be `char` or numeric", rhs_ty)
391-
);
392-
} else if !lhs_compat {
393-
err.span_label(
394-
begin.span,
395-
&format!("this is of type `{}` but it should be `char` or numeric", lhs_ty)
396-
);
397-
if !rhs_ty.references_error() {
398-
err.span_label(
399-
end.span,
400-
&format!("this is of type `{}`", rhs_ty)
401-
);
402-
}
403-
} else {
404-
err.span_label(
405-
end.span,
406-
&format!("this is of type `{}` but it should be `char` or numeric", rhs_ty)
407-
);
408-
if !lhs_ty.references_error() {
409-
err.span_label(
410-
begin.span,
411-
&format!("this is of type `{}`", lhs_ty)
412-
);
413-
}
414-
}
415-
if self.tcx.sess.teach(&err.get_code().unwrap()) {
416-
err.note(
417-
"In a match expression, only numbers and characters can be matched \
418-
against a range. This is because the compiler checks that the range \
419-
is non-empty at compile-time, and is unable to evaluate arbitrary \
420-
comparison functions. If you want to capture values of an orderable \
421-
type between two end-points, you can use a guard."
422-
);
423-
}
424-
err.emit();
425372
return None;
426373
}
427374

@@ -435,6 +382,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
435382
Some(common_type)
436383
}
437384

385+
fn emit_err_pat_range(
386+
&self,
387+
span: Span,
388+
begin_span: Span,
389+
end_span: Span,
390+
lhs_fail: bool,
391+
rhs_fail: bool,
392+
lhs_ty: Ty<'tcx>,
393+
rhs_ty: Ty<'tcx>,
394+
) {
395+
let span = if lhs_fail && rhs_fail {
396+
span
397+
} else if lhs_fail {
398+
begin_span
399+
} else {
400+
end_span
401+
};
402+
403+
let mut err = struct_span_err!(
404+
self.tcx.sess,
405+
span,
406+
E0029,
407+
"only char and numeric types are allowed in range patterns"
408+
);
409+
let msg = |ty| {
410+
format!("this is of type `{}` but it should be `char` or numeric", ty)
411+
};
412+
let mut one_side_err = |first_span, first_ty, second_span, second_ty: Ty<'_>| {
413+
err.span_label(first_span, &msg(first_ty));
414+
if !second_ty.references_error() {
415+
err.span_label(
416+
second_span,
417+
&format!("this is of type `{}`", second_ty)
418+
);
419+
}
420+
};
421+
if lhs_fail && rhs_fail {
422+
err.span_label(begin_span, &msg(lhs_ty));
423+
err.span_label(end_span, &msg(rhs_ty));
424+
} else if lhs_fail {
425+
one_side_err(begin_span, lhs_ty, end_span, rhs_ty);
426+
} else {
427+
one_side_err(end_span, rhs_ty, begin_span, lhs_ty);
428+
}
429+
if self.tcx.sess.teach(&err.get_code().unwrap()) {
430+
err.note(
431+
"In a match expression, only numbers and characters can be matched \
432+
against a range. This is because the compiler checks that the range \
433+
is non-empty at compile-time, and is unable to evaluate arbitrary \
434+
comparison functions. If you want to capture values of an orderable \
435+
type between two end-points, you can use a guard."
436+
);
437+
}
438+
err.emit();
439+
}
440+
438441
fn check_pat_ident(
439442
&self,
440443
pat: &Pat,

0 commit comments

Comments
 (0)