aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/traits/chalk.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/traits/chalk.rs')
-rw-r--r--crates/hir_ty/src/traits/chalk.rs589
1 files changed, 589 insertions, 0 deletions
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
new file mode 100644
index 000000000..17c83b6a4
--- /dev/null
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -0,0 +1,589 @@
1//! Conversion code from/to Chalk.
2use std::sync::Arc;
3
4use log::debug;
5
6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8
9use base_db::{salsa::InternKey, CrateId};
10use hir_def::{
11 lang_item::{lang_attr, LangItemTarget},
12 AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId,
13};
14
15use super::ChalkContext;
16use crate::{
17 db::HirDatabase,
18 display::HirDisplay,
19 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
20 utils::generics,
21 CallableDefId, DebruijnIndex, FnSig, GenericPredicate, Substs, Ty, TypeCtor,
22};
23use mapping::{
24 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
25};
26
27pub use self::interner::*;
28
29pub(super) mod tls;
30mod interner;
31mod mapping;
32
33pub(super) trait ToChalk {
34 type Chalk;
35 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
36 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
37}
38
39pub(super) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T
40where
41 T: ToChalk<Chalk = ChalkT>,
42{
43 T::from_chalk(db, chalk)
44}
45
46impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
47 fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> {
48 self.db.associated_ty_data(id)
49 }
50 fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> {
51 self.db.trait_datum(self.krate, trait_id)
52 }
53 fn adt_datum(&self, struct_id: AdtId) -> Arc<StructDatum> {
54 self.db.struct_datum(self.krate, struct_id)
55 }
56 fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr {
57 rust_ir::AdtRepr { repr_c: false, repr_packed: false }
58 }
59 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
60 self.db.impl_datum(self.krate, impl_id)
61 }
62
63 fn fn_def_datum(
64 &self,
65 fn_def_id: chalk_ir::FnDefId<Interner>,
66 ) -> Arc<rust_ir::FnDefDatum<Interner>> {
67 self.db.fn_def_datum(self.krate, fn_def_id)
68 }
69
70 fn impls_for_trait(
71 &self,
72 trait_id: TraitId,
73 parameters: &[GenericArg<Interner>],
74 binders: &CanonicalVarKinds<Interner>,
75 ) -> Vec<ImplId> {
76 debug!("impls_for_trait {:?}", trait_id);
77 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
78
79 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
80
81 fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> {
82 if let Ty::Bound(bv) = ty {
83 let binders = binders.as_slice(&Interner);
84 if bv.debruijn == DebruijnIndex::INNERMOST {
85 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
86 return Some(tk);
87 }
88 }
89 }
90 None
91 }
92
93 let self_ty_fp = TyFingerprint::for_impl(&ty);
94 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
95 Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS,
96 Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS,
97 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
98 };
99
100 // Note: Since we're using impls_for_trait, only impls where the trait
101 // can be resolved should ever reach Chalk. `impl_datum` relies on that
102 // and will panic if the trait can't be resolved.
103 let in_deps = self.db.trait_impls_in_deps(self.krate);
104 let in_self = self.db.trait_impls_in_crate(self.krate);
105 let impl_maps = [in_deps, in_self];
106
107 let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db);
108
109 let result: Vec<_> = if fps.is_empty() {
110 debug!("Unrestricted search for {:?} impls...", trait_);
111 impl_maps
112 .iter()
113 .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
114 .collect()
115 } else {
116 impl_maps
117 .iter()
118 .flat_map(|crate_impl_defs| {
119 fps.iter().flat_map(move |fp| {
120 crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
121 })
122 })
123 .collect()
124 };
125
126 debug!("impls_for_trait returned {} impls", result.len());
127 result
128 }
129 fn impl_provided_for(&self, auto_trait_id: TraitId, struct_id: AdtId) -> bool {
130 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id);
131 false // FIXME
132 }
133 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
134 self.db.associated_ty_value(self.krate, id)
135 }
136
137 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> {
138 vec![]
139 }
140 fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> {
141 // We don't do coherence checking (yet)
142 unimplemented!()
143 }
144 fn interner(&self) -> &Interner {
145 &Interner
146 }
147 fn well_known_trait_id(
148 &self,
149 well_known_trait: rust_ir::WellKnownTrait,
150 ) -> Option<chalk_ir::TraitId<Interner>> {
151 let lang_attr = lang_attr_from_well_known_trait(well_known_trait);
152 let trait_ = match self.db.lang_item(self.krate, lang_attr.into()) {
153 Some(LangItemTarget::TraitId(trait_)) => trait_,
154 _ => return None,
155 };
156 Some(trait_.to_chalk(self.db))
157 }
158
159 fn program_clauses_for_env(
160 &self,
161 environment: &chalk_ir::Environment<Interner>,
162 ) -> chalk_ir::ProgramClauses<Interner> {
163 self.db.program_clauses_for_chalk_env(self.krate, environment.clone())
164 }
165
166 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
167 let interned_id = crate::db::InternedOpaqueTyId::from(id);
168 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
169 let (func, idx) = match full_id {
170 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx),
171 };
172 let datas =
173 self.db.return_type_impl_traits(func).expect("impl trait id without impl traits");
174 let data = &datas.value.impl_traits[idx as usize];
175 let bound = OpaqueTyDatumBound {
176 bounds: make_binders(
177 data.bounds
178 .value
179 .iter()
180 .cloned()
181 .filter(|b| !b.is_error())
182 .map(|b| b.to_chalk(self.db))
183 .collect(),
184 1,
185 ),
186 where_clauses: make_binders(vec![], 0),
187 };
188 let num_vars = datas.num_binders;
189 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) })
190 }
191
192 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
193 // FIXME: actually provide the hidden type; it is relevant for auto traits
194 Ty::Unknown.to_chalk(self.db)
195 }
196
197 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
198 // FIXME: implement actual object safety
199 true
200 }
201
202 fn closure_kind(
203 &self,
204 _closure_id: chalk_ir::ClosureId<Interner>,
205 _substs: &chalk_ir::Substitution<Interner>,
206 ) -> rust_ir::ClosureKind {
207 // Fn is the closure kind that implements all three traits
208 rust_ir::ClosureKind::Fn
209 }
210 fn closure_inputs_and_output(
211 &self,
212 _closure_id: chalk_ir::ClosureId<Interner>,
213 substs: &chalk_ir::Substitution<Interner>,
214 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
215 let sig_ty: Ty =
216 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
217 let sig = FnSig::from_fn_ptr_substs(
218 &sig_ty.substs().expect("first closure param should be fn ptr"),
219 false,
220 );
221 let io = rust_ir::FnDefInputsAndOutputDatum {
222 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
223 return_type: sig.ret().clone().to_chalk(self.db),
224 };
225 make_binders(io.shifted_in(&Interner), 0)
226 }
227 fn closure_upvars(
228 &self,
229 _closure_id: chalk_ir::ClosureId<Interner>,
230 _substs: &chalk_ir::Substitution<Interner>,
231 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
232 let ty = Ty::unit().to_chalk(self.db);
233 make_binders(ty, 0)
234 }
235 fn closure_fn_substitution(
236 &self,
237 _closure_id: chalk_ir::ClosureId<Interner>,
238 _substs: &chalk_ir::Substitution<Interner>,
239 ) -> chalk_ir::Substitution<Interner> {
240 Substs::empty().to_chalk(self.db)
241 }
242
243 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
244 let id = from_chalk(self.db, trait_id);
245 self.db.trait_data(id).name.to_string()
246 }
247 // FIXME: lookup names
248 fn adt_name(&self, struct_id: chalk_ir::AdtId<Interner>) -> String {
249 let datum = self.db.struct_datum(self.krate, struct_id);
250 format!("{:?}", datum.name(&Interner))
251 }
252 fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String {
253 format!("Assoc_{}", assoc_ty_id.0)
254 }
255 fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String {
256 format!("Opaque_{}", opaque_ty_id.0)
257 }
258 fn fn_def_name(&self, fn_def_id: chalk_ir::FnDefId<Interner>) -> String {
259 format!("fn_{}", fn_def_id.0)
260 }
261}
262
263pub(crate) fn program_clauses_for_chalk_env_query(
264 db: &dyn HirDatabase,
265 krate: CrateId,
266 environment: chalk_ir::Environment<Interner>,
267) -> chalk_ir::ProgramClauses<Interner> {
268 chalk_solve::program_clauses_for_env(&ChalkContext { db, krate }, &environment)
269}
270
271pub(crate) fn associated_ty_data_query(
272 db: &dyn HirDatabase,
273 id: AssocTypeId,
274) -> Arc<AssociatedTyDatum> {
275 debug!("associated_ty_data {:?}", id);
276 let type_alias: TypeAliasId = from_chalk(db, id);
277 let trait_ = match type_alias.lookup(db.upcast()).container {
278 AssocContainerId::TraitId(t) => t,
279 _ => panic!("associated type not in trait"),
280 };
281
282 // Lower bounds -- we could/should maybe move this to a separate query in `lower`
283 let type_alias_data = db.type_alias_data(type_alias);
284 let generic_params = generics(db.upcast(), type_alias.into());
285 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
286 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
287 let ctx = crate::TyLoweringContext::new(db, &resolver)
288 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
289 let self_ty = Ty::Bound(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0));
290 let bounds = type_alias_data
291 .bounds
292 .iter()
293 .flat_map(|bound| GenericPredicate::from_type_bound(&ctx, bound, self_ty.clone()))
294 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
295 .map(|bound| make_binders(bound.shifted_in(&Interner), 0))
296 .collect();
297
298 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
299 let bound_data = rust_ir::AssociatedTyDatumBound { bounds, where_clauses };
300 let datum = AssociatedTyDatum {
301 trait_id: trait_.to_chalk(db),
302 id,
303 name: type_alias,
304 binders: make_binders(bound_data, generic_params.len()),
305 };
306 Arc::new(datum)
307}
308
309pub(crate) fn trait_datum_query(
310 db: &dyn HirDatabase,
311 krate: CrateId,
312 trait_id: TraitId,
313) -> Arc<TraitDatum> {
314 debug!("trait_datum {:?}", trait_id);
315 let trait_: hir_def::TraitId = from_chalk(db, trait_id);
316 let trait_data = db.trait_data(trait_);
317 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
318 let generic_params = generics(db.upcast(), trait_.into());
319 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
320 let flags = rust_ir::TraitFlags {
321 auto: trait_data.auto,
322 upstream: trait_.lookup(db.upcast()).container.module(db.upcast()).krate != krate,
323 non_enumerable: true,
324 coinductive: false, // only relevant for Chalk testing
325 // FIXME: set these flags correctly
326 marker: false,
327 fundamental: false,
328 };
329 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
330 let associated_ty_ids =
331 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
332 let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses };
333 let well_known =
334 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
335 let trait_datum = TraitDatum {
336 id: trait_id,
337 binders: make_binders(trait_datum_bound, bound_vars.len()),
338 flags,
339 associated_ty_ids,
340 well_known,
341 };
342 Arc::new(trait_datum)
343}
344
345fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {
346 Some(match name {
347 "sized" => WellKnownTrait::Sized,
348 "copy" => WellKnownTrait::Copy,
349 "clone" => WellKnownTrait::Clone,
350 "drop" => WellKnownTrait::Drop,
351 "fn_once" => WellKnownTrait::FnOnce,
352 "fn_mut" => WellKnownTrait::FnMut,
353 "fn" => WellKnownTrait::Fn,
354 "unsize" => WellKnownTrait::Unsize,
355 _ => return None,
356 })
357}
358
359fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
360 match attr {
361 WellKnownTrait::Sized => "sized",
362 WellKnownTrait::Copy => "copy",
363 WellKnownTrait::Clone => "clone",
364 WellKnownTrait::Drop => "drop",
365 WellKnownTrait::FnOnce => "fn_once",
366 WellKnownTrait::FnMut => "fn_mut",
367 WellKnownTrait::Fn => "fn",
368 WellKnownTrait::Unsize => "unsize",
369 }
370}
371
372pub(crate) fn struct_datum_query(
373 db: &dyn HirDatabase,
374 krate: CrateId,
375 struct_id: AdtId,
376) -> Arc<StructDatum> {
377 debug!("struct_datum {:?}", struct_id);
378 let type_ctor: TypeCtor = from_chalk(db, TypeName::Adt(struct_id));
379 debug!("struct {:?} = {:?}", struct_id, type_ctor);
380 let num_params = type_ctor.num_ty_params(db);
381 let upstream = type_ctor.krate(db) != Some(krate);
382 let where_clauses = type_ctor
383 .as_generic_def()
384 .map(|generic_def| {
385 let generic_params = generics(db.upcast(), generic_def);
386 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
387 convert_where_clauses(db, generic_def, &bound_vars)
388 })
389 .unwrap_or_else(Vec::new);
390 let flags = rust_ir::AdtFlags {
391 upstream,
392 // FIXME set fundamental and phantom_data flags correctly
393 fundamental: false,
394 phantom_data: false,
395 };
396 // FIXME provide enum variants properly (for auto traits)
397 let variant = rust_ir::AdtVariantDatum {
398 fields: Vec::new(), // FIXME add fields (only relevant for auto traits),
399 };
400 let struct_datum_bound = rust_ir::AdtDatumBound { variants: vec![variant], where_clauses };
401 let struct_datum = StructDatum {
402 // FIXME set ADT kind
403 kind: rust_ir::AdtKind::Struct,
404 id: struct_id,
405 binders: make_binders(struct_datum_bound, num_params),
406 flags,
407 };
408 Arc::new(struct_datum)
409}
410
411pub(crate) fn impl_datum_query(
412 db: &dyn HirDatabase,
413 krate: CrateId,
414 impl_id: ImplId,
415) -> Arc<ImplDatum> {
416 let _p = profile::span("impl_datum");
417 debug!("impl_datum {:?}", impl_id);
418 let impl_: hir_def::ImplId = from_chalk(db, impl_id);
419 impl_def_datum(db, krate, impl_id, impl_)
420}
421
422fn impl_def_datum(
423 db: &dyn HirDatabase,
424 krate: CrateId,
425 chalk_id: ImplId,
426 impl_id: hir_def::ImplId,
427) -> Arc<ImplDatum> {
428 let trait_ref = db
429 .impl_trait(impl_id)
430 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
431 .expect("invalid impl passed to Chalk")
432 .value;
433 let impl_data = db.impl_data(impl_id);
434
435 let generic_params = generics(db.upcast(), impl_id.into());
436 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
437 let trait_ = trait_ref.trait_;
438 let impl_type = if impl_id.lookup(db.upcast()).container.module(db.upcast()).krate == krate {
439 rust_ir::ImplType::Local
440 } else {
441 rust_ir::ImplType::External
442 };
443 let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars);
444 let negative = impl_data.is_negative;
445 debug!(
446 "impl {:?}: {}{} where {:?}",
447 chalk_id,
448 if negative { "!" } else { "" },
449 trait_ref.display(db),
450 where_clauses
451 );
452 let trait_ref = trait_ref.to_chalk(db);
453
454 let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive };
455
456 let impl_datum_bound = rust_ir::ImplDatumBound { trait_ref, where_clauses };
457 let trait_data = db.trait_data(trait_);
458 let associated_ty_value_ids = impl_data
459 .items
460 .iter()
461 .filter_map(|item| match item {
462 AssocItemId::TypeAliasId(type_alias) => Some(*type_alias),
463 _ => None,
464 })
465 .filter(|&type_alias| {
466 // don't include associated types that don't exist in the trait
467 let name = &db.type_alias_data(type_alias).name;
468 trait_data.associated_type_by_name(name).is_some()
469 })
470 .map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db))
471 .collect();
472 debug!("impl_datum: {:?}", impl_datum_bound);
473 let impl_datum = ImplDatum {
474 binders: make_binders(impl_datum_bound, bound_vars.len()),
475 impl_type,
476 polarity,
477 associated_ty_value_ids,
478 };
479 Arc::new(impl_datum)
480}
481
482pub(crate) fn associated_ty_value_query(
483 db: &dyn HirDatabase,
484 krate: CrateId,
485 id: AssociatedTyValueId,
486) -> Arc<AssociatedTyValue> {
487 let type_alias: TypeAliasAsValue = from_chalk(db, id);
488 type_alias_associated_ty_value(db, krate, type_alias.0)
489}
490
491fn type_alias_associated_ty_value(
492 db: &dyn HirDatabase,
493 _krate: CrateId,
494 type_alias: TypeAliasId,
495) -> Arc<AssociatedTyValue> {
496 let type_alias_data = db.type_alias_data(type_alias);
497 let impl_id = match type_alias.lookup(db.upcast()).container {
498 AssocContainerId::ImplId(it) => it,
499 _ => panic!("assoc ty value should be in impl"),
500 };
501
502 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
503
504 let assoc_ty = db
505 .trait_data(trait_ref.trait_)
506 .associated_type_by_name(&type_alias_data.name)
507 .expect("assoc ty value should not exist"); // validated when building the impl data as well
508 let ty = db.ty(type_alias.into());
509 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
510 let value = rust_ir::AssociatedTyValue {
511 impl_id: impl_id.to_chalk(db),
512 associated_ty_id: assoc_ty.to_chalk(db),
513 value: make_binders(value_bound, ty.num_binders),
514 };
515 Arc::new(value)
516}
517
518pub(crate) fn fn_def_datum_query(
519 db: &dyn HirDatabase,
520 _krate: CrateId,
521 fn_def_id: FnDefId,
522) -> Arc<FnDefDatum> {
523 let callable_def: CallableDefId = from_chalk(db, fn_def_id);
524 let generic_params = generics(db.upcast(), callable_def.into());
525 let sig = db.callable_item_signature(callable_def);
526 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
527 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
528 let bound = rust_ir::FnDefDatumBound {
529 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
530 inputs_and_output: make_binders(
531 rust_ir::FnDefInputsAndOutputDatum {
532 argument_types: sig
533 .value
534 .params()
535 .iter()
536 .map(|ty| ty.clone().to_chalk(db))
537 .collect(),
538 return_type: sig.value.ret().clone().to_chalk(db),
539 }
540 .shifted_in(&Interner),
541 0,
542 ),
543 where_clauses,
544 };
545 let datum = FnDefDatum {
546 id: fn_def_id,
547 abi: (),
548 safety: chalk_ir::Safety::Safe,
549 variadic: sig.value.is_varargs,
550 binders: make_binders(bound, sig.num_binders),
551 };
552 Arc::new(datum)
553}
554
555impl From<FnDefId> for crate::db::InternedCallableDefId {
556 fn from(fn_def_id: FnDefId) -> Self {
557 InternKey::from_intern_id(fn_def_id.0)
558 }
559}
560
561impl From<crate::db::InternedCallableDefId> for FnDefId {
562 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
563 chalk_ir::FnDefId(callable_def_id.as_intern_id())
564 }
565}
566
567impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
568 fn from(id: OpaqueTyId) -> Self {
569 InternKey::from_intern_id(id.0)
570 }
571}
572
573impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
574 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
575 chalk_ir::OpaqueTyId(id.as_intern_id())
576 }
577}
578
579impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId {
580 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
581 Self::from_intern_id(id.0)
582 }
583}
584
585impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> {
586 fn from(id: crate::db::ClosureId) -> Self {
587 chalk_ir::ClosureId(id.as_intern_id())
588 }
589}