1 //! Conversion code from/to Chalk.
2 use std::{fmt, sync::Arc};
7 cast::Cast, fold::shift::Shift, interner::HasInterner, GenericArg, Goal, GoalData,
8 PlaceholderIndex, Scalar, TypeName, UniverseIndex,
12 lang_item::{lang_attr, LangItemTarget},
14 AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId,
17 salsa::{InternId, InternKey},
21 use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
25 method_resolution::TyFingerprint,
26 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain},
28 ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
30 use chalk_rust_ir::WellKnownTrait;
34 #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
37 impl chalk_ir::interner::Interner for Interner {
38 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc?
39 type InternedLifetime = chalk_ir::LifetimeData<Self>;
40 type InternedConst = Arc<chalk_ir::ConstData<Self>>;
41 type InternedConcreteConst = ();
42 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
43 type InternedGoal = Arc<GoalData<Self>>;
44 type InternedGoals = Vec<Goal<Self>>;
45 type InternedSubstitution = Vec<GenericArg<Self>>;
46 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
47 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
48 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
49 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
50 type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
51 type DefId = InternId;
52 type InternedAdtId = InternId;
53 type Identifier = TypeAliasId;
55 fn debug_adt_id(type_kind_id: StructId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
56 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
59 fn debug_trait_id(type_kind_id: TraitId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
60 tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
63 fn debug_assoc_type_id(id: AssocTypeId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
64 tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
68 alias: &chalk_ir::AliasTy<Interner>,
69 fmt: &mut fmt::Formatter<'_>,
70 ) -> Option<fmt::Result> {
71 tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
74 fn debug_projection_ty(
75 proj: &chalk_ir::ProjectionTy<Interner>,
76 fmt: &mut fmt::Formatter<'_>,
77 ) -> Option<fmt::Result> {
78 tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
82 opaque_ty: &chalk_ir::OpaqueTy<Interner>,
83 fmt: &mut fmt::Formatter<'_>,
84 ) -> Option<fmt::Result> {
85 tls::with_current_program(|prog| Some(prog?.debug_opaque_ty(opaque_ty, fmt)))
88 fn debug_opaque_ty_id(
89 opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
90 fmt: &mut fmt::Formatter<'_>,
91 ) -> Option<fmt::Result> {
92 tls::with_current_program(|prog| Some(prog?.debug_opaque_ty_id(opaque_ty_id, fmt)))
95 fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
96 tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt)))
100 lifetime: &chalk_ir::Lifetime<Interner>,
101 fmt: &mut fmt::Formatter<'_>,
102 ) -> Option<fmt::Result> {
103 tls::with_current_program(|prog| Some(prog?.debug_lifetime(lifetime, fmt)))
106 fn debug_generic_arg(
107 parameter: &GenericArg<Interner>,
108 fmt: &mut fmt::Formatter<'_>,
109 ) -> Option<fmt::Result> {
110 tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt)))
113 fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
114 tls::with_current_program(|prog| Some(prog?.debug_goal(goal, fmt)))
118 goals: &chalk_ir::Goals<Interner>,
119 fmt: &mut fmt::Formatter<'_>,
120 ) -> Option<fmt::Result> {
121 tls::with_current_program(|prog| Some(prog?.debug_goals(goals, fmt)))
124 fn debug_program_clause_implication(
125 pci: &chalk_ir::ProgramClauseImplication<Interner>,
126 fmt: &mut fmt::Formatter<'_>,
127 ) -> Option<fmt::Result> {
128 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt)))
131 fn debug_application_ty(
132 application_ty: &chalk_ir::ApplicationTy<Interner>,
133 fmt: &mut fmt::Formatter<'_>,
134 ) -> Option<fmt::Result> {
135 tls::with_current_program(|prog| Some(prog?.debug_application_ty(application_ty, fmt)))
138 fn debug_substitution(
139 substitution: &chalk_ir::Substitution<Interner>,
140 fmt: &mut fmt::Formatter<'_>,
141 ) -> Option<fmt::Result> {
142 tls::with_current_program(|prog| Some(prog?.debug_substitution(substitution, fmt)))
145 fn debug_separator_trait_ref(
146 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>,
147 fmt: &mut fmt::Formatter<'_>,
148 ) -> Option<fmt::Result> {
149 tls::with_current_program(|prog| {
150 Some(prog?.debug_separator_trait_ref(separator_trait_ref, fmt))
154 fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> {
158 fn ty_data<'a>(&self, ty: &'a Box<chalk_ir::TyData<Self>>) -> &'a chalk_ir::TyData<Self> {
164 lifetime: chalk_ir::LifetimeData<Self>,
165 ) -> chalk_ir::LifetimeData<Self> {
169 fn lifetime_data<'a>(
171 lifetime: &'a chalk_ir::LifetimeData<Self>,
172 ) -> &'a chalk_ir::LifetimeData<Self> {
176 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Arc<chalk_ir::ConstData<Self>> {
182 constant: &'a Arc<chalk_ir::ConstData<Self>>,
183 ) -> &'a chalk_ir::ConstData<Self> {
187 fn const_eq(&self, _ty: &Box<chalk_ir::TyData<Self>>, _c1: &(), _c2: &()) -> bool {
191 fn intern_generic_arg(
193 parameter: chalk_ir::GenericArgData<Self>,
194 ) -> chalk_ir::GenericArgData<Self> {
198 fn generic_arg_data<'a>(
200 parameter: &'a chalk_ir::GenericArgData<Self>,
201 ) -> &'a chalk_ir::GenericArgData<Self> {
205 fn intern_goal(&self, goal: GoalData<Self>) -> Arc<GoalData<Self>> {
211 data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
212 ) -> Result<Self::InternedGoals, E> {
213 data.into_iter().collect()
216 fn goal_data<'a>(&self, goal: &'a Arc<GoalData<Self>>) -> &'a GoalData<Self> {
220 fn goals_data<'a>(&self, goals: &'a Vec<Goal<Interner>>) -> &'a [Goal<Interner>] {
224 fn intern_substitution<E>(
226 data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
227 ) -> Result<Vec<GenericArg<Self>>, E> {
228 data.into_iter().collect()
231 fn substitution_data<'a>(
233 substitution: &'a Vec<GenericArg<Self>>,
234 ) -> &'a [GenericArg<Self>] {
238 fn intern_program_clause(
240 data: chalk_ir::ProgramClauseData<Self>,
241 ) -> chalk_ir::ProgramClauseData<Self> {
245 fn program_clause_data<'a>(
247 clause: &'a chalk_ir::ProgramClauseData<Self>,
248 ) -> &'a chalk_ir::ProgramClauseData<Self> {
252 fn intern_program_clauses<E>(
254 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
255 ) -> Result<Arc<[chalk_ir::ProgramClause<Self>]>, E> {
256 data.into_iter().collect()
259 fn program_clauses_data<'a>(
261 clauses: &'a Arc<[chalk_ir::ProgramClause<Self>]>,
262 ) -> &'a [chalk_ir::ProgramClause<Self>] {
266 fn intern_quantified_where_clauses<E>(
268 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
269 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
270 data.into_iter().collect()
273 fn quantified_where_clauses_data<'a>(
275 clauses: &'a Self::InternedQuantifiedWhereClauses,
276 ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
280 fn intern_generic_arg_kinds<E>(
282 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
283 ) -> Result<Self::InternedVariableKinds, E> {
284 data.into_iter().collect()
287 fn variable_kinds_data<'a>(
289 parameter_kinds: &'a Self::InternedVariableKinds,
290 ) -> &'a [chalk_ir::VariableKind<Self>] {
294 fn intern_canonical_var_kinds<E>(
296 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
297 ) -> Result<Self::InternedCanonicalVarKinds, E> {
298 data.into_iter().collect()
301 fn canonical_var_kinds_data<'a>(
303 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
304 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
309 impl chalk_ir::interner::HasInterner for Interner {
310 type Interner = Self;
313 pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
314 pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<Interner>;
315 pub type TraitId = chalk_ir::TraitId<Interner>;
316 pub type TraitDatum = chalk_rust_ir::TraitDatum<Interner>;
317 pub type StructId = chalk_ir::AdtId<Interner>;
318 pub type StructDatum = chalk_rust_ir::AdtDatum<Interner>;
319 pub type ImplId = chalk_ir::ImplId<Interner>;
320 pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>;
321 pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId<Interner>;
322 pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<Interner>;
324 pub(super) trait ToChalk {
326 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
327 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
330 pub(super) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T
332 T: ToChalk<Chalk = ChalkT>,
334 T::from_chalk(db, chalk)
337 impl ToChalk for Ty {
338 type Chalk = chalk_ir::Ty<Interner>;
339 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
341 Ty::Apply(apply_ty) => {
342 if let TypeCtor::Ref(m) = apply_ty.ctor {
343 return ref_to_chalk(db, m, apply_ty.parameters);
345 let name = apply_ty.ctor.to_chalk(db);
346 let substitution = apply_ty.parameters.to_chalk(db);
347 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
349 Ty::Projection(proj_ty) => {
350 let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
351 let substitution = proj_ty.parameters.to_chalk(db);
352 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
359 Ty::Placeholder(id) => {
360 let interned_id = db.intern_type_param_id(id);
362 ui: UniverseIndex::ROOT,
363 idx: interned_id.as_intern_id().as_usize(),
365 .to_ty::<Interner>(&Interner)
367 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
368 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
369 Ty::Dyn(predicates) => {
370 let where_clauses = chalk_ir::QuantifiedWhereClauses::from(
372 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
374 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) };
375 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
377 Ty::Opaque(_) | Ty::Unknown => {
378 let substitution = chalk_ir::Substitution::empty(&Interner);
379 let name = TypeName::Error;
380 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
384 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
385 match chalk.data(&Interner).clone() {
386 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
387 TypeName::Error => Ty::Unknown,
388 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
390 let ctor = from_chalk(db, apply_ty.name);
391 let parameters = from_chalk(db, apply_ty.substitution);
392 Ty::Apply(ApplicationTy { ctor, parameters })
395 chalk_ir::TyData::Placeholder(idx) => {
396 assert_eq!(idx.ui, UniverseIndex::ROOT);
397 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
398 crate::salsa::InternId::from(idx.idx),
400 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
402 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => {
403 let associated_ty = from_chalk(db, proj.associated_ty_id);
404 let parameters = from_chalk(db, proj.substitution);
405 Ty::Projection(ProjectionTy { associated_ty, parameters })
407 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(),
408 chalk_ir::TyData::Function(_) => unimplemented!(),
409 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx),
410 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
411 chalk_ir::TyData::Dyn(where_clauses) => {
412 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
413 let predicates = where_clauses
417 .map(|c| from_chalk(db, c.clone()))
425 const LIFETIME_PLACEHOLDER: PlaceholderIndex =
426 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
428 /// We currently don't model lifetimes, but Chalk does. So, we have to insert a
429 /// fake lifetime here, because Chalks built-in logic may expect it to be there.
431 db: &dyn HirDatabase,
432 mutability: Mutability,
434 ) -> chalk_ir::Ty<Interner> {
435 let arg = subst[0].clone().to_chalk(db);
436 let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner);
437 chalk_ir::ApplicationTy {
438 name: TypeName::Ref(mutability.to_chalk(db)),
439 substitution: chalk_ir::Substitution::from(
441 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
447 /// Here we remove the lifetime from the type we got from Chalk.
449 db: &dyn HirDatabase,
450 mutability: chalk_ir::Mutability,
451 subst: chalk_ir::Substitution<Interner>,
455 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
457 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
460 impl ToChalk for Substs {
461 type Chalk = chalk_ir::Substitution<Interner>;
463 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
464 chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
467 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
470 .map(|p| match p.ty(&Interner) {
471 Some(ty) => from_chalk(db, ty.clone()),
472 None => unimplemented!(),
479 impl ToChalk for TraitRef {
480 type Chalk = chalk_ir::TraitRef<Interner>;
482 fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> {
483 let trait_id = self.trait_.to_chalk(db);
484 let substitution = self.substs.to_chalk(db);
485 chalk_ir::TraitRef { trait_id, substitution }
488 fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self {
489 let trait_ = from_chalk(db, trait_ref.trait_id);
490 let substs = from_chalk(db, trait_ref.substitution);
491 TraitRef { trait_, substs }
495 impl ToChalk for hir_def::TraitId {
496 type Chalk = TraitId;
498 fn to_chalk(self, _db: &dyn HirDatabase) -> TraitId {
499 chalk_ir::TraitId(self.as_intern_id())
502 fn from_chalk(_db: &dyn HirDatabase, trait_id: TraitId) -> hir_def::TraitId {
503 InternKey::from_intern_id(trait_id.0)
507 impl ToChalk for TypeCtor {
508 type Chalk = TypeName<Interner>;
510 fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> {
512 TypeCtor::AssociatedType(type_alias) => {
513 let type_id = type_alias.to_chalk(db);
514 TypeName::AssociatedType(type_id)
517 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
518 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
519 TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
520 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) => {
521 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
523 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) => {
524 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
527 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
528 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
529 TypeCtor::Slice => TypeName::Slice,
530 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
531 TypeCtor::Str => TypeName::Str,
533 TypeCtor::Int(Uncertain::Unknown)
534 | TypeCtor::Float(Uncertain::Unknown)
538 | TypeCtor::FnPtr { .. }
540 | TypeCtor::Closure { .. } => {
541 // other TypeCtors get interned and turned into a chalk StructId
542 let struct_id = db.intern_type_ctor(self).into();
543 TypeName::Adt(struct_id)
548 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
550 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
551 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
552 TypeName::OpaqueType(_) => unreachable!(),
554 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
555 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
556 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(Uncertain::Known(IntTy {
557 signedness: Signedness::Signed,
558 bitness: bitness_from_chalk_int(int_ty),
560 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(Uncertain::Known(IntTy {
561 signedness: Signedness::Unsigned,
562 bitness: bitness_from_chalk_uint(uint_ty),
564 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
565 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 }))
567 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
568 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 }))
570 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
571 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
572 TypeName::Slice => TypeCtor::Slice,
573 TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)),
574 TypeName::Str => TypeCtor::Str,
576 TypeName::FnDef(_) => unreachable!(),
579 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
586 fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness {
587 use chalk_ir::UintTy;
590 UintTy::Usize => IntBitness::Xsize,
591 UintTy::U8 => IntBitness::X8,
592 UintTy::U16 => IntBitness::X16,
593 UintTy::U32 => IntBitness::X32,
594 UintTy::U64 => IntBitness::X64,
595 UintTy::U128 => IntBitness::X128,
599 fn bitness_from_chalk_int(int_ty: chalk_ir::IntTy) -> IntBitness {
603 IntTy::Isize => IntBitness::Xsize,
604 IntTy::I8 => IntBitness::X8,
605 IntTy::I16 => IntBitness::X16,
606 IntTy::I32 => IntBitness::X32,
607 IntTy::I64 => IntBitness::X64,
608 IntTy::I128 => IntBitness::X128,
612 fn int_ty_to_chalk(int_ty: IntTy) -> Scalar {
613 use chalk_ir::{IntTy, UintTy};
615 match int_ty.signedness {
616 Signedness::Signed => Scalar::Int(match int_ty.bitness {
617 IntBitness::Xsize => IntTy::Isize,
618 IntBitness::X8 => IntTy::I8,
619 IntBitness::X16 => IntTy::I16,
620 IntBitness::X32 => IntTy::I32,
621 IntBitness::X64 => IntTy::I64,
622 IntBitness::X128 => IntTy::I128,
624 Signedness::Unsigned => Scalar::Uint(match int_ty.bitness {
625 IntBitness::Xsize => UintTy::Usize,
626 IntBitness::X8 => UintTy::U8,
627 IntBitness::X16 => UintTy::U16,
628 IntBitness::X32 => UintTy::U32,
629 IntBitness::X64 => UintTy::U64,
630 IntBitness::X128 => UintTy::U128,
635 impl ToChalk for Mutability {
636 type Chalk = chalk_ir::Mutability;
637 fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk {
639 Mutability::Shared => chalk_ir::Mutability::Not,
640 Mutability::Mut => chalk_ir::Mutability::Mut,
643 fn from_chalk(_db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
645 chalk_ir::Mutability::Mut => Mutability::Mut,
646 chalk_ir::Mutability::Not => Mutability::Shared,
651 impl ToChalk for Impl {
654 fn to_chalk(self, db: &dyn HirDatabase) -> ImplId {
655 db.intern_chalk_impl(self).into()
658 fn from_chalk(db: &dyn HirDatabase, impl_id: ImplId) -> Impl {
659 db.lookup_intern_chalk_impl(impl_id.into())
663 impl ToChalk for TypeAliasId {
664 type Chalk = AssocTypeId;
666 fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId {
667 chalk_ir::AssocTypeId(self.as_intern_id())
670 fn from_chalk(_db: &dyn HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId {
671 InternKey::from_intern_id(type_alias_id.0)
675 impl ToChalk for AssocTyValue {
676 type Chalk = AssociatedTyValueId;
678 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValueId {
679 db.intern_assoc_ty_value(self).into()
682 fn from_chalk(db: &dyn HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue {
683 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into())
687 impl ToChalk for GenericPredicate {
688 type Chalk = chalk_ir::QuantifiedWhereClause<Interner>;
690 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> {
692 GenericPredicate::Implemented(trait_ref) => {
693 let chalk_trait_ref = trait_ref.to_chalk(db);
694 let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner);
695 make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0)
697 GenericPredicate::Projection(projection_pred) => {
698 let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner);
699 let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
700 let alias = chalk_ir::AliasTy::Projection(projection);
701 make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0)
703 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
708 db: &dyn HirDatabase,
709 where_clause: chalk_ir::QuantifiedWhereClause<Interner>,
710 ) -> GenericPredicate {
711 // we don't produce any where clauses with binders and can't currently deal with them
714 .shifted_out(&Interner)
715 .expect("unexpected bound vars in where clause")
717 chalk_ir::WhereClause::Implemented(tr) => {
718 GenericPredicate::Implemented(from_chalk(db, tr))
720 chalk_ir::WhereClause::AliasEq(projection_eq) => {
721 let projection_ty = from_chalk(
723 match projection_eq.alias {
724 chalk_ir::AliasTy::Projection(p) => p,
725 _ => unimplemented!(),
728 let ty = from_chalk(db, projection_eq.ty);
729 GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty })
735 impl ToChalk for ProjectionTy {
736 type Chalk = chalk_ir::ProjectionTy<Interner>;
738 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
739 chalk_ir::ProjectionTy {
740 associated_ty_id: self.associated_ty.to_chalk(db),
741 substitution: self.parameters.to_chalk(db),
746 db: &dyn HirDatabase,
747 projection_ty: chalk_ir::ProjectionTy<Interner>,
750 associated_ty: from_chalk(db, projection_ty.associated_ty_id),
751 parameters: from_chalk(db, projection_ty.substitution),
756 impl ToChalk for super::ProjectionPredicate {
757 type Chalk = chalk_ir::AliasEq<Interner>;
759 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
761 alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)),
762 ty: self.ty.to_chalk(db),
766 fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self {
771 impl ToChalk for Obligation {
772 type Chalk = chalk_ir::DomainGoal<Interner>;
774 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
776 Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner),
777 Obligation::Projection(pr) => pr.to_chalk(db).cast(&Interner),
781 fn from_chalk(_db: &dyn HirDatabase, _goal: chalk_ir::DomainGoal<Interner>) -> Self {
786 impl<T> ToChalk for Canonical<T>
789 T::Chalk: HasInterner<Interner = Interner>,
791 type Chalk = chalk_ir::Canonical<T::Chalk>;
793 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
794 let parameter = chalk_ir::CanonicalVarKind::new(
795 chalk_ir::VariableKind::Ty,
796 chalk_ir::UniverseIndex::ROOT,
798 let value = self.value.to_chalk(db);
799 chalk_ir::Canonical {
801 binders: chalk_ir::CanonicalVarKinds::from(&Interner, vec![parameter; self.num_vars]),
805 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
807 num_vars: canonical.binders.len(&Interner),
808 value: from_chalk(db, canonical.value),
813 impl ToChalk for Arc<super::TraitEnvironment> {
814 type Chalk = chalk_ir::Environment<Interner>;
816 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Environment<Interner> {
817 let mut clauses = Vec::new();
818 for pred in &self.predicates {
820 // for env, we just ignore errors
823 let program_clause: chalk_ir::ProgramClause<Interner> =
824 pred.clone().to_chalk(db).cast(&Interner);
825 clauses.push(program_clause.into_from_env_clause(&Interner));
827 chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses)
831 _db: &dyn HirDatabase,
832 _env: chalk_ir::Environment<Interner>,
833 ) -> Arc<super::TraitEnvironment> {
838 impl<T: ToChalk> ToChalk for super::InEnvironment<T>
840 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
842 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
844 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
845 chalk_ir::InEnvironment {
846 environment: self.environment.to_chalk(db),
847 goal: self.value.to_chalk(db),
852 db: &dyn HirDatabase,
853 in_env: chalk_ir::InEnvironment<T::Chalk>,
854 ) -> super::InEnvironment<T> {
855 super::InEnvironment {
856 environment: from_chalk(db, in_env.environment),
857 value: from_chalk(db, in_env.goal),
862 impl ToChalk for builtin::BuiltinImplData {
863 type Chalk = ImplDatum;
865 fn to_chalk(self, db: &dyn HirDatabase) -> ImplDatum {
866 let impl_type = chalk_rust_ir::ImplType::External;
867 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
869 let impl_datum_bound =
870 chalk_rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses };
871 let associated_ty_value_ids =
872 self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect();
873 chalk_rust_ir::ImplDatum {
874 binders: make_binders(impl_datum_bound, self.num_vars),
876 polarity: chalk_rust_ir::Polarity::Positive,
877 associated_ty_value_ids,
881 fn from_chalk(_db: &dyn HirDatabase, _data: ImplDatum) -> Self {
886 impl ToChalk for builtin::BuiltinImplAssocTyValueData {
887 type Chalk = AssociatedTyValue;
889 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue {
890 let ty = self.value.to_chalk(db);
891 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty };
893 chalk_rust_ir::AssociatedTyValue {
894 associated_ty_id: self.assoc_ty_id.to_chalk(db),
895 impl_id: self.impl_.to_chalk(db),
896 value: make_binders(value_bound, self.num_vars),
901 _db: &dyn HirDatabase,
902 _data: AssociatedTyValue,
903 ) -> builtin::BuiltinImplAssocTyValueData {
908 fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
910 T: HasInterner<Interner = Interner>,
912 chalk_ir::Binders::new(
913 chalk_ir::VariableKinds::from(
915 std::iter::repeat(chalk_ir::VariableKind::Ty).take(num_vars),
921 fn convert_where_clauses(
922 db: &dyn HirDatabase,
925 ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
926 let generic_predicates = db.generic_predicates(def);
927 let mut result = Vec::with_capacity(generic_predicates.len());
928 for pred in generic_predicates.iter() {
929 if pred.value.is_error() {
930 // skip errored predicates completely
933 result.push(pred.clone().subst(substs).to_chalk(db));
938 fn generic_predicate_to_inline_bound(
939 db: &dyn HirDatabase,
940 pred: &GenericPredicate,
942 ) -> Option<chalk_rust_ir::InlineBound<Interner>> {
943 // An InlineBound is like a GenericPredicate, except the self type is left out.
944 // We don't have a special type for this, but Chalk does.
946 GenericPredicate::Implemented(trait_ref) => {
947 if &trait_ref.substs[0] != self_ty {
948 // we can only convert predicates back to type bounds if they
949 // have the expected self type
952 let args_no_self = trait_ref.substs[1..]
954 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
957 chalk_rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self };
958 Some(chalk_rust_ir::InlineBound::TraitBound(trait_bound))
960 GenericPredicate::Projection(proj) => {
961 if &proj.projection_ty.parameters[0] != self_ty {
964 let trait_ = match proj.projection_ty.associated_ty.lookup(db.upcast()).container {
965 AssocContainerId::TraitId(t) => t,
966 _ => panic!("associated type not in trait"),
968 let args_no_self = proj.projection_ty.parameters[1..]
970 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
972 let alias_eq_bound = chalk_rust_ir::AliasEqBound {
973 value: proj.ty.clone().to_chalk(db),
974 trait_bound: chalk_rust_ir::TraitBound {
975 trait_id: trait_.to_chalk(db),
978 associated_ty_id: proj.projection_ty.associated_ty.to_chalk(db),
979 parameters: Vec::new(), // FIXME we don't support generic associated types yet
981 Some(chalk_rust_ir::InlineBound::AliasEqBound(alias_eq_bound))
983 GenericPredicate::Error => None,
987 impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
988 fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> {
989 self.db.associated_ty_data(id)
991 fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> {
992 self.db.trait_datum(self.krate, trait_id)
994 fn adt_datum(&self, struct_id: StructId) -> Arc<StructDatum> {
995 self.db.struct_datum(self.krate, struct_id)
997 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
998 self.db.impl_datum(self.krate, impl_id)
1003 _fn_def_id: chalk_ir::FnDefId<Interner>,
1004 ) -> Arc<chalk_rust_ir::FnDefDatum<Interner>> {
1005 // We don't yet provide any FnDefs to Chalk
1012 parameters: &[GenericArg<Interner>],
1014 debug!("impls_for_trait {:?}", trait_id);
1015 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
1017 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
1019 let self_ty_fp = TyFingerprint::for_impl(&ty);
1021 // Note: Since we're using impls_for_trait, only impls where the trait
1022 // can be resolved should ever reach Chalk. `impl_datum` relies on that
1023 // and will panic if the trait can't be resolved.
1024 let mut result: Vec<_> = self
1026 .impls_for_trait(self.krate, trait_, self_ty_fp)
1030 .map(|impl_| impl_.to_chalk(self.db))
1033 let arg: Option<Ty> =
1034 parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone()));
1036 builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| {
1037 result.push(i.to_chalk(self.db))
1040 debug!("impls_for_trait returned {} impls", result.len());
1043 fn impl_provided_for(&self, auto_trait_id: TraitId, struct_id: StructId) -> bool {
1044 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id);
1047 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
1048 self.db.associated_ty_value(self.krate, id)
1050 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> {
1053 fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> {
1054 // We don't do coherence checking (yet)
1057 fn interner(&self) -> &Interner {
1060 fn well_known_trait_id(
1062 well_known_trait: chalk_rust_ir::WellKnownTrait,
1063 ) -> Option<chalk_ir::TraitId<Interner>> {
1064 let lang_attr = lang_attr_from_well_known_trait(well_known_trait);
1065 let lang_items = self.db.crate_lang_items(self.krate);
1066 let trait_ = match lang_items.target(lang_attr) {
1067 Some(LangItemTarget::TraitId(trait_)) => trait_,
1070 Some(trait_.to_chalk(self.db))
1073 fn program_clauses_for_env(
1075 environment: &chalk_ir::Environment<Interner>,
1076 ) -> chalk_ir::ProgramClauses<Interner> {
1077 self.db.program_clauses_for_chalk_env(self.krate, environment.clone())
1082 _id: chalk_ir::OpaqueTyId<Interner>,
1083 ) -> Arc<chalk_rust_ir::OpaqueTyDatum<Interner>> {
1089 _well_known: chalk_rust_ir::WellKnownTrait,
1090 _ty: &chalk_ir::TyData<Interner>,
1092 // this method is mostly for rustc
1096 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
1097 // FIXME: implement actual object safety
1102 pub(crate) fn program_clauses_for_chalk_env_query(
1103 db: &dyn HirDatabase,
1105 environment: chalk_ir::Environment<Interner>,
1106 ) -> chalk_ir::ProgramClauses<Interner> {
1107 chalk_solve::program_clauses_for_env(&ChalkContext { db, krate }, &environment)
1110 pub(crate) fn associated_ty_data_query(
1111 db: &dyn HirDatabase,
1113 ) -> Arc<AssociatedTyDatum> {
1114 debug!("associated_ty_data {:?}", id);
1115 let type_alias: TypeAliasId = from_chalk(db, id);
1116 let trait_ = match type_alias.lookup(db.upcast()).container {
1117 AssocContainerId::TraitId(t) => t,
1118 _ => panic!("associated type not in trait"),
1121 // Lower bounds -- we could/should maybe move this to a separate query in `lower`
1122 let type_alias_data = db.type_alias_data(type_alias);
1123 let generic_params = generics(db.upcast(), type_alias.into());
1124 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
1125 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
1126 let ctx = crate::TyLoweringContext::new(db, &resolver)
1127 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
1128 let self_ty = Ty::Bound(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0));
1129 let bounds = type_alias_data
1132 .flat_map(|bound| GenericPredicate::from_type_bound(&ctx, bound, self_ty.clone()))
1133 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
1134 .map(|bound| make_binders(bound.shifted_in(&Interner), 0))
1137 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
1138 let bound_data = chalk_rust_ir::AssociatedTyDatumBound { bounds, where_clauses };
1139 let datum = AssociatedTyDatum {
1140 trait_id: trait_.to_chalk(db),
1143 binders: make_binders(bound_data, generic_params.len()),
1148 pub(crate) fn trait_datum_query(
1149 db: &dyn HirDatabase,
1152 ) -> Arc<TraitDatum> {
1153 debug!("trait_datum {:?}", trait_id);
1154 let trait_: hir_def::TraitId = from_chalk(db, trait_id);
1155 let trait_data = db.trait_data(trait_);
1156 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
1157 let generic_params = generics(db.upcast(), trait_.into());
1158 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
1159 let flags = chalk_rust_ir::TraitFlags {
1160 auto: trait_data.auto,
1161 upstream: trait_.lookup(db.upcast()).container.module(db.upcast()).krate != krate,
1162 non_enumerable: true,
1163 coinductive: false, // only relevant for Chalk testing
1164 // FIXME set these flags correctly
1168 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
1169 let associated_ty_ids =
1170 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
1171 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
1173 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
1174 let trait_datum = TraitDatum {
1176 binders: make_binders(trait_datum_bound, bound_vars.len()),
1181 Arc::new(trait_datum)
1184 fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {
1186 "sized" => WellKnownTrait::SizedTrait,
1187 "copy" => WellKnownTrait::CopyTrait,
1188 "clone" => WellKnownTrait::CloneTrait,
1189 "drop" => WellKnownTrait::DropTrait,
1194 fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
1196 WellKnownTrait::SizedTrait => "sized",
1197 WellKnownTrait::CopyTrait => "copy",
1198 WellKnownTrait::CloneTrait => "clone",
1199 WellKnownTrait::DropTrait => "drop",
1203 pub(crate) fn struct_datum_query(
1204 db: &dyn HirDatabase,
1206 struct_id: StructId,
1207 ) -> Arc<StructDatum> {
1208 debug!("struct_datum {:?}", struct_id);
1209 let type_ctor: TypeCtor = from_chalk(db, TypeName::Adt(struct_id));
1210 debug!("struct {:?} = {:?}", struct_id, type_ctor);
1211 let num_params = type_ctor.num_ty_params(db);
1212 let upstream = type_ctor.krate(db) != Some(krate);
1213 let where_clauses = type_ctor
1215 .map(|generic_def| {
1216 let generic_params = generics(db.upcast(), generic_def);
1217 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
1218 convert_where_clauses(db, generic_def, &bound_vars)
1220 .unwrap_or_else(Vec::new);
1221 let flags = chalk_rust_ir::AdtFlags {
1223 // FIXME set fundamental flag correctly
1226 let struct_datum_bound = chalk_rust_ir::AdtDatumBound {
1227 fields: Vec::new(), // FIXME add fields (only relevant for auto traits)
1231 StructDatum { id: struct_id, binders: make_binders(struct_datum_bound, num_params), flags };
1232 Arc::new(struct_datum)
1235 pub(crate) fn impl_datum_query(
1236 db: &dyn HirDatabase,
1239 ) -> Arc<ImplDatum> {
1240 let _p = ra_prof::profile("impl_datum");
1241 debug!("impl_datum {:?}", impl_id);
1242 let impl_: Impl = from_chalk(db, impl_id);
1244 Impl::ImplDef(impl_def) => impl_def_datum(db, krate, impl_id, impl_def),
1245 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
1250 db: &dyn HirDatabase,
1253 impl_id: hir_def::ImplId,
1254 ) -> Arc<ImplDatum> {
1256 .impl_trait(impl_id)
1257 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
1258 .expect("invalid impl passed to Chalk")
1260 let impl_data = db.impl_data(impl_id);
1262 let generic_params = generics(db.upcast(), impl_id.into());
1263 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
1264 let trait_ = trait_ref.trait_;
1265 let impl_type = if impl_id.lookup(db.upcast()).container.module(db.upcast()).krate == krate {
1266 chalk_rust_ir::ImplType::Local
1268 chalk_rust_ir::ImplType::External
1270 let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars);
1271 let negative = impl_data.is_negative;
1273 "impl {:?}: {}{} where {:?}",
1275 if negative { "!" } else { "" },
1276 trait_ref.display(db),
1279 let trait_ref = trait_ref.to_chalk(db);
1281 let polarity = if negative {
1282 chalk_rust_ir::Polarity::Negative
1284 chalk_rust_ir::Polarity::Positive
1287 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses };
1288 let trait_data = db.trait_data(trait_);
1289 let associated_ty_value_ids = impl_data
1292 .filter_map(|item| match item {
1293 AssocItemId::TypeAliasId(type_alias) => Some(*type_alias),
1296 .filter(|&type_alias| {
1297 // don't include associated types that don't exist in the trait
1298 let name = &db.type_alias_data(type_alias).name;
1299 trait_data.associated_type_by_name(name).is_some()
1301 .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db))
1303 debug!("impl_datum: {:?}", impl_datum_bound);
1304 let impl_datum = ImplDatum {
1305 binders: make_binders(impl_datum_bound, bound_vars.len()),
1308 associated_ty_value_ids,
1310 Arc::new(impl_datum)
1313 pub(crate) fn associated_ty_value_query(
1314 db: &dyn HirDatabase,
1316 id: AssociatedTyValueId,
1317 ) -> Arc<AssociatedTyValue> {
1318 let data: AssocTyValue = from_chalk(db, id);
1320 AssocTyValue::TypeAlias(type_alias) => {
1321 type_alias_associated_ty_value(db, krate, type_alias)
1323 _ => Arc::new(builtin::associated_ty_value(db, krate, data).to_chalk(db)),
1327 fn type_alias_associated_ty_value(
1328 db: &dyn HirDatabase,
1330 type_alias: TypeAliasId,
1331 ) -> Arc<AssociatedTyValue> {
1332 let type_alias_data = db.type_alias_data(type_alias);
1333 let impl_id = match type_alias.lookup(db.upcast()).container {
1334 AssocContainerId::ImplId(it) => it,
1335 _ => panic!("assoc ty value should be in impl"),
1338 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved
1341 .trait_data(trait_ref.trait_)
1342 .associated_type_by_name(&type_alias_data.name)
1343 .expect("assoc ty value should not exist"); // validated when building the impl data as well
1344 let ty = db.ty(type_alias.into());
1345 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
1346 let value = chalk_rust_ir::AssociatedTyValue {
1347 impl_id: Impl::ImplDef(impl_id).to_chalk(db),
1348 associated_ty_id: assoc_ty.to_chalk(db),
1349 value: make_binders(value_bound, ty.num_binders),
1354 impl From<StructId> for crate::TypeCtorId {
1355 fn from(struct_id: StructId) -> Self {
1356 InternKey::from_intern_id(struct_id.0)
1360 impl From<crate::TypeCtorId> for StructId {
1361 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
1362 chalk_ir::AdtId(type_ctor_id.as_intern_id())
1366 impl From<ImplId> for crate::traits::GlobalImplId {
1367 fn from(impl_id: ImplId) -> Self {
1368 InternKey::from_intern_id(impl_id.0)
1372 impl From<crate::traits::GlobalImplId> for ImplId {
1373 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
1374 chalk_ir::ImplId(impl_id.as_intern_id())
1378 impl From<chalk_rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId {
1379 fn from(id: chalk_rust_ir::AssociatedTyValueId<Interner>) -> Self {
1380 Self::from_intern_id(id.0)
1384 impl From<crate::traits::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId<Interner> {
1385 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self {
1386 chalk_rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id())