diff options
author | Dawer <[email protected]> | 2021-05-06 13:26:05 +0100 |
---|---|---|
committer | Dawer <[email protected]> | 2021-05-31 20:03:47 +0100 |
commit | d6d77e8a35cb2ac63b877f73bdf0ea6e6a1578e4 (patch) | |
tree | feea1e81b0dc0bdbb21466c04c373559b5508c78 | |
parent | e711abc29032ddd395b60fccc47063e49785168f (diff) |
Treat ctor of unhandled type as non-exhaustive.
-rw-r--r-- | crates/hir_ty/src/diagnostics/pattern.rs | 18 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs | 10 |
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#" | ||
364 | struct S { a: char} | ||
365 | fn 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 | } |