aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/_match.rs29
-rw-r--r--crates/ra_hir_ty/src/tests.rs27
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs29
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs38
5 files changed, 101 insertions, 26 deletions
diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs
index 779e78574..149f65042 100644
--- a/crates/ra_hir_ty/src/_match.rs
+++ b/crates/ra_hir_ty/src/_match.rs
@@ -573,14 +573,20 @@ pub(crate) fn is_useful(
573 matrix: &Matrix, 573 matrix: &Matrix,
574 v: &PatStack, 574 v: &PatStack,
575) -> MatchCheckResult<Usefulness> { 575) -> MatchCheckResult<Usefulness> {
576 // Handle the special case of enums with no variants. In that case, no match 576 // Handle two special cases:
577 // arm is useful. 577 // - enum with no variants
578 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) = 578 // - `!` type
579 cx.infer[cx.match_expr].strip_references() 579 // In those cases, no match arm is useful.
580 { 580 match cx.infer[cx.match_expr].strip_references() {
581 if cx.db.enum_data(*enum_id).variants.is_empty() { 581 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) => {
582 if cx.db.enum_data(*enum_id).variants.is_empty() {
583 return Ok(Usefulness::NotUseful);
584 }
585 }
586 Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) => {
582 return Ok(Usefulness::NotUseful); 587 return Ok(Usefulness::NotUseful);
583 } 588 }
589 _ => (),
584 } 590 }
585 591
586 if v.is_empty() { 592 if v.is_empty() {
@@ -1918,6 +1924,17 @@ mod tests {
1918 } 1924 }
1919 1925
1920 #[test] 1926 #[test]
1927 fn type_never() {
1928 let content = r"
1929 fn test_fn(never: !) {
1930 match never {}
1931 }
1932 ";
1933
1934 check_no_diagnostic(content);
1935 }
1936
1937 #[test]
1921 fn enum_never_ref() { 1938 fn enum_never_ref() {
1922 let content = r" 1939 let content = r"
1923 enum Never {} 1940 enum Never {}
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index 588d81282..d60732e19 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -361,6 +361,33 @@ fn no_such_field_with_feature_flag_diagnostics() {
361} 361}
362 362
363#[test] 363#[test]
364fn no_such_field_enum_with_feature_flag_diagnostics() {
365 let diagnostics = TestDB::with_files(
366 r#"
367 //- /lib.rs crate:foo cfg:feature=foo
368 enum Foo {
369 #[cfg(not(feature = "foo"))]
370 Buz,
371 #[cfg(feature = "foo")]
372 Bar,
373 Baz
374 }
375
376 fn test_fn(f: Foo) {
377 match f {
378 Foo::Bar => {},
379 Foo::Baz => {},
380 }
381 }
382 "#,
383 )
384 .diagnostics()
385 .0;
386
387 assert_snapshot!(diagnostics, @r###""###);
388}
389
390#[test]
364fn no_such_field_with_feature_flag_diagnostics_on_struct_lit() { 391fn no_such_field_with_feature_flag_diagnostics_on_struct_lit() {
365 let diagnostics = TestDB::with_files( 392 let diagnostics = TestDB::with_files(
366 r#" 393 r#"
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs
index 29e38a06c..07398ddcc 100644
--- a/crates/ra_hir_ty/src/tests/macros.rs
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -269,7 +269,7 @@ fn test() { S.foo()<|>; }
269} 269}
270 270
271#[test] 271#[test]
272fn infer_impl_items_generated_by_macros() { 272fn infer_assoc_items_generated_by_macros() {
273 let t = type_at( 273 let t = type_at(
274 r#" 274 r#"
275//- /main.rs 275//- /main.rs
@@ -288,7 +288,7 @@ fn test() { S.foo()<|>; }
288} 288}
289 289
290#[test] 290#[test]
291fn infer_impl_items_generated_by_macros_chain() { 291fn infer_assoc_items_generated_by_macros_chain() {
292 let t = type_at( 292 let t = type_at(
293 r#" 293 r#"
294//- /main.rs 294//- /main.rs
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs
index 8a1292c7a..115ad8328 100644
--- a/crates/ra_hir_ty/src/tests/regression.rs
+++ b/crates/ra_hir_ty/src/tests/regression.rs
@@ -535,6 +535,35 @@ fn foo(b: Bar) {
535} 535}
536 536
537#[test] 537#[test]
538fn issue_4235_name_conflicts() {
539 assert_snapshot!(
540 infer(r#"
541struct FOO {}
542static FOO:FOO = FOO {};
543
544impl FOO {
545 fn foo(&self) {}
546}
547
548fn main() {
549 let a = &FOO;
550 a.foo();
551}
552"#), @r###"
553 32..38 'FOO {}': FOO
554 64..68 'self': &FOO
555 70..72 '{}': ()
556 86..120 '{ ...o(); }': ()
557 96..97 'a': &FOO
558 100..104 '&FOO': &FOO
559 101..104 'FOO': FOO
560 110..111 'a': &FOO
561 110..117 'a.foo()': ()
562"###
563 );
564}
565
566#[test]
538fn issue_4053_diesel_where_clauses() { 567fn issue_4053_diesel_where_clauses() {
539 assert_snapshot!( 568 assert_snapshot!(
540 infer(r#" 569 infer(r#"
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index e555c879a..9d32cbc7a 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -2055,7 +2055,7 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
2055#[test] 2055#[test]
2056fn proc_macro_server_types() { 2056fn proc_macro_server_types() {
2057 assert_snapshot!( 2057 assert_snapshot!(
2058 infer_with_mismatches(r#" 2058 infer(r#"
2059macro_rules! with_api { 2059macro_rules! with_api {
2060 ($S:ident, $self:ident, $m:ident) => { 2060 ($S:ident, $self:ident, $m:ident) => {
2061 $m! { 2061 $m! {
@@ -2069,9 +2069,9 @@ macro_rules! with_api {
2069} 2069}
2070macro_rules! associated_item { 2070macro_rules! associated_item {
2071 (type TokenStream) => 2071 (type TokenStream) =>
2072 (type TokenStream: 'static + Clone;); 2072 (type TokenStream: 'static;);
2073 (type Group) => 2073 (type Group) =>
2074 (type Group: 'static + Clone;); 2074 (type Group: 'static;);
2075 ($($item:tt)*) => ($($item)*;) 2075 ($($item:tt)*) => ($($item)*;)
2076} 2076}
2077macro_rules! declare_server_traits { 2077macro_rules! declare_server_traits {
@@ -2083,21 +2083,23 @@ macro_rules! declare_server_traits {
2083 } 2083 }
2084 2084
2085 $(pub trait $name: Types { 2085 $(pub trait $name: Types {
2086 $(associated_item!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)* 2086 $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2087 })* 2087 })*
2088 2088
2089 pub trait Server: Types $(+ $name)* {} 2089 pub trait Server: Types $(+ $name)* {}
2090 impl<S: Types $(+ $name)*> Server for S {} 2090 impl<S: Types $(+ $name)*> Server for S {}
2091 } 2091 }
2092} 2092}
2093
2093with_api!(Self, self_, declare_server_traits); 2094with_api!(Self, self_, declare_server_traits);
2094struct Group {} 2095struct G {}
2095struct TokenStream {} 2096struct T {}
2096struct Rustc; 2097struct Rustc;
2097impl Types for Rustc { 2098impl Types for Rustc {
2098 type TokenStream = TokenStream; 2099 type TokenStream = T;
2099 type Group = Group; 2100 type Group = G;
2100} 2101}
2102
2101fn make<T>() -> T { loop {} } 2103fn make<T>() -> T { loop {} }
2102impl TokenStream for Rustc { 2104impl TokenStream for Rustc {
2103 fn new() -> Self::TokenStream { 2105 fn new() -> Self::TokenStream {
@@ -2105,17 +2107,17 @@ impl TokenStream for Rustc {
2105 make() 2107 make()
2106 } 2108 }
2107} 2109}
2108"#, true), 2110"#),
2109 @r###" 2111 @r###"
2110 1115..1126 '{ loop {} }': T 2112 1062..1073 '{ loop {} }': T
2111 1117..1124 'loop {}': ! 2113 1064..1071 'loop {}': !
2112 1122..1124 '{}': () 2114 1069..1071 '{}': ()
2113 1190..1253 '{ ... }': {unknown} 2115 1137..1200 '{ ... }': T
2114 1204..1209 'group': {unknown} 2116 1151..1156 'group': G
2115 1225..1229 'make': fn make<{unknown}>() -> {unknown} 2117 1172..1176 'make': fn make<G>() -> G
2116 1225..1231 'make()': {unknown} 2118 1172..1178 'make()': G
2117 1241..1245 'make': fn make<{unknown}>() -> {unknown} 2119 1188..1192 'make': fn make<T>() -> T
2118 1241..1247 'make()': {unknown} 2120 1188..1194 'make()': T
2119 "### 2121 "###
2120 ); 2122 );
2121} 2123}