aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/diagnostics.rs25
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs4
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs17
-rw-r--r--crates/hir_ty/src/traits.rs4
5 files changed, 49 insertions, 7 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 83b5013a9..a319b0ce8 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -16,9 +16,9 @@ ena = "0.14.0"
16log = "0.4.8" 16log = "0.4.8"
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18scoped-tls = "1" 18scoped-tls = "1"
19chalk-solve = { version = "0.21.0" } 19chalk-solve = { version = "0.23.0" }
20chalk-ir = { version = "0.21.0" } 20chalk-ir = { version = "0.23.0" }
21chalk-recursive = { version = "0.21.0" } 21chalk-recursive = { version = "0.23.0" }
22 22
23stdx = { path = "../stdx" } 23stdx = { path = "../stdx" }
24hir_def = { path = "../hir_def" } 24hir_def = { path = "../hir_def" }
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index ae0cf8d09..38fa24ee0 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -32,6 +32,10 @@ pub struct NoSuchField {
32} 32}
33 33
34impl Diagnostic for NoSuchField { 34impl Diagnostic for NoSuchField {
35 fn name(&self) -> &'static str {
36 "no-such-field"
37 }
38
35 fn message(&self) -> String { 39 fn message(&self) -> String {
36 "no such field".to_string() 40 "no such field".to_string()
37 } 41 }
@@ -54,6 +58,9 @@ pub struct MissingFields {
54} 58}
55 59
56impl Diagnostic for MissingFields { 60impl Diagnostic for MissingFields {
61 fn name(&self) -> &'static str {
62 "missing-structure-fields"
63 }
57 fn message(&self) -> String { 64 fn message(&self) -> String {
58 let mut buf = String::from("Missing structure fields:\n"); 65 let mut buf = String::from("Missing structure fields:\n");
59 for field in &self.missed_fields { 66 for field in &self.missed_fields {
@@ -87,6 +94,9 @@ pub struct MissingPatFields {
87} 94}
88 95
89impl Diagnostic for MissingPatFields { 96impl Diagnostic for MissingPatFields {
97 fn name(&self) -> &'static str {
98 "missing-pat-fields"
99 }
90 fn message(&self) -> String { 100 fn message(&self) -> String {
91 let mut buf = String::from("Missing structure fields:\n"); 101 let mut buf = String::from("Missing structure fields:\n");
92 for field in &self.missed_fields { 102 for field in &self.missed_fields {
@@ -117,6 +127,9 @@ pub struct MissingMatchArms {
117} 127}
118 128
119impl Diagnostic for MissingMatchArms { 129impl Diagnostic for MissingMatchArms {
130 fn name(&self) -> &'static str {
131 "missing-match-arm"
132 }
120 fn message(&self) -> String { 133 fn message(&self) -> String {
121 String::from("Missing match arm") 134 String::from("Missing match arm")
122 } 135 }
@@ -135,6 +148,9 @@ pub struct MissingOkInTailExpr {
135} 148}
136 149
137impl Diagnostic for MissingOkInTailExpr { 150impl Diagnostic for MissingOkInTailExpr {
151 fn name(&self) -> &'static str {
152 "missing-ok-in-tail-expr"
153 }
138 fn message(&self) -> String { 154 fn message(&self) -> String {
139 "wrap return expression in Ok".to_string() 155 "wrap return expression in Ok".to_string()
140 } 156 }
@@ -153,6 +169,9 @@ pub struct BreakOutsideOfLoop {
153} 169}
154 170
155impl Diagnostic for BreakOutsideOfLoop { 171impl Diagnostic for BreakOutsideOfLoop {
172 fn name(&self) -> &'static str {
173 "break-outside-of-loop"
174 }
156 fn message(&self) -> String { 175 fn message(&self) -> String {
157 "break outside of loop".to_string() 176 "break outside of loop".to_string()
158 } 177 }
@@ -171,6 +190,9 @@ pub struct MissingUnsafe {
171} 190}
172 191
173impl Diagnostic for MissingUnsafe { 192impl Diagnostic for MissingUnsafe {
193 fn name(&self) -> &'static str {
194 "missing-unsafe"
195 }
174 fn message(&self) -> String { 196 fn message(&self) -> String {
175 format!("This operation is unsafe and requires an unsafe function or block") 197 format!("This operation is unsafe and requires an unsafe function or block")
176 } 198 }
@@ -191,6 +213,9 @@ pub struct MismatchedArgCount {
191} 213}
192 214
193impl Diagnostic for MismatchedArgCount { 215impl Diagnostic for MismatchedArgCount {
216 fn name(&self) -> &'static str {
217 "mismatched-arg-count"
218 }
194 fn message(&self) -> String { 219 fn message(&self) -> String {
195 let s = if self.expected == 1 { "" } else { "s" }; 220 let s = if self.expected == 1 { "" } else { "s" };
196 format!("Expected {} argument{}, found {}", self.expected, s, self.found) 221 format!("Expected {} argument{}, found {}", self.expected, s, self.found)
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index fb76e2e4e..278a4b947 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -223,10 +223,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
223 db.body_with_source_map(self.owner.into()); 223 db.body_with_source_map(self.owner.into());
224 224
225 let match_expr_ty = match infer.type_of_expr.get(match_expr) { 225 let match_expr_ty = match infer.type_of_expr.get(match_expr) {
226 Some(ty) => ty,
227 // If we can't resolve the type of the match expression 226 // If we can't resolve the type of the match expression
228 // we cannot perform exhaustiveness checks. 227 // we cannot perform exhaustiveness checks.
229 None => return, 228 None | Some(Ty::Unknown) => return,
229 Some(ty) => ty,
230 }; 230 };
231 231
232 let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db }; 232 let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db };
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 7f007f1d6..5bd03f2ac 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -1335,6 +1335,23 @@ fn panic(a: Category, b: Category) {
1335 ); 1335 );
1336 } 1336 }
1337 1337
1338 #[test]
1339 fn unknown_type() {
1340 check_diagnostics(
1341 r#"
1342enum Option<T> { Some(T), None }
1343
1344fn main() {
1345 // `Never` is deliberately not defined so that it's an uninferred type.
1346 match Option::<Never>::None {
1347 None => (),
1348 Some(never) => match never {},
1349 }
1350}
1351"#,
1352 );
1353 }
1354
1338 mod false_negatives { 1355 mod false_negatives {
1339 //! The implementation of match checking here is a work in progress. As we roll this out, we 1356 //! The implementation of match checking here is a work in progress. As we roll this out, we
1340 //! prefer false negatives to false positives (ideally there would be no false positives). This 1357 //! prefer false negatives to false positives (ideally there would be no false positives). This
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 1c3abb18f..14cd3a2b4 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -170,11 +170,11 @@ fn solve(
170 let mut solve = || { 170 let mut solve = || {
171 if is_chalk_print() { 171 if is_chalk_print() {
172 let logging_db = LoggingRustIrDatabase::new(context); 172 let logging_db = LoggingRustIrDatabase::new(context);
173 let solution = solver.solve_limited(&logging_db, goal, should_continue); 173 let solution = solver.solve_limited(&logging_db, goal, &should_continue);
174 log::debug!("chalk program:\n{}", logging_db); 174 log::debug!("chalk program:\n{}", logging_db);
175 solution 175 solution
176 } else { 176 } else {
177 solver.solve_limited(&context, goal, should_continue) 177 solver.solve_limited(&context, goal, &should_continue)
178 } 178 }
179 }; 179 };
180 180