aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs12
-rw-r--r--crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs29
-rw-r--r--crates/hir_ty/src/diagnostics/match_check/usefulness.rs9
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
300impl<'a> MatchCheckCtx<'a> { 301impl<'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