Skip to content

Commit 3e056b9

Browse files
bors[bot]iDawer
andauthored
Merge #10213
10213: minor: Improve resilience of match checking r=flodiebold a=iDawer In bug condition the match checking strives to recover giving false no-error diagnostic. Suggested in #9105 (comment) Co-authored-by: Dawer <[email protected]>
2 parents 80552d4 + 68dfe19 commit 3e056b9

File tree

3 files changed

+32
-40
lines changed

3 files changed

+32
-40
lines changed

crates/hir_ty/src/diagnostics/expr.rs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
};
2323

2424
pub(crate) use hir_def::{
25-
body::{Body, BodySourceMap},
25+
body::Body,
2626
expr::{Expr, ExprId, MatchArm, Pat, PatId},
2727
LocalFieldId, VariantId,
2828
};
@@ -264,8 +264,7 @@ impl ExprValidator {
264264
db: &dyn HirDatabase,
265265
infer: Arc<InferenceResult>,
266266
) {
267-
let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
268-
db.body_with_source_map(self.owner);
267+
let body = db.body(self.owner);
269268

270269
let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() {
271270
return;
@@ -330,21 +329,6 @@ impl ExprValidator {
330329
infer: &infer,
331330
db,
332331
pattern_arena: &pattern_arena,
333-
panic_context: &|| {
334-
use syntax::AstNode;
335-
let match_expr_text = source_map
336-
.expr_syntax(match_expr)
337-
.ok()
338-
.and_then(|scrutinee_sptr| {
339-
let root = scrutinee_sptr.file_syntax(db.upcast());
340-
scrutinee_sptr.value.to_node(&root).syntax().parent()
341-
})
342-
.map(|node| node.to_string());
343-
format!(
344-
"expression:\n{}",
345-
match_expr_text.as_deref().unwrap_or("<synthesized expr>")
346-
)
347-
},
348332
};
349333
let report = compute_match_usefulness(&cx, &m_arms);
350334

crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use std::{
4949

5050
use hir_def::{EnumVariantId, HasModule, LocalFieldId, VariantId};
5151
use smallvec::{smallvec, SmallVec};
52+
use stdx::never;
5253

5354
use crate::{AdtId, Interner, Scalar, Ty, TyExt, TyKind};
5455

@@ -324,7 +325,10 @@ impl Constructor {
324325
PatKind::Leaf { .. } | PatKind::Deref { .. } => Single,
325326
&PatKind::Variant { enum_variant, .. } => Variant(enum_variant),
326327
&PatKind::LiteralBool { value } => IntRange(IntRange::from_bool(value)),
327-
PatKind::Or { .. } => cx.bug("Or-pattern should have been expanded earlier on."),
328+
PatKind::Or { .. } => {
329+
never!("Or-pattern should have been expanded earlier on.");
330+
Wildcard
331+
}
328332
}
329333
}
330334

@@ -371,7 +375,7 @@ impl Constructor {
371375
/// this checks for inclusion.
372376
// We inline because this has a single call site in `Matrix::specialize_constructor`.
373377
#[inline]
374-
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 {
375379
// This must be kept in sync with `is_covered_by_any`.
376380
match (self, other) {
377381
// Wildcards cover anything
@@ -396,17 +400,18 @@ impl Constructor {
396400
// Only a wildcard pattern can match the special extra constructor.
397401
(NonExhaustive, _) => false,
398402

399-
_ => pcx.cx.bug(&format!(
400-
"trying to compare incompatible constructors {:?} and {:?}",
401-
self, other
402-
)),
403+
_ => {
404+
never!("trying to compare incompatible constructors {:?} and {:?}", self, other);
405+
// Continue with 'whatever is covered' supposed to result in false no-error diagnostic.
406+
true
407+
}
403408
}
404409
}
405410

406411
/// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is
407412
/// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is
408413
/// assumed to have been split from a wildcard.
409-
fn is_covered_by_any(&self, pcx: PatCtxt<'_>, used_ctors: &[Constructor]) -> bool {
414+
fn is_covered_by_any(&self, _pcx: PatCtxt<'_>, used_ctors: &[Constructor]) -> bool {
410415
if used_ctors.is_empty() {
411416
return false;
412417
}
@@ -427,7 +432,8 @@ impl Constructor {
427432
// This constructor is never covered by anything else
428433
NonExhaustive => false,
429434
Str(..) | FloatRange(..) | Opaque | Missing | Wildcard => {
430-
pcx.cx.bug(&format!("found unexpected ctor in all_ctors: {:?}", self))
435+
never!("found unexpected ctor in all_ctors: {:?}", self);
436+
true
431437
}
432438
}
433439
}
@@ -683,7 +689,8 @@ impl Fields {
683689
}
684690
}
685691
ty_kind => {
686-
cx.bug(&format!("Unexpected type for `Single` constructor: {:?}", ty_kind))
692+
never!("Unexpected type for `Single` constructor: {:?}", ty_kind);
693+
Fields::from_single_pattern(wildcard_from_ty(ty))
687694
}
688695
},
689696
Slice(..) => {
@@ -745,7 +752,8 @@ impl Fields {
745752
// can ignore this issue.
746753
TyKind::Ref(..) => PatKind::Deref { subpattern: subpatterns.next().unwrap() },
747754
TyKind::Slice(..) | TyKind::Array(..) => {
748-
pcx.cx.bug(&format!("bad slice pattern {:?} {:?}", ctor, pcx.ty))
755+
never!("bad slice pattern {:?} {:?}", ctor, pcx.ty);
756+
PatKind::Wild
749757
}
750758
_ => PatKind::Wild,
751759
},
@@ -755,11 +763,17 @@ impl Fields {
755763
Constructor::IntRange(_) => UNHANDLED,
756764
NonExhaustive => PatKind::Wild,
757765
Wildcard => return Pat::wildcard_from_ty(pcx.ty.clone()),
758-
Opaque => pcx.cx.bug("we should not try to apply an opaque constructor"),
759-
Missing => pcx.cx.bug(
760-
"trying to apply the `Missing` constructor;\
761-
this should have been done in `apply_constructors`",
762-
),
766+
Opaque => {
767+
never!("we should not try to apply an opaque constructor");
768+
PatKind::Wild
769+
}
770+
Missing => {
771+
never!(
772+
"trying to apply the `Missing` constructor; \
773+
this should have been done in `apply_constructors`",
774+
);
775+
PatKind::Wild
776+
}
763777
};
764778

765779
Pat { ty: pcx.ty.clone(), kind: Box::new(pat) }

crates/hir_ty/src/diagnostics/match_check/usefulness.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ pub(crate) struct MatchCheckCtx<'a> {
295295
pub(crate) db: &'a dyn HirDatabase,
296296
/// Lowered patterns from arms plus generated by the check.
297297
pub(crate) pattern_arena: &'a RefCell<PatternArena>,
298-
pub(crate) panic_context: &'a dyn Fn() -> String,
299298
}
300299

301300
impl<'a> MatchCheckCtx<'a> {
@@ -328,11 +327,6 @@ impl<'a> MatchCheckCtx<'a> {
328327
pub(super) fn type_of(&self, pat: PatId) -> Ty {
329328
self.pattern_arena.borrow()[pat].ty.clone()
330329
}
331-
332-
#[track_caller]
333-
pub(super) fn bug(&self, info: &str) -> ! {
334-
panic!("bug: {}\n{}", info, (self.panic_context)());
335-
}
336330
}
337331

338332
#[derive(Copy, Clone)]
@@ -1131,7 +1125,7 @@ pub(crate) fn compute_match_usefulness(
11311125
arms: &[MatchArm],
11321126
) -> UsefulnessReport {
11331127
let mut matrix = Matrix::empty();
1134-
let arm_usefulness: Vec<_> = arms
1128+
let arm_usefulness = arms
11351129
.iter()
11361130
.copied()
11371131
.map(|arm| {

0 commit comments

Comments
 (0)