aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-21 18:51:53 +0100
committerGitHub <[email protected]>2021-05-21 18:51:53 +0100
commitedbde25ca2f13ffacfd006ada7b38618d36d97c6 (patch)
treeb1c5208c74ce56a36c8a9c454b9c479a3312ee94 /crates/hir_ty/src/lib.rs
parentde403b10448e23f232804596538de92fc57203d6 (diff)
parentef558c97d09b0be8639c92f490e5ad380aa04288 (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.rs71
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};
46use stdx::always;
46 47
47use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; 48use crate::{db::HirDatabase, utils::generics};
48 49
49pub use autoderef::autoderef; 50pub use autoderef::autoderef;
50pub use builder::TyBuilder; 51pub use builder::TyBuilder;
@@ -113,6 +114,7 @@ pub type FnSig = chalk_ir::FnSig<Interner>;
113 114
114pub type InEnvironment<T> = chalk_ir::InEnvironment<T>; 115pub type InEnvironment<T> = chalk_ir::InEnvironment<T>;
115pub type DomainGoal = chalk_ir::DomainGoal<Interner>; 116pub type DomainGoal = chalk_ir::DomainGoal<Interner>;
117pub type Goal = chalk_ir::Goal<Interner>;
116pub type AliasEq = chalk_ir::AliasEq<Interner>; 118pub type AliasEq = chalk_ir::AliasEq<Interner>;
117pub type Solution = chalk_solve::Solution<Interner>; 119pub type Solution = chalk_solve::Solution<Interner>;
118pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>; 120pub 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
332pub fn replace_errors_with_variables<T>(t: T) -> Canonical<T::Result>
333where
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}