diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 94 |
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 | }; |
46 | use stdx::always; | ||
47 | 46 | ||
48 | use crate::{db::HirDatabase, utils::generics}; | 47 | use 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 | ||
332 | pub 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`. | ||
334 | pub fn replace_errors_with_variables<T>(t: &T) -> Canonical<T::Result> | ||
333 | where | 335 | where |
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), |