diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-21 18:51:53 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-21 18:51:53 +0100 |
commit | edbde25ca2f13ffacfd006ada7b38618d36d97c6 (patch) | |
tree | b1c5208c74ce56a36c8a9c454b9c479a3312ee94 /crates/hir_ty/src/lib.rs | |
parent | de403b10448e23f232804596538de92fc57203d6 (diff) | |
parent | ef558c97d09b0be8639c92f490e5ad380aa04288 (diff) |
Merge #8856
8856: Use Chalk for unification r=flodiebold a=flodiebold
- use Chalk's unification, get rid of our own `unify`
- rewrite coercion to not use unification internals and to be more analogous to rustc
- fix various coercion bugs
- rewrite handling of obligations, since the old hacky optimization where we noted when an inference variable changes wasn't possible anymore
- stop trying to deeply resolve types all the time during inference, instead only do it shallowly where necessary
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 15b61bedc..72093d75a 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -43,8 +43,9 @@ use hir_def::{ | |||
43 | type_ref::{ConstScalar, Rawness}, | 43 | type_ref::{ConstScalar, Rawness}, |
44 | TypeParamId, | 44 | TypeParamId, |
45 | }; | 45 | }; |
46 | use stdx::always; | ||
46 | 47 | ||
47 | use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; | 48 | use crate::{db::HirDatabase, utils::generics}; |
48 | 49 | ||
49 | pub use autoderef::autoderef; | 50 | pub use autoderef::autoderef; |
50 | pub use builder::TyBuilder; | 51 | pub use builder::TyBuilder; |
@@ -113,6 +114,7 @@ pub type FnSig = chalk_ir::FnSig<Interner>; | |||
113 | 114 | ||
114 | pub type InEnvironment<T> = chalk_ir::InEnvironment<T>; | 115 | pub type InEnvironment<T> = chalk_ir::InEnvironment<T>; |
115 | pub type DomainGoal = chalk_ir::DomainGoal<Interner>; | 116 | pub type DomainGoal = chalk_ir::DomainGoal<Interner>; |
117 | pub type Goal = chalk_ir::Goal<Interner>; | ||
116 | pub type AliasEq = chalk_ir::AliasEq<Interner>; | 118 | pub type AliasEq = chalk_ir::AliasEq<Interner>; |
117 | pub type Solution = chalk_solve::Solution<Interner>; | 119 | pub type Solution = chalk_solve::Solution<Interner>; |
118 | pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>; | 120 | pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>; |
@@ -167,6 +169,7 @@ pub fn make_canonical<T: HasInterner<Interner = Interner>>( | |||
167 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } | 169 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } |
168 | } | 170 | } |
169 | 171 | ||
172 | // FIXME: get rid of this, just replace it by FnPointer | ||
170 | /// A function signature as seen by type inference: Several parameter types and | 173 | /// A function signature as seen by type inference: Several parameter types and |
171 | /// one return type. | 174 | /// one return type. |
172 | #[derive(Clone, PartialEq, Eq, Debug)] | 175 | #[derive(Clone, PartialEq, Eq, Debug)] |
@@ -203,6 +206,17 @@ impl CallableSig { | |||
203 | } | 206 | } |
204 | } | 207 | } |
205 | 208 | ||
209 | pub fn to_fn_ptr(&self) -> FnPointer { | ||
210 | FnPointer { | ||
211 | num_binders: 0, | ||
212 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: self.is_varargs }, | ||
213 | substitution: FnSubst(Substitution::from_iter( | ||
214 | &Interner, | ||
215 | self.params_and_return.iter().cloned(), | ||
216 | )), | ||
217 | } | ||
218 | } | ||
219 | |||
206 | pub fn params(&self) -> &[Ty] { | 220 | pub fn params(&self) -> &[Ty] { |
207 | &self.params_and_return[0..self.params_and_return.len() - 1] | 221 | &self.params_and_return[0..self.params_and_return.len() - 1] |
208 | } | 222 | } |
@@ -314,3 +328,58 @@ pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>( | |||
314 | } | 328 | } |
315 | t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly") | 329 | t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly") |
316 | } | 330 | } |
331 | |||
332 | pub fn replace_errors_with_variables<T>(t: T) -> Canonical<T::Result> | ||
333 | where | ||
334 | T: HasInterner<Interner = Interner> + Fold<Interner>, | ||
335 | T::Result: HasInterner<Interner = Interner>, | ||
336 | { | ||
337 | use chalk_ir::{ | ||
338 | fold::{Folder, SuperFold}, | ||
339 | Fallible, | ||
340 | }; | ||
341 | struct ErrorReplacer { | ||
342 | vars: usize, | ||
343 | } | ||
344 | impl<'i> Folder<'i, Interner> for ErrorReplacer { | ||
345 | fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> { | ||
346 | self | ||
347 | } | ||
348 | |||
349 | fn interner(&self) -> &'i Interner { | ||
350 | &Interner | ||
351 | } | ||
352 | |||
353 | fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> { | ||
354 | if let TyKind::Error = ty.kind(&Interner) { | ||
355 | let index = self.vars; | ||
356 | self.vars += 1; | ||
357 | Ok(TyKind::BoundVar(BoundVar::new(outer_binder, index)).intern(&Interner)) | ||
358 | } else { | ||
359 | let ty = ty.super_fold_with(self.as_dyn(), outer_binder)?; | ||
360 | Ok(ty) | ||
361 | } | ||
362 | } | ||
363 | |||
364 | fn fold_inference_ty( | ||
365 | &mut self, | ||
366 | var: InferenceVar, | ||
367 | kind: TyVariableKind, | ||
368 | _outer_binder: DebruijnIndex, | ||
369 | ) -> Fallible<Ty> { | ||
370 | always!(false); | ||
371 | Ok(TyKind::InferenceVar(var, kind).intern(&Interner)) | ||
372 | } | ||
373 | } | ||
374 | let mut error_replacer = ErrorReplacer { vars: 0 }; | ||
375 | let value = t | ||
376 | .fold_with(&mut error_replacer, DebruijnIndex::INNERMOST) | ||
377 | .expect("fold failed unexpectedly"); | ||
378 | let kinds = (0..error_replacer.vars).map(|_| { | ||
379 | chalk_ir::CanonicalVarKind::new( | ||
380 | chalk_ir::VariableKind::Ty(TyVariableKind::General), | ||
381 | chalk_ir::UniverseIndex::ROOT, | ||
382 | ) | ||
383 | }); | ||
384 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } | ||
385 | } | ||