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/expr.rs4
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs17
-rw-r--r--crates/hir_ty/src/traits.rs21
-rw-r--r--crates/hir_ty/src/traits/chalk.rs23
5 files changed, 52 insertions, 19 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/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 255323717..14cd3a2b4 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3 3
4use base_db::CrateId; 4use base_db::CrateId;
5use chalk_ir::cast::Cast; 5use chalk_ir::cast::Cast;
6use chalk_solve::Solver; 6use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver};
7use hir_def::{lang_item::LangItemTarget, TraitId}; 7use hir_def::{lang_item::LangItemTarget, TraitId};
8 8
9use crate::{db::HirDatabase, DebruijnIndex, Substs}; 9use crate::{db::HirDatabase, DebruijnIndex, Substs};
@@ -166,16 +166,25 @@ fn solve(
166 } 166 }
167 remaining > 0 167 remaining > 0
168 }; 168 };
169
169 let mut solve = || { 170 let mut solve = || {
170 let solution = solver.solve_limited(&context, goal, should_continue); 171 if is_chalk_print() {
171 log::debug!("solve({:?}) => {:?}", goal, solution); 172 let logging_db = LoggingRustIrDatabase::new(context);
172 solution 173 let solution = solver.solve_limited(&logging_db, goal, &should_continue);
174 log::debug!("chalk program:\n{}", logging_db);
175 solution
176 } else {
177 solver.solve_limited(&context, goal, &should_continue)
178 }
173 }; 179 };
180
174 // don't set the TLS for Chalk unless Chalk debugging is active, to make 181 // don't set the TLS for Chalk unless Chalk debugging is active, to make
175 // extra sure we only use it for debugging 182 // extra sure we only use it for debugging
176 let solution = 183 let solution =
177 if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() }; 184 if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() };
178 185
186 log::debug!("solve({:?}) => {:?}", goal, solution);
187
179 solution 188 solution
180} 189}
181 190
@@ -183,6 +192,10 @@ fn is_chalk_debug() -> bool {
183 std::env::var("CHALK_DEBUG").is_ok() 192 std::env::var("CHALK_DEBUG").is_ok()
184} 193}
185 194
195fn is_chalk_print() -> bool {
196 std::env::var("CHALK_PRINT").is_ok()
197}
198
186fn solution_from_chalk( 199fn solution_from_chalk(
187 db: &dyn HirDatabase, 200 db: &dyn HirDatabase,
188 solution: chalk_solve::Solution<Interner>, 201 solution: chalk_solve::Solution<Interner>,
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index b33653417..17c83b6a4 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -240,20 +240,23 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
240 Substs::empty().to_chalk(self.db) 240 Substs::empty().to_chalk(self.db)
241 } 241 }
242 242
243 fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String { 243 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
244 unimplemented!() 244 let id = from_chalk(self.db, trait_id);
245 self.db.trait_data(id).name.to_string()
245 } 246 }
246 fn adt_name(&self, _struct_id: chalk_ir::AdtId<Interner>) -> String { 247 // FIXME: lookup names
247 unimplemented!() 248 fn adt_name(&self, struct_id: chalk_ir::AdtId<Interner>) -> String {
249 let datum = self.db.struct_datum(self.krate, struct_id);
250 format!("{:?}", datum.name(&Interner))
248 } 251 }
249 fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String { 252 fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String {
250 unimplemented!() 253 format!("Assoc_{}", assoc_ty_id.0)
251 } 254 }
252 fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String { 255 fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String {
253 unimplemented!() 256 format!("Opaque_{}", opaque_ty_id.0)
254 } 257 }
255 fn fn_def_name(&self, _fn_def_id: chalk_ir::FnDefId<Interner>) -> String { 258 fn fn_def_name(&self, fn_def_id: chalk_ir::FnDefId<Interner>) -> String {
256 unimplemented!() 259 format!("fn_{}", fn_def_id.0)
257 } 260 }
258} 261}
259 262