|
1 | 1 | use crate::check::FnCtxt; |
2 | 2 | use rustc_ast as ast; |
| 3 | + |
3 | 4 | use rustc_ast::util::lev_distance::find_best_match_for_name; |
4 | 5 | use rustc_data_structures::fx::FxHashMap; |
5 | 6 | use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; |
@@ -740,6 +741,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
740 | 741 | pat_ty |
741 | 742 | } |
742 | 743 |
|
| 744 | + fn maybe_suggest_range_literal( |
| 745 | + &self, |
| 746 | + e: &mut DiagnosticBuilder<'_>, |
| 747 | + opt_def_id: Option<hir::def_id::DefId>, |
| 748 | + ident: Ident, |
| 749 | + ) -> bool { |
| 750 | + match opt_def_id { |
| 751 | + Some(def_id) => match self.tcx.hir().get_if_local(def_id) { |
| 752 | + Some(hir::Node::Item(hir::Item { |
| 753 | + kind: hir::ItemKind::Const(_, body_id), .. |
| 754 | + })) => match self.tcx.hir().get(body_id.hir_id) { |
| 755 | + hir::Node::Expr(expr) => { |
| 756 | + if hir::is_range_literal(expr) { |
| 757 | + let span = self.tcx.hir().span(body_id.hir_id); |
| 758 | + if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) { |
| 759 | + e.span_suggestion_verbose( |
| 760 | + ident.span, |
| 761 | + "you may want to move the range into the match block", |
| 762 | + snip, |
| 763 | + Applicability::MachineApplicable, |
| 764 | + ); |
| 765 | + return true; |
| 766 | + } |
| 767 | + } |
| 768 | + } |
| 769 | + _ => (), |
| 770 | + }, |
| 771 | + _ => (), |
| 772 | + }, |
| 773 | + _ => (), |
| 774 | + } |
| 775 | + false |
| 776 | + } |
| 777 | + |
743 | 778 | fn emit_bad_pat_path( |
744 | 779 | &self, |
745 | 780 | mut e: DiagnosticBuilder<'_>, |
@@ -789,40 +824,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
789 | 824 | self.tcx.lang_items().range_to_inclusive_struct(), |
790 | 825 | ]; |
791 | 826 | if type_def_id != None && ranges.contains(&type_def_id) { |
792 | | - let generic_message = match item_def_id { |
793 | | - Some(def_id) => match self.tcx.hir().get_if_local(def_id) { |
794 | | - Some(hir::Node::Item(hir::Item { |
795 | | - kind: hir::ItemKind::Const(_, body_id), |
796 | | - .. |
797 | | - })) => match self.tcx.hir().get(body_id.hir_id) { |
798 | | - hir::Node::Expr(expr) => { |
799 | | - if hir::is_range_literal(expr) { |
800 | | - let span = self.tcx.hir().span(body_id.hir_id); |
801 | | - if let Ok(snip) = |
802 | | - self.tcx.sess.source_map().span_to_snippet(span) |
803 | | - { |
804 | | - e.span_suggestion_verbose( |
805 | | - span, |
806 | | - "you may want to move the range into the match block", |
807 | | - snip, |
808 | | - Applicability::MachineApplicable |
809 | | - ); |
810 | | - false |
811 | | - } else { |
812 | | - true |
813 | | - } |
814 | | - } else { |
815 | | - true |
816 | | - } |
817 | | - } |
818 | | - _ => true, |
819 | | - }, |
820 | | - _ => true, |
821 | | - }, |
822 | | - _ => true, |
823 | | - }; |
824 | | - |
825 | | - if generic_message { |
| 827 | + if !self.maybe_suggest_range_literal(&mut e, item_def_id, *ident) { |
826 | 828 | let msg = "constants only support matching by type, \ |
827 | 829 | if you meant to match against a range of values, \ |
828 | 830 | consider using a range pattern like `min ..= max` in the match block"; |
|
0 commit comments