aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDawer <[email protected]>2021-05-06 13:26:05 +0100
committerDawer <[email protected]>2021-05-31 20:03:47 +0100
commitd6d77e8a35cb2ac63b877f73bdf0ea6e6a1578e4 (patch)
treefeea1e81b0dc0bdbb21466c04c373559b5508c78
parente711abc29032ddd395b60fccc47063e49785168f (diff)
Treat ctor of unhandled type as non-exhaustive.
-rw-r--r--crates/hir_ty/src/diagnostics/pattern.rs18
-rw-r--r--crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs10
2 files changed, 24 insertions, 4 deletions
diff --git a/crates/hir_ty/src/diagnostics/pattern.rs b/crates/hir_ty/src/diagnostics/pattern.rs
index 5c9419d2c..7b0b63d0b 100644
--- a/crates/hir_ty/src/diagnostics/pattern.rs
+++ b/crates/hir_ty/src/diagnostics/pattern.rs
@@ -356,4 +356,22 @@ fn main() {
356"#, 356"#,
357 ); 357 );
358 } 358 }
359
360 #[test]
361 fn no_panic_at_unimplemented_subpattern_type() {
362 check_diagnostics(
363 r#"
364struct S { a: char}
365fn main(v: S) {
366 match v { S{ a } => {} }
367 match v { S{ a: x } => {} }
368 match v { S{ a: 'a' } => {} }
369 match v { S{..} => {} }
370 match v { _ => {} }
371 match v { }
372 //^ Missing match arm
373}
374"#,
375 );
376 }
359} 377}
diff --git a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs
index ddf6b1198..1319745ce 100644
--- a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs
+++ b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs
@@ -419,6 +419,8 @@ impl SplitWildcard {
419 let cx = pcx.cx; 419 let cx = pcx.cx;
420 let make_range = 420 let make_range =
421 |start, end, scalar| IntRange(IntRange::from_range(cx, start, end, scalar)); 421 |start, end, scalar| IntRange(IntRange::from_range(cx, start, end, scalar));
422 // FIXME(iDawer) using NonExhaustive ctor for unhandled types
423 let unhandled = || smallvec![NonExhaustive];
422 424
423 // This determines the set of all possible constructors for the type `pcx.ty`. For numbers, 425 // This determines the set of all possible constructors for the type `pcx.ty`. For numbers,
424 // arrays and slices we use ranges and variable-length slices when appropriate. 426 // arrays and slices we use ranges and variable-length slices when appropriate.
@@ -431,7 +433,7 @@ impl SplitWildcard {
431 let all_ctors = match pcx.ty.kind(&Interner) { 433 let all_ctors = match pcx.ty.kind(&Interner) {
432 TyKind::Scalar(Scalar::Bool) => smallvec![make_range(0, 1, Scalar::Bool)], 434 TyKind::Scalar(Scalar::Bool) => smallvec![make_range(0, 1, Scalar::Bool)],
433 // TyKind::Array(..) if ... => todo!(), 435 // TyKind::Array(..) if ... => todo!(),
434 TyKind::Array(..) | TyKind::Slice(..) => todo!(), 436 TyKind::Array(..) | TyKind::Slice(..) => unhandled(),
435 &TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref _substs) => { 437 &TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref _substs) => {
436 let enum_data = cx.db.enum_data(enum_id); 438 let enum_data = cx.db.enum_data(enum_id);
437 439
@@ -466,7 +468,7 @@ impl SplitWildcard {
466 } else if cx.feature_exhaustive_patterns() { 468 } else if cx.feature_exhaustive_patterns() {
467 // If `exhaustive_patterns` is enabled, we exclude variants known to be 469 // If `exhaustive_patterns` is enabled, we exclude variants known to be
468 // uninhabited. 470 // uninhabited.
469 todo!() 471 unhandled()
470 } else { 472 } else {
471 enum_data 473 enum_data
472 .variants 474 .variants
@@ -475,8 +477,8 @@ impl SplitWildcard {
475 .collect() 477 .collect()
476 } 478 }
477 } 479 }
478 TyKind::Scalar(Scalar::Char) => todo!(), 480 TyKind::Scalar(Scalar::Char) => unhandled(),
479 TyKind::Scalar(Scalar::Int(..)) | TyKind::Scalar(Scalar::Uint(..)) => todo!(), 481 TyKind::Scalar(Scalar::Int(..)) | TyKind::Scalar(Scalar::Uint(..)) => unhandled(),
480 TyKind::Never if !cx.feature_exhaustive_patterns() && !pcx.is_top_level => { 482 TyKind::Never if !cx.feature_exhaustive_patterns() && !pcx.is_top_level => {
481 smallvec![NonExhaustive] 483 smallvec![NonExhaustive]
482 } 484 }