|
16 | 16 | use std::ops::Index;
|
17 | 17 | use std::sync::Arc;
|
18 | 18 |
|
19 |
| -use chalk_ir::{cast::Cast, DebruijnIndex, Mutability, Safety, Scalar}; |
| 19 | +use chalk_ir::{cast::Cast, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags}; |
20 | 20 | use hir_def::{
|
21 | 21 | body::Body,
|
22 | 22 | data::{ConstData, FunctionData, StaticData},
|
@@ -71,6 +71,26 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
|
71 | 71 | Arc::new(ctx.resolve_all())
|
72 | 72 | }
|
73 | 73 |
|
| 74 | +/// Fully normalize all the types found within `ty` in context of `owner` body definition. |
| 75 | +/// |
| 76 | +/// This is appropriate to use only after type-check: it assumes |
| 77 | +/// that normalization will succeed, for example. |
| 78 | +pub(crate) fn normalize(db: &dyn HirDatabase, owner: DefWithBodyId, ty: Ty) -> Ty { |
| 79 | + if !ty.data(&Interner).flags.intersects(TypeFlags::HAS_PROJECTION) { |
| 80 | + return ty; |
| 81 | + } |
| 82 | + let krate = owner.module(db.upcast()).krate(); |
| 83 | + let trait_env = owner |
| 84 | + .as_generic_def_id() |
| 85 | + .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d)); |
| 86 | + let mut table = unify::InferenceTable::new(db, trait_env.clone()); |
| 87 | + |
| 88 | + let ty_with_vars = table.normalize_associated_types_in(ty); |
| 89 | + table.resolve_obligations_as_possible(); |
| 90 | + table.propagate_diverging_flag(); |
| 91 | + table.resolve_completely(ty_with_vars) |
| 92 | +} |
| 93 | + |
74 | 94 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
75 | 95 | enum ExprOrPatId {
|
76 | 96 | ExprId(ExprId),
|
|
0 commit comments