1 //! Provides the `RustIrDatabase` implementation for `chalk-solve`
3 //! The purpose of the `chalk_solve::RustIrDatabase` is to get data about
4 //! specific types, such as bounds, where clauses, or fields. This file contains
5 //! the minimal logic to assemble the types for `chalk-solve` by calling out to
6 //! either the `TyCtxt` (for information about types) or
7 //! `crate::chalk::lowering` (to lower rustc types into Chalk types).
9 use rustc_middle
::traits
::ChalkRustInterner
as RustInterner
;
10 use rustc_middle
::ty
::subst
::{InternalSubsts, Subst, SubstsRef}
;
11 use rustc_middle
::ty
::{self, AssocItemContainer, AssocKind, TyCtxt}
;
13 use rustc_hir
::def_id
::DefId
;
15 use rustc_span
::symbol
::sym
;
20 use crate::chalk
::lowering
::LowerInto
;
22 pub struct RustIrDatabase
<'tcx
> {
23 pub tcx
: TyCtxt
<'tcx
>,
24 pub interner
: RustInterner
<'tcx
>,
27 impl fmt
::Debug
for RustIrDatabase
<'_
> {
28 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
29 write
!(f
, "RustIrDatabase")
33 impl<'tcx
> chalk_solve
::RustIrDatabase
<RustInterner
<'tcx
>> for RustIrDatabase
<'tcx
> {
34 fn interner(&self) -> &RustInterner
<'tcx
> {
38 fn associated_ty_data(
40 assoc_type_id
: chalk_ir
::AssocTypeId
<RustInterner
<'tcx
>>,
41 ) -> Arc
<chalk_solve
::rust_ir
::AssociatedTyDatum
<RustInterner
<'tcx
>>> {
42 let def_id
= assoc_type_id
.0;
43 let assoc_item
= self.tcx
.associated_item(def_id
);
44 let trait_def_id
= match assoc_item
.container
{
45 AssocItemContainer
::TraitContainer(def_id
) => def_id
,
46 _
=> unimplemented
!("Not possible??"),
48 match assoc_item
.kind
{
50 _
=> unimplemented
!("Not possible??"),
52 let bound_vars
= bound_vars_for_item(self.tcx
, def_id
);
53 let binders
= binders_for(&self.interner
, bound_vars
);
54 // FIXME(chalk): this really isn't right I don't think. The functions
55 // for GATs are a bit hard to figure out. Are these supposed to be where
57 let predicates
= self.tcx
.predicates_defined_on(def_id
).predicates
;
58 let where_clauses
: Vec
<_
> = predicates
60 .map(|(wc
, _
)| wc
.subst(self.tcx
, &bound_vars
))
61 .filter_map(|wc
| LowerInto
::<Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>>::lower_into(wc
, &self.interner
)).collect();
63 Arc
::new(chalk_solve
::rust_ir
::AssociatedTyDatum
{
64 trait_id
: chalk_ir
::TraitId(trait_def_id
),
67 binders
: chalk_ir
::Binders
::new(
69 chalk_solve
::rust_ir
::AssociatedTyDatumBound { bounds: vec![], where_clauses }
,
76 trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
77 ) -> Arc
<chalk_solve
::rust_ir
::TraitDatum
<RustInterner
<'tcx
>>> {
78 let def_id
= trait_id
.0;
79 let trait_def
= self.tcx
.trait_def(def_id
);
81 let bound_vars
= bound_vars_for_item(self.tcx
, def_id
);
82 let binders
= binders_for(&self.interner
, bound_vars
);
83 let predicates
= self.tcx
.predicates_defined_on(def_id
).predicates
;
84 let where_clauses
: Vec
<_
> = predicates
86 .map(|(wc
, _
)| wc
.subst(self.tcx
, &bound_vars
))
87 .filter_map(|wc
| LowerInto
::<Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>>::lower_into(wc
, &self.interner
)).collect();
88 let associated_ty_ids
: Vec
<_
> = self
90 .associated_items(def_id
)
91 .in_definition_order()
92 .filter(|i
| i
.kind
== AssocKind
::Type
)
93 .map(|i
| chalk_ir
::AssocTypeId(i
.def_id
))
97 if self.tcx
.lang_items().sized_trait().map(|t
| def_id
== t
).unwrap_or(false) {
98 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Sized
)
99 } else if self.tcx
.lang_items().copy_trait().map(|t
| def_id
== t
).unwrap_or(false) {
100 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Copy
)
101 } else if self.tcx
.lang_items().clone_trait().map(|t
| def_id
== t
).unwrap_or(false) {
102 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Clone
)
103 } else if self.tcx
.lang_items().drop_trait().map(|t
| def_id
== t
).unwrap_or(false) {
104 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Drop
)
105 } else if self.tcx
.lang_items().fn_trait().map(|t
| def_id
== t
).unwrap_or(false) {
106 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Fn
)
107 } else if self.tcx
.lang_items().fn_once_trait().map(|t
| def_id
== t
).unwrap_or(false) {
108 Some(chalk_solve
::rust_ir
::WellKnownTrait
::FnOnce
)
109 } else if self.tcx
.lang_items().fn_mut_trait().map(|t
| def_id
== t
).unwrap_or(false) {
110 Some(chalk_solve
::rust_ir
::WellKnownTrait
::FnMut
)
114 Arc
::new(chalk_solve
::rust_ir
::TraitDatum
{
116 binders
: chalk_ir
::Binders
::new(
118 chalk_solve
::rust_ir
::TraitDatumBound { where_clauses }
,
120 flags
: chalk_solve
::rust_ir
::TraitFlags
{
121 auto: trait_def
.has_auto_impl
,
122 marker
: trait_def
.is_marker
,
123 upstream
: !def_id
.is_local(),
124 fundamental
: self.tcx
.has_attr(def_id
, sym
::fundamental
),
125 non_enumerable
: true,
135 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
136 ) -> Arc
<chalk_solve
::rust_ir
::AdtDatum
<RustInterner
<'tcx
>>> {
137 let adt_def
= adt_id
.0;
139 let bound_vars
= bound_vars_for_item(self.tcx
, adt_def
.did
);
140 let binders
= binders_for(&self.interner
, bound_vars
);
142 let predicates
= self.tcx
.predicates_of(adt_def
.did
).predicates
;
143 let where_clauses
: Vec
<_
> = predicates
145 .map(|(wc
, _
)| wc
.subst(self.tcx
, bound_vars
))
146 .filter_map(|wc
| LowerInto
::<Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>>::lower_into(wc
, &self.interner
))
148 let fields
= match adt_def
.adt_kind() {
149 ty
::AdtKind
::Struct
| ty
::AdtKind
::Union
=> {
150 let variant
= adt_def
.non_enum_variant();
157 .subst(self.tcx
, bound_vars
)
158 .lower_into(&self.interner
)
162 // FIXME(chalk): handle enums; force_impl_for requires this
163 ty
::AdtKind
::Enum
=> vec
![],
165 let struct_datum
= Arc
::new(chalk_solve
::rust_ir
::AdtDatum
{
167 binders
: chalk_ir
::Binders
::new(
169 chalk_solve
::rust_ir
::AdtDatumBound { fields, where_clauses }
,
171 flags
: chalk_solve
::rust_ir
::AdtFlags
{
172 upstream
: !adt_def
.did
.is_local(),
173 fundamental
: adt_def
.is_fundamental(),
174 phantom_data
: adt_def
.is_phantom_data(),
182 fn_def_id
: chalk_ir
::FnDefId
<RustInterner
<'tcx
>>,
183 ) -> Arc
<chalk_solve
::rust_ir
::FnDefDatum
<RustInterner
<'tcx
>>> {
184 let def_id
= fn_def_id
.0;
185 let bound_vars
= bound_vars_for_item(self.tcx
, def_id
);
186 let binders
= binders_for(&self.interner
, bound_vars
);
188 let predicates
= self.tcx
.predicates_defined_on(def_id
).predicates
;
189 let where_clauses
: Vec
<_
> = predicates
191 .map(|(wc
, _
)| wc
.subst(self.tcx
, &bound_vars
))
192 .filter_map(|wc
| LowerInto
::<Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>>::lower_into(wc
, &self.interner
)).collect();
194 let sig
= self.tcx
.fn_sig(def_id
);
195 let inputs_and_output
= sig
.inputs_and_output();
196 let (inputs_and_output
, iobinders
, _
) = crate::chalk
::lowering
::collect_bound_vars(
202 let argument_types
= inputs_and_output
[..inputs_and_output
.len() - 1]
204 .map(|t
| t
.subst(self.tcx
, &bound_vars
).lower_into(&self.interner
))
207 let return_type
= inputs_and_output
[inputs_and_output
.len() - 1]
208 .subst(self.tcx
, &bound_vars
)
209 .lower_into(&self.interner
);
211 let bound
= chalk_solve
::rust_ir
::FnDefDatumBound
{
212 inputs_and_output
: chalk_ir
::Binders
::new(
214 chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum { argument_types, return_type }
,
218 Arc
::new(chalk_solve
::rust_ir
::FnDefDatum
{
221 binders
: chalk_ir
::Binders
::new(binders
, bound
),
227 impl_id
: chalk_ir
::ImplId
<RustInterner
<'tcx
>>,
228 ) -> Arc
<chalk_solve
::rust_ir
::ImplDatum
<RustInterner
<'tcx
>>> {
229 let def_id
= impl_id
.0;
230 let bound_vars
= bound_vars_for_item(self.tcx
, def_id
);
231 let binders
= binders_for(&self.interner
, bound_vars
);
233 let trait_ref
= self.tcx
.impl_trait_ref(def_id
).expect("not an impl");
234 let trait_ref
= trait_ref
.subst(self.tcx
, bound_vars
);
236 let predicates
= self.tcx
.predicates_of(def_id
).predicates
;
237 let where_clauses
: Vec
<_
> = predicates
239 .map(|(wc
, _
)| wc
.subst(self.tcx
, bound_vars
))
240 .filter_map(|wc
| LowerInto
::<Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>>::lower_into(wc
, &self.interner
)).collect();
242 let value
= chalk_solve
::rust_ir
::ImplDatumBound
{
243 trait_ref
: trait_ref
.lower_into(&self.interner
),
247 Arc
::new(chalk_solve
::rust_ir
::ImplDatum
{
248 polarity
: chalk_solve
::rust_ir
::Polarity
::Positive
,
249 binders
: chalk_ir
::Binders
::new(binders
, value
),
250 impl_type
: chalk_solve
::rust_ir
::ImplType
::Local
,
251 associated_ty_value_ids
: vec
![],
257 trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
258 parameters
: &[chalk_ir
::GenericArg
<RustInterner
<'tcx
>>],
259 ) -> Vec
<chalk_ir
::ImplId
<RustInterner
<'tcx
>>> {
260 let def_id
= trait_id
.0;
262 // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will
263 // require us to be able to interconvert `Ty<'tcx>`, and we're
266 let all_impls
= self.tcx
.all_impls(def_id
);
267 let matched_impls
= all_impls
.filter(|impl_def_id
| {
268 use chalk_ir
::could_match
::CouldMatch
;
269 let trait_ref
= self.tcx
.impl_trait_ref(*impl_def_id
).unwrap();
270 let bound_vars
= bound_vars_for_item(self.tcx
, *impl_def_id
);
272 let self_ty
= trait_ref
.self_ty();
273 let self_ty
= self_ty
.subst(self.tcx
, bound_vars
);
274 let lowered_ty
= self_ty
.lower_into(&self.interner
);
276 parameters
[0].assert_ty_ref(&self.interner
).could_match(&self.interner
, &lowered_ty
)
279 let impls
= matched_impls
.map(chalk_ir
::ImplId
).collect();
283 fn impl_provided_for(
285 auto_trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
286 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
288 let trait_def_id
= auto_trait_id
.0;
289 let adt_def
= adt_id
.0;
290 let all_impls
= self.tcx
.all_impls(trait_def_id
);
291 for impl_def_id
in all_impls
{
292 let trait_ref
= self.tcx
.impl_trait_ref(impl_def_id
).unwrap();
293 let self_ty
= trait_ref
.self_ty();
295 ty
::Adt(impl_adt_def
, _
) => {
296 if impl_adt_def
== adt_def
{
306 fn associated_ty_value(
308 associated_ty_id
: chalk_solve
::rust_ir
::AssociatedTyValueId
<RustInterner
<'tcx
>>,
309 ) -> Arc
<chalk_solve
::rust_ir
::AssociatedTyValue
<RustInterner
<'tcx
>>> {
310 let def_id
= associated_ty_id
.0;
311 let assoc_item
= self.tcx
.associated_item(def_id
);
312 let impl_id
= match assoc_item
.container
{
313 AssocItemContainer
::TraitContainer(def_id
) => def_id
,
314 _
=> unimplemented
!("Not possible??"),
316 match assoc_item
.kind
{
317 AssocKind
::Type
=> {}
318 _
=> unimplemented
!("Not possible??"),
320 let bound_vars
= bound_vars_for_item(self.tcx
, def_id
);
321 let binders
= binders_for(&self.interner
, bound_vars
);
322 let ty
= self.tcx
.type_of(def_id
);
324 Arc
::new(chalk_solve
::rust_ir
::AssociatedTyValue
{
325 impl_id
: chalk_ir
::ImplId(impl_id
),
326 associated_ty_id
: chalk_ir
::AssocTypeId(def_id
),
327 value
: chalk_ir
::Binders
::new(
329 chalk_solve
::rust_ir
::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }
,
334 fn custom_clauses(&self) -> Vec
<chalk_ir
::ProgramClause
<RustInterner
<'tcx
>>> {
338 fn local_impls_to_coherence_check(
340 _trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
341 ) -> Vec
<chalk_ir
::ImplId
<RustInterner
<'tcx
>>> {
347 opaque_ty_id
: chalk_ir
::OpaqueTyId
<RustInterner
<'tcx
>>,
348 ) -> Arc
<chalk_solve
::rust_ir
::OpaqueTyDatum
<RustInterner
<'tcx
>>> {
349 let bound_vars
= bound_vars_for_item(self.tcx
, opaque_ty_id
.0);
350 let binders
= binders_for(&self.interner
, bound_vars
);
351 let predicates
= self.tcx
.predicates_defined_on(opaque_ty_id
.0).predicates
;
352 let where_clauses
: Vec
<_
> = predicates
354 .map(|(wc
, _
)| wc
.subst(self.tcx
, &bound_vars
))
355 .filter_map(|wc
| LowerInto
::<Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>>::lower_into(wc
, &self.interner
)).collect();
357 let value
= chalk_solve
::rust_ir
::OpaqueTyDatumBound
{
358 bounds
: chalk_ir
::Binders
::new(binders
, where_clauses
),
360 Arc
::new(chalk_solve
::rust_ir
::OpaqueTyDatum
{
362 bound
: chalk_ir
::Binders
::new(chalk_ir
::VariableKinds
::new(&self.interner
), value
),
366 /// Since Chalk can't handle all Rust types currently, we have to handle
367 /// some specially for now. Over time, these `Some` returns will change to
368 /// `None` and eventually this function will be removed.
371 well_known
: chalk_solve
::rust_ir
::WellKnownTrait
,
372 ty
: &chalk_ir
::TyData
<RustInterner
<'tcx
>>,
374 use chalk_ir
::TyData
::*;
376 chalk_solve
::rust_ir
::WellKnownTrait
::Sized
=> match ty
{
377 Apply(apply
) => match apply
.name
{
378 chalk_ir
::TypeName
::Adt(chalk_ir
::AdtId(adt_def
)) => match adt_def
.adt_kind() {
379 ty
::AdtKind
::Struct
| ty
::AdtKind
::Union
=> None
,
380 ty
::AdtKind
::Enum
=> {
381 let constraint
= self.tcx
.adt_sized_constraint(adt_def
.did
);
382 if !constraint
.0.is_empty
() { unimplemented!() }
else { Some(true) }
392 | BoundVar(_
) => None
,
394 chalk_solve
::rust_ir
::WellKnownTrait
::Copy
395 | chalk_solve
::rust_ir
::WellKnownTrait
::Clone
=> match ty
{
396 Apply(apply
) => match apply
.name
{
397 chalk_ir
::TypeName
::Adt(chalk_ir
::AdtId(adt_def
)) => match adt_def
.adt_kind() {
398 ty
::AdtKind
::Struct
| ty
::AdtKind
::Union
=> None
,
399 ty
::AdtKind
::Enum
=> {
400 let constraint
= self.tcx
.adt_sized_constraint(adt_def
.did
);
401 if !constraint
.0.is_empty
() { unimplemented!() }
else { Some(true) }
411 | BoundVar(_
) => None
,
413 chalk_solve
::rust_ir
::WellKnownTrait
::Drop
=> None
,
414 chalk_solve
::rust_ir
::WellKnownTrait
::Fn
=> None
,
415 chalk_solve
::rust_ir
::WellKnownTrait
::FnMut
=> None
,
416 chalk_solve
::rust_ir
::WellKnownTrait
::FnOnce
=> None
,
417 chalk_solve
::rust_ir
::WellKnownTrait
::Unsize
=> None
,
421 fn program_clauses_for_env(
423 environment
: &chalk_ir
::Environment
<RustInterner
<'tcx
>>,
424 ) -> chalk_ir
::ProgramClauses
<RustInterner
<'tcx
>> {
425 chalk_solve
::program_clauses_for_env(self, environment
)
428 fn well_known_trait_id(
430 well_known_trait
: chalk_solve
::rust_ir
::WellKnownTrait
,
431 ) -> Option
<chalk_ir
::TraitId
<RustInterner
<'tcx
>>> {
432 use chalk_solve
::rust_ir
::WellKnownTrait
::*;
433 let def_id
= match well_known_trait
{
434 Sized
=> self.tcx
.lang_items().sized_trait(),
435 Copy
=> self.tcx
.lang_items().copy_trait(),
436 Clone
=> self.tcx
.lang_items().clone_trait(),
437 Drop
=> self.tcx
.lang_items().drop_trait(),
438 Fn
=> self.tcx
.lang_items().fn_trait(),
439 FnMut
=> self.tcx
.lang_items().fn_mut_trait(),
440 FnOnce
=> self.tcx
.lang_items().fn_once_trait(),
441 Unsize
=> self.tcx
.lang_items().unsize_trait(),
443 def_id
.map(chalk_ir
::TraitId
)
446 fn is_object_safe(&self, trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>) -> bool
{
447 self.tcx
.is_object_safe(trait_id
.0)
450 fn hidden_opaque_type(
452 _id
: chalk_ir
::OpaqueTyId
<RustInterner
<'tcx
>>,
453 ) -> chalk_ir
::Ty
<RustInterner
<'tcx
>> {
454 // FIXME(chalk): actually get hidden ty
455 self.tcx
.mk_ty(ty
::Tuple(self.tcx
.intern_substs(&[]))).lower_into(&self.interner
)
460 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
461 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
462 ) -> chalk_solve
::rust_ir
::ClosureKind
{
463 let kind
= &substs
.parameters(&self.interner
)[substs
.len(&self.interner
) - 3];
464 match kind
.assert_ty_ref(&self.interner
).data(&self.interner
) {
465 chalk_ir
::TyData
::Apply(apply
) => match apply
.name
{
466 chalk_ir
::TypeName
::Scalar(scalar
) => match scalar
{
467 chalk_ir
::Scalar
::Int(int_ty
) => match int_ty
{
468 chalk_ir
::IntTy
::I8
=> chalk_solve
::rust_ir
::ClosureKind
::Fn
,
469 chalk_ir
::IntTy
::I16
=> chalk_solve
::rust_ir
::ClosureKind
::FnMut
,
470 chalk_ir
::IntTy
::I32
=> chalk_solve
::rust_ir
::ClosureKind
::FnOnce
,
471 _
=> bug
!("bad closure kind"),
473 _
=> bug
!("bad closure kind"),
475 _
=> bug
!("bad closure kind"),
477 _
=> bug
!("bad closure kind"),
481 fn closure_inputs_and_output(
483 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
484 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
485 ) -> chalk_ir
::Binders
<chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum
<RustInterner
<'tcx
>>>
487 let sig
= &substs
.parameters(&self.interner
)[substs
.len(&self.interner
) - 2];
488 match sig
.assert_ty_ref(&self.interner
).data(&self.interner
) {
489 chalk_ir
::TyData
::Function(f
) => {
490 let substitution
= f
.substitution
.parameters(&self.interner
);
492 substitution
.last().unwrap().assert_ty_ref(&self.interner
).clone();
493 // Closure arguments are tupled
494 let argument_tuple
= substitution
[0].assert_ty_ref(&self.interner
);
495 let argument_types
= match argument_tuple
.data(&self.interner
) {
496 chalk_ir
::TyData
::Apply(apply
) => match apply
.name
{
497 chalk_ir
::TypeName
::Tuple(_
) => apply
499 .iter(&self.interner
)
500 .map(|arg
| arg
.assert_ty_ref(&self.interner
))
503 _
=> bug
!("Expecting closure FnSig args to be tupled."),
505 _
=> bug
!("Expecting closure FnSig args to be tupled."),
508 chalk_ir
::Binders
::new(
509 chalk_ir
::VariableKinds
::from(
511 (0..f
.num_binders
).map(|_
| chalk_ir
::VariableKind
::Lifetime
),
513 chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum { argument_types, return_type }
,
516 _
=> panic
!("Invalid sig."),
522 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
523 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
524 ) -> chalk_ir
::Binders
<chalk_ir
::Ty
<RustInterner
<'tcx
>>> {
525 let inputs_and_output
= self.closure_inputs_and_output(_closure_id
, substs
);
526 let tuple
= substs
.parameters(&self.interner
).last().unwrap().assert_ty_ref(&self.interner
);
527 inputs_and_output
.map_ref(|_
| tuple
.clone())
530 fn closure_fn_substitution(
532 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
533 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
534 ) -> chalk_ir
::Substitution
<RustInterner
<'tcx
>> {
535 let substitution
= &substs
.parameters(&self.interner
)[0..substs
.len(&self.interner
) - 3];
536 chalk_ir
::Substitution
::from(&self.interner
, substitution
)
540 /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
541 /// var bound at index `0`. For types, we use a `BoundVar` index equal to
542 /// the type parameter index. For regions, we use the `BoundRegion::BrNamed`
543 /// variant (which has a `DefId`).
544 fn bound_vars_for_item(tcx
: TyCtxt
<'tcx
>, def_id
: DefId
) -> SubstsRef
<'tcx
> {
545 InternalSubsts
::for_item(tcx
, def_id
, |param
, substs
| match param
.kind
{
546 ty
::GenericParamDefKind
::Type { .. }
=> tcx
550 var
: ty
::BoundVar
::from(param
.index
),
551 kind
: ty
::BoundTyKind
::Param(param
.name
),
556 ty
::GenericParamDefKind
::Lifetime
=> tcx
557 .mk_region(ty
::RegionKind
::ReLateBound(
559 ty
::BoundRegion
::BrAnon(substs
.len() as u32),
563 ty
::GenericParamDefKind
::Const
=> tcx
564 .mk_const(ty
::Const
{
565 val
: ty
::ConstKind
::Bound(ty
::INNERMOST
, ty
::BoundVar
::from(param
.index
)),
566 ty
: tcx
.type_of(param
.def_id
),
572 fn binders_for
<'tcx
>(
573 interner
: &RustInterner
<'tcx
>,
574 bound_vars
: SubstsRef
<'tcx
>,
575 ) -> chalk_ir
::VariableKinds
<RustInterner
<'tcx
>> {
576 chalk_ir
::VariableKinds
::from(
578 bound_vars
.iter().map(|arg
| match arg
.unpack() {
579 ty
::subst
::GenericArgKind
::Lifetime(_re
) => chalk_ir
::VariableKind
::Lifetime
,
580 ty
::subst
::GenericArgKind
::Type(_ty
) => {
581 chalk_ir
::VariableKind
::Ty(chalk_ir
::TyKind
::General
)
583 ty
::subst
::GenericArgKind
::Const(c
) => {
584 chalk_ir
::VariableKind
::Const(c
.ty
.lower_into(interner
))