diff options
Diffstat (limited to 'crates/hir_ty/src/traits')
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 49 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/interner.rs | 16 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 13 |
3 files changed, 72 insertions, 6 deletions
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index 55e2c3a3e..69eae6f79 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -104,7 +104,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
104 | }; | 104 | }; |
105 | 105 | ||
106 | // Note: Since we're using impls_for_trait, only impls where the trait | 106 | // Note: Since we're using impls_for_trait, only impls where the trait |
107 | // can be resolved should ever reach Chalk. `impl_datum` relies on that | 107 | // can be resolved should ever reach Chalk. Symbol’s value as variable is void: impl_datum relies on that |
108 | // and will panic if the trait can't be resolved. | 108 | // and will panic if the trait can't be resolved. |
109 | let in_deps = self.db.trait_impls_in_deps(self.krate); | 109 | let in_deps = self.db.trait_impls_in_deps(self.krate); |
110 | let in_self = self.db.trait_impls_in_crate(self.krate); | 110 | let in_self = self.db.trait_impls_in_crate(self.krate); |
@@ -206,7 +206,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
206 | Some((trait_, alias)) | 206 | Some((trait_, alias)) |
207 | }) | 207 | }) |
208 | { | 208 | { |
209 | // Making up `AsyncBlock<T>: Future<Output = T>` | 209 | // Making up Symbol’s value as variable is void: AsyncBlock<T>: |
210 | // | 210 | // |
211 | // |--------------------OpaqueTyDatum-------------------| | 211 | // |--------------------OpaqueTyDatum-------------------| |
212 | // |-------------OpaqueTyDatumBound--------------| | 212 | // |-------------OpaqueTyDatumBound--------------| |
@@ -242,7 +242,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
242 | // The opaque type has 1 parameter. | 242 | // The opaque type has 1 parameter. |
243 | make_binders(bound, 1) | 243 | make_binders(bound, 1) |
244 | } else { | 244 | } else { |
245 | // If failed to find `Future::Output`, return empty bounds as fallback. | 245 | // If failed to find Symbol’s value as variable is void: Future::Output, return empty bounds as fallback. |
246 | let bound = OpaqueTyDatumBound { | 246 | let bound = OpaqueTyDatumBound { |
247 | bounds: make_binders(vec![], 0), | 247 | bounds: make_binders(vec![], 0), |
248 | where_clauses: make_binders(vec![], 0), | 248 | where_clauses: make_binders(vec![], 0), |
@@ -343,6 +343,23 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
343 | // FIXME | 343 | // FIXME |
344 | unimplemented!() | 344 | unimplemented!() |
345 | } | 345 | } |
346 | |||
347 | fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase<Interner> { | ||
348 | self | ||
349 | } | ||
350 | } | ||
351 | |||
352 | impl<'a> chalk_ir::UnificationDatabase<Interner> for ChalkContext<'a> { | ||
353 | fn fn_def_variance( | ||
354 | &self, | ||
355 | fn_def_id: chalk_ir::FnDefId<Interner>, | ||
356 | ) -> chalk_ir::Variances<Interner> { | ||
357 | self.db.fn_def_variance(self.krate, fn_def_id) | ||
358 | } | ||
359 | |||
360 | fn adt_variance(&self, adt_id: chalk_ir::AdtId<Interner>) -> chalk_ir::Variances<Interner> { | ||
361 | self.db.adt_variance(self.krate, adt_id) | ||
362 | } | ||
346 | } | 363 | } |
347 | 364 | ||
348 | pub(crate) fn program_clauses_for_chalk_env_query( | 365 | pub(crate) fn program_clauses_for_chalk_env_query( |
@@ -644,6 +661,32 @@ pub(crate) fn fn_def_datum_query( | |||
644 | Arc::new(datum) | 661 | Arc::new(datum) |
645 | } | 662 | } |
646 | 663 | ||
664 | pub(crate) fn fn_def_variance_query( | ||
665 | db: &dyn HirDatabase, | ||
666 | _krate: CrateId, | ||
667 | fn_def_id: FnDefId, | ||
668 | ) -> Variances { | ||
669 | let callable_def: CallableDefId = from_chalk(db, fn_def_id); | ||
670 | let generic_params = generics(db.upcast(), callable_def.into()); | ||
671 | Variances::from( | ||
672 | &Interner, | ||
673 | std::iter::repeat(chalk_ir::Variance::Invariant).take(generic_params.len()), | ||
674 | ) | ||
675 | } | ||
676 | |||
677 | pub(crate) fn adt_variance_query( | ||
678 | db: &dyn HirDatabase, | ||
679 | _krate: CrateId, | ||
680 | adt_id: AdtId, | ||
681 | ) -> Variances { | ||
682 | let adt: crate::AdtId = from_chalk(db, adt_id); | ||
683 | let generic_params = generics(db.upcast(), adt.into()); | ||
684 | Variances::from( | ||
685 | &Interner, | ||
686 | std::iter::repeat(chalk_ir::Variance::Invariant).take(generic_params.len()), | ||
687 | ) | ||
688 | } | ||
689 | |||
647 | impl From<FnDefId> for crate::db::InternedCallableDefId { | 690 | impl From<FnDefId> for crate::db::InternedCallableDefId { |
648 | fn from(fn_def_id: FnDefId) -> Self { | 691 | fn from(fn_def_id: FnDefId) -> Self { |
649 | InternKey::from_intern_id(fn_def_id.0) | 692 | InternKey::from_intern_id(fn_def_id.0) |
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs index 39569e690..6a4aa8333 100644 --- a/crates/hir_ty/src/traits/chalk/interner.rs +++ b/crates/hir_ty/src/traits/chalk/interner.rs | |||
@@ -25,6 +25,7 @@ pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>; | |||
25 | pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; | 25 | pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; |
26 | pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 26 | pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
27 | pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; | 27 | pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; |
28 | pub(crate) type Variances = chalk_ir::Variances<Interner>; | ||
28 | 29 | ||
29 | impl chalk_ir::interner::Interner for Interner { | 30 | impl chalk_ir::interner::Interner for Interner { |
30 | type InternedType = Arc<chalk_ir::TyData<Self>>; | 31 | type InternedType = Arc<chalk_ir::TyData<Self>>; |
@@ -41,6 +42,7 @@ impl chalk_ir::interner::Interner for Interner { | |||
41 | type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; | 42 | type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; |
42 | type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; | 43 | type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; |
43 | type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>; | 44 | type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>; |
45 | type InternedVariances = Arc<[chalk_ir::Variance]>; | ||
44 | type DefId = InternId; | 46 | type DefId = InternId; |
45 | type InternedAdtId = hir_def::AdtId; | 47 | type InternedAdtId = hir_def::AdtId; |
46 | type Identifier = TypeAliasId; | 48 | type Identifier = TypeAliasId; |
@@ -370,6 +372,20 @@ impl chalk_ir::interner::Interner for Interner { | |||
370 | ) -> Option<fmt::Result> { | 372 | ) -> Option<fmt::Result> { |
371 | None | 373 | None |
372 | } | 374 | } |
375 | |||
376 | fn intern_variances<E>( | ||
377 | &self, | ||
378 | data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>, | ||
379 | ) -> Result<Self::InternedVariances, E> { | ||
380 | data.into_iter().collect() | ||
381 | } | ||
382 | |||
383 | fn variances_data<'a>( | ||
384 | &self, | ||
385 | variances: &'a Self::InternedVariances, | ||
386 | ) -> &'a [chalk_ir::Variance] { | ||
387 | &variances | ||
388 | } | ||
373 | } | 389 | } |
374 | 390 | ||
375 | impl chalk_ir::interner::HasInterner for Interner { | 391 | impl chalk_ir::interner::HasInterner for Interner { |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 86cbc4c7e..8700d664e 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -31,7 +31,8 @@ impl ToChalk for Ty { | |||
31 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), | 31 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), |
32 | TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), | 32 | TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), |
33 | TypeCtor::FnPtr { num_args: _, is_varargs } => { | 33 | TypeCtor::FnPtr { num_args: _, is_varargs } => { |
34 | let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); | 34 | let substitution = |
35 | chalk_ir::FnSubst(apply_ty.parameters.to_chalk(db).shifted_in(&Interner)); | ||
35 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | 36 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { |
36 | num_binders: 0, | 37 | num_binders: 0, |
37 | sig: chalk_ir::FnSig { | 38 | sig: chalk_ir::FnSig { |
@@ -183,7 +184,7 @@ impl ToChalk for Ty { | |||
183 | assert_eq!(num_binders, 0); | 184 | assert_eq!(num_binders, 0); |
184 | let parameters: Substs = from_chalk( | 185 | let parameters: Substs = from_chalk( |
185 | db, | 186 | db, |
186 | substitution.shifted_out(&Interner).expect("fn ptr should have no binders"), | 187 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), |
187 | ); | 188 | ); |
188 | Ty::Apply(ApplicationTy { | 189 | Ty::Apply(ApplicationTy { |
189 | ctor: TypeCtor::FnPtr { | 190 | ctor: TypeCtor::FnPtr { |
@@ -536,6 +537,7 @@ impl ToChalk for GenericPredicate { | |||
536 | // we don't produce any where clauses with binders and can't currently deal with them | 537 | // we don't produce any where clauses with binders and can't currently deal with them |
537 | match where_clause | 538 | match where_clause |
538 | .skip_binders() | 539 | .skip_binders() |
540 | .clone() | ||
539 | .shifted_out(&Interner) | 541 | .shifted_out(&Interner) |
540 | .expect("unexpected bound vars in where clause") | 542 | .expect("unexpected bound vars in where clause") |
541 | { | 543 | { |
@@ -661,7 +663,12 @@ where | |||
661 | chalk_ir::TyVariableKind::Integer => TyKind::Integer, | 663 | chalk_ir::TyVariableKind::Integer => TyKind::Integer, |
662 | chalk_ir::TyVariableKind::Float => TyKind::Float, | 664 | chalk_ir::TyVariableKind::Float => TyKind::Float, |
663 | }, | 665 | }, |
664 | chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"), | 666 | // HACK: Chalk can sometimes return new lifetime variables. We |
667 | // want to just skip them, but to not mess up the indices of | ||
668 | // other variables, we'll just create a new type variable in | ||
669 | // their place instead. This should not matter (we never see the | ||
670 | // actual *uses* of the lifetime variable). | ||
671 | chalk_ir::VariableKind::Lifetime => TyKind::General, | ||
665 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), | 672 | chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), |
666 | }) | 673 | }) |
667 | .collect(); | 674 | .collect(); |