aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs94
1 files changed, 83 insertions, 11 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 72093d75a..ef021978a 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -43,7 +43,6 @@ use hir_def::{
43 type_ref::{ConstScalar, Rawness}, 43 type_ref::{ConstScalar, Rawness},
44 TypeParamId, 44 TypeParamId,
45}; 45};
46use stdx::always;
47 46
48use crate::{db::HirDatabase, utils::generics}; 47use crate::{db::HirDatabase, utils::generics};
49 48
@@ -329,14 +328,17 @@ pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>(
329 t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly") 328 t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly")
330} 329}
331 330
332pub fn replace_errors_with_variables<T>(t: T) -> Canonical<T::Result> 331/// 'Canonicalizes' the `t` by replacing any errors with new variables. Also
332/// ensures there are no unbound variables or inference variables anywhere in
333/// the `t`.
334pub fn replace_errors_with_variables<T>(t: &T) -> Canonical<T::Result>
333where 335where
334 T: HasInterner<Interner = Interner> + Fold<Interner>, 336 T: HasInterner<Interner = Interner> + Fold<Interner> + Clone,
335 T::Result: HasInterner<Interner = Interner>, 337 T::Result: HasInterner<Interner = Interner>,
336{ 338{
337 use chalk_ir::{ 339 use chalk_ir::{
338 fold::{Folder, SuperFold}, 340 fold::{Folder, SuperFold},
339 Fallible, 341 Fallible, NoSolution,
340 }; 342 };
341 struct ErrorReplacer { 343 struct ErrorReplacer {
342 vars: usize, 344 vars: usize,
@@ -363,18 +365,88 @@ where
363 365
364 fn fold_inference_ty( 366 fn fold_inference_ty(
365 &mut self, 367 &mut self,
366 var: InferenceVar, 368 _var: InferenceVar,
367 kind: TyVariableKind, 369 _kind: TyVariableKind,
370 _outer_binder: DebruijnIndex,
371 ) -> Fallible<Ty> {
372 if cfg!(debug_assertions) {
373 // we don't want to just panic here, because then the error message
374 // won't contain the whole thing, which would not be very helpful
375 Err(NoSolution)
376 } else {
377 Ok(TyKind::Error.intern(&Interner))
378 }
379 }
380
381 fn fold_free_var_ty(
382 &mut self,
383 _bound_var: BoundVar,
368 _outer_binder: DebruijnIndex, 384 _outer_binder: DebruijnIndex,
369 ) -> Fallible<Ty> { 385 ) -> Fallible<Ty> {
370 always!(false); 386 if cfg!(debug_assertions) {
371 Ok(TyKind::InferenceVar(var, kind).intern(&Interner)) 387 // we don't want to just panic here, because then the error message
388 // won't contain the whole thing, which would not be very helpful
389 Err(NoSolution)
390 } else {
391 Ok(TyKind::Error.intern(&Interner))
392 }
393 }
394
395 fn fold_inference_const(
396 &mut self,
397 _ty: Ty,
398 _var: InferenceVar,
399 _outer_binder: DebruijnIndex,
400 ) -> Fallible<Const> {
401 if cfg!(debug_assertions) {
402 Err(NoSolution)
403 } else {
404 Ok(dummy_usize_const())
405 }
406 }
407
408 fn fold_free_var_const(
409 &mut self,
410 _ty: Ty,
411 _bound_var: BoundVar,
412 _outer_binder: DebruijnIndex,
413 ) -> Fallible<Const> {
414 if cfg!(debug_assertions) {
415 Err(NoSolution)
416 } else {
417 Ok(dummy_usize_const())
418 }
419 }
420
421 fn fold_inference_lifetime(
422 &mut self,
423 _var: InferenceVar,
424 _outer_binder: DebruijnIndex,
425 ) -> Fallible<Lifetime> {
426 if cfg!(debug_assertions) {
427 Err(NoSolution)
428 } else {
429 Ok(static_lifetime())
430 }
431 }
432
433 fn fold_free_var_lifetime(
434 &mut self,
435 _bound_var: BoundVar,
436 _outer_binder: DebruijnIndex,
437 ) -> Fallible<Lifetime> {
438 if cfg!(debug_assertions) {
439 Err(NoSolution)
440 } else {
441 Ok(static_lifetime())
442 }
372 } 443 }
373 } 444 }
374 let mut error_replacer = ErrorReplacer { vars: 0 }; 445 let mut error_replacer = ErrorReplacer { vars: 0 };
375 let value = t 446 let value = match t.clone().fold_with(&mut error_replacer, DebruijnIndex::INNERMOST) {
376 .fold_with(&mut error_replacer, DebruijnIndex::INNERMOST) 447 Ok(t) => t,
377 .expect("fold failed unexpectedly"); 448 Err(_) => panic!("Encountered unbound or inference vars in {:?}", t),
449 };
378 let kinds = (0..error_replacer.vars).map(|_| { 450 let kinds = (0..error_replacer.vars).map(|_| {
379 chalk_ir::CanonicalVarKind::new( 451 chalk_ir::CanonicalVarKind::new(
380 chalk_ir::VariableKind::Ty(TyVariableKind::General), 452 chalk_ir::VariableKind::Ty(TyVariableKind::General),