diff options
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 12 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs | 29 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/match_check/usefulness.rs | 9 |
3 files changed, 36 insertions, 14 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 0a7e6ee52..44d5f6b22 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -357,6 +357,18 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
357 | infer: &infer, | 357 | infer: &infer, |
358 | db, | 358 | db, |
359 | pattern_arena: &pattern_arena, | 359 | pattern_arena: &pattern_arena, |
360 | eprint_panic_context: &|| { | ||
361 | use syntax::AstNode; | ||
362 | if let Ok(scrutinee_sptr) = source_map.expr_syntax(match_expr) { | ||
363 | let root = scrutinee_sptr.file_syntax(db.upcast()); | ||
364 | if let Some(match_ast) = scrutinee_sptr.value.to_node(&root).syntax().parent() { | ||
365 | eprintln!( | ||
366 | "Match checking is about to panic on this expression:\n{}", | ||
367 | match_ast.to_string(), | ||
368 | ); | ||
369 | } | ||
370 | } | ||
371 | }, | ||
360 | }; | 372 | }; |
361 | let report = compute_match_usefulness(&cx, &m_arms); | 373 | let report = compute_match_usefulness(&cx, &m_arms); |
362 | 374 | ||
diff --git a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs index 6711fbb4a..15ec5cf45 100644 --- a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs +++ b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs | |||
@@ -328,7 +328,7 @@ impl Constructor { | |||
328 | PatKind::Leaf { .. } | PatKind::Deref { .. } => Single, | 328 | PatKind::Leaf { .. } | PatKind::Deref { .. } => Single, |
329 | &PatKind::Variant { enum_variant, .. } => Variant(enum_variant), | 329 | &PatKind::Variant { enum_variant, .. } => Variant(enum_variant), |
330 | &PatKind::LiteralBool { value } => IntRange(IntRange::from_bool(value)), | 330 | &PatKind::LiteralBool { value } => IntRange(IntRange::from_bool(value)), |
331 | PatKind::Or { .. } => panic!("bug: Or-pattern should have been expanded earlier on."), | 331 | PatKind::Or { .. } => cx.bug("Or-pattern should have been expanded earlier on."), |
332 | } | 332 | } |
333 | } | 333 | } |
334 | 334 | ||
@@ -375,7 +375,7 @@ impl Constructor { | |||
375 | /// this checks for inclusion. | 375 | /// this checks for inclusion. |
376 | // We inline because this has a single call site in `Matrix::specialize_constructor`. | 376 | // We inline because this has a single call site in `Matrix::specialize_constructor`. |
377 | #[inline] | 377 | #[inline] |
378 | pub(super) fn is_covered_by(&self, _pcx: PatCtxt<'_>, other: &Self) -> bool { | 378 | pub(super) fn is_covered_by(&self, pcx: PatCtxt<'_>, other: &Self) -> bool { |
379 | // This must be kept in sync with `is_covered_by_any`. | 379 | // This must be kept in sync with `is_covered_by_any`. |
380 | match (self, other) { | 380 | match (self, other) { |
381 | // Wildcards cover anything | 381 | // Wildcards cover anything |
@@ -400,17 +400,17 @@ impl Constructor { | |||
400 | // Only a wildcard pattern can match the special extra constructor. | 400 | // Only a wildcard pattern can match the special extra constructor. |
401 | (NonExhaustive, _) => false, | 401 | (NonExhaustive, _) => false, |
402 | 402 | ||
403 | _ => panic!( | 403 | _ => pcx.cx.bug(&format!( |
404 | "bug: trying to compare incompatible constructors {:?} and {:?}", | 404 | "trying to compare incompatible constructors {:?} and {:?}", |
405 | self, other | 405 | self, other |
406 | ), | 406 | )), |
407 | } | 407 | } |
408 | } | 408 | } |
409 | 409 | ||
410 | /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is | 410 | /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is |
411 | /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is | 411 | /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is |
412 | /// assumed to have been split from a wildcard. | 412 | /// assumed to have been split from a wildcard. |
413 | fn is_covered_by_any(&self, _pcx: PatCtxt<'_>, used_ctors: &[Constructor]) -> bool { | 413 | fn is_covered_by_any(&self, pcx: PatCtxt<'_>, used_ctors: &[Constructor]) -> bool { |
414 | if used_ctors.is_empty() { | 414 | if used_ctors.is_empty() { |
415 | return false; | 415 | return false; |
416 | } | 416 | } |
@@ -431,7 +431,7 @@ impl Constructor { | |||
431 | // This constructor is never covered by anything else | 431 | // This constructor is never covered by anything else |
432 | NonExhaustive => false, | 432 | NonExhaustive => false, |
433 | Str(..) | FloatRange(..) | Opaque | Missing | Wildcard => { | 433 | Str(..) | FloatRange(..) | Opaque | Missing | Wildcard => { |
434 | panic!("bug: found unexpected ctor in all_ctors: {:?}", self) | 434 | pcx.cx.bug(&format!("found unexpected ctor in all_ctors: {:?}", self)) |
435 | } | 435 | } |
436 | } | 436 | } |
437 | } | 437 | } |
@@ -683,7 +683,9 @@ impl Fields { | |||
683 | } | 683 | } |
684 | } | 684 | } |
685 | } | 685 | } |
686 | _ => panic!("Unexpected type for `Single` constructor: {:?}", ty), | 686 | ty_kind => { |
687 | cx.bug(&format!("Unexpected type for `Single` constructor: {:?}", ty_kind)) | ||
688 | } | ||
687 | }, | 689 | }, |
688 | Slice(..) => { | 690 | Slice(..) => { |
689 | unimplemented!() | 691 | unimplemented!() |
@@ -748,7 +750,7 @@ impl Fields { | |||
748 | // can ignore this issue. | 750 | // can ignore this issue. |
749 | TyKind::Ref(..) => PatKind::Deref { subpattern: subpatterns.next().unwrap() }, | 751 | TyKind::Ref(..) => PatKind::Deref { subpattern: subpatterns.next().unwrap() }, |
750 | TyKind::Slice(..) | TyKind::Array(..) => { | 752 | TyKind::Slice(..) | TyKind::Array(..) => { |
751 | panic!("bug: bad slice pattern {:?} {:?}", ctor, pcx.ty) | 753 | pcx.cx.bug(&format!("bad slice pattern {:?} {:?}", ctor, pcx.ty)) |
752 | } | 754 | } |
753 | _ => PatKind::Wild, | 755 | _ => PatKind::Wild, |
754 | }, | 756 | }, |
@@ -758,10 +760,11 @@ impl Fields { | |||
758 | Constructor::IntRange(_) => UNHANDLED, | 760 | Constructor::IntRange(_) => UNHANDLED, |
759 | NonExhaustive => PatKind::Wild, | 761 | NonExhaustive => PatKind::Wild, |
760 | Wildcard => return Pat::wildcard_from_ty(pcx.ty), | 762 | Wildcard => return Pat::wildcard_from_ty(pcx.ty), |
761 | Opaque => panic!("bug: we should not try to apply an opaque constructor"), | 763 | Opaque => pcx.cx.bug("we should not try to apply an opaque constructor"), |
762 | Missing => { | 764 | Missing => pcx.cx.bug( |
763 | panic!("bug: trying to apply the `Missing` constructor; this should have been done in `apply_constructors`") | 765 | "trying to apply the `Missing` constructor;\ |
764 | } | 766 | this should have been done in `apply_constructors`", |
767 | ), | ||
765 | }; | 768 | }; |
766 | 769 | ||
767 | Pat { ty: pcx.ty.clone(), kind: Box::new(pat) } | 770 | Pat { ty: pcx.ty.clone(), kind: Box::new(pat) } |
diff --git a/crates/hir_ty/src/diagnostics/match_check/usefulness.rs b/crates/hir_ty/src/diagnostics/match_check/usefulness.rs index 44e08b6e9..cb322a3de 100644 --- a/crates/hir_ty/src/diagnostics/match_check/usefulness.rs +++ b/crates/hir_ty/src/diagnostics/match_check/usefulness.rs | |||
@@ -295,6 +295,7 @@ pub(crate) struct MatchCheckCtx<'a> { | |||
295 | pub(crate) db: &'a dyn HirDatabase, | 295 | pub(crate) db: &'a dyn HirDatabase, |
296 | /// Lowered patterns from arms plus generated by the check. | 296 | /// Lowered patterns from arms plus generated by the check. |
297 | pub(crate) pattern_arena: &'a RefCell<PatternArena>, | 297 | pub(crate) pattern_arena: &'a RefCell<PatternArena>, |
298 | pub(crate) eprint_panic_context: &'a dyn Fn(), | ||
298 | } | 299 | } |
299 | 300 | ||
300 | impl<'a> MatchCheckCtx<'a> { | 301 | impl<'a> MatchCheckCtx<'a> { |
@@ -327,6 +328,12 @@ impl<'a> MatchCheckCtx<'a> { | |||
327 | pub(super) fn type_of(&self, pat: PatId) -> Ty { | 328 | pub(super) fn type_of(&self, pat: PatId) -> Ty { |
328 | self.pattern_arena.borrow()[pat].ty.clone() | 329 | self.pattern_arena.borrow()[pat].ty.clone() |
329 | } | 330 | } |
331 | |||
332 | #[track_caller] | ||
333 | pub(super) fn bug(&self, info: &str) -> ! { | ||
334 | (self.eprint_panic_context)(); | ||
335 | panic!("bug: {}", info); | ||
336 | } | ||
330 | } | 337 | } |
331 | 338 | ||
332 | #[derive(Copy, Clone)] | 339 | #[derive(Copy, Clone)] |
@@ -737,7 +744,7 @@ impl SubPatSet { | |||
737 | } | 744 | } |
738 | Seq { subpats: new_subpats } | 745 | Seq { subpats: new_subpats } |
739 | } | 746 | } |
740 | Alt { .. } => panic!("bug"), | 747 | Alt { .. } => panic!("bug"), // `self` is a patstack |
741 | } | 748 | } |
742 | } | 749 | } |
743 | 750 | ||