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, TypeFoldable}
;
13 use rustc_hir
::def_id
::DefId
;
15 use rustc_span
::symbol
::sym
;
20 use crate::chalk
::lowering
::{self, LowerInto}
;
23 pub struct RustIrDatabase
<'tcx
> {
24 pub(crate) interner
: RustInterner
<'tcx
>,
25 pub(crate) restatic_placeholder
: ty
::Region
<'tcx
>,
26 pub(crate) reempty_placeholder
: ty
::Region
<'tcx
>,
29 impl fmt
::Debug
for RustIrDatabase
<'_
> {
30 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
31 write
!(f
, "RustIrDatabase")
35 impl<'tcx
> RustIrDatabase
<'tcx
> {
39 bound_vars
: SubstsRef
<'tcx
>,
40 ) -> Vec
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>> {
41 let predicates
= self.interner
.tcx
.predicates_of(def_id
).predicates
;
42 let mut regions_substitutor
= lowering
::RegionsSubstitutor
::new(
44 self.restatic_placeholder
,
45 self.reempty_placeholder
,
49 .map(|(wc
, _
)| wc
.subst(self.interner
.tcx
, bound_vars
))
50 .map(|wc
| wc
.fold_with(&mut regions_substitutor
))
51 .filter_map(|wc
| LowerInto
::<Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>>::lower_into(wc
, &self.interner
)).collect()
55 impl<'tcx
> chalk_solve
::RustIrDatabase
<RustInterner
<'tcx
>> for RustIrDatabase
<'tcx
> {
56 fn interner(&self) -> &RustInterner
<'tcx
> {
60 fn associated_ty_data(
62 assoc_type_id
: chalk_ir
::AssocTypeId
<RustInterner
<'tcx
>>,
63 ) -> Arc
<chalk_solve
::rust_ir
::AssociatedTyDatum
<RustInterner
<'tcx
>>> {
64 let def_id
= assoc_type_id
.0;
65 let assoc_item
= self.interner
.tcx
.associated_item(def_id
);
66 let trait_def_id
= match assoc_item
.container
{
67 AssocItemContainer
::TraitContainer(def_id
) => def_id
,
68 _
=> unimplemented
!("Not possible??"),
70 match assoc_item
.kind
{
72 _
=> unimplemented
!("Not possible??"),
74 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
75 let binders
= binders_for(&self.interner
, bound_vars
);
76 // FIXME(chalk): this really isn't right I don't think. The functions
77 // for GATs are a bit hard to figure out. Are these supposed to be where
79 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
81 Arc
::new(chalk_solve
::rust_ir
::AssociatedTyDatum
{
82 trait_id
: chalk_ir
::TraitId(trait_def_id
),
85 binders
: chalk_ir
::Binders
::new(
87 chalk_solve
::rust_ir
::AssociatedTyDatumBound { bounds: vec![], where_clauses }
,
94 trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
95 ) -> Arc
<chalk_solve
::rust_ir
::TraitDatum
<RustInterner
<'tcx
>>> {
96 let def_id
= trait_id
.0;
97 let trait_def
= self.interner
.tcx
.trait_def(def_id
);
99 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
100 let binders
= binders_for(&self.interner
, bound_vars
);
102 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
104 let associated_ty_ids
: Vec
<_
> = self
107 .associated_items(def_id
)
108 .in_definition_order()
109 .filter(|i
| i
.kind
== AssocKind
::Type
)
110 .map(|i
| chalk_ir
::AssocTypeId(i
.def_id
))
113 let well_known
= if self.interner
.tcx
.lang_items().sized_trait() == Some(def_id
) {
114 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Sized
)
115 } else if self.interner
.tcx
.lang_items().copy_trait() == Some(def_id
) {
116 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Copy
)
117 } else if self.interner
.tcx
.lang_items().clone_trait() == Some(def_id
) {
118 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Clone
)
119 } else if self.interner
.tcx
.lang_items().drop_trait() == Some(def_id
) {
120 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Drop
)
121 } else if self.interner
.tcx
.lang_items().fn_trait() == Some(def_id
) {
122 Some(chalk_solve
::rust_ir
::WellKnownTrait
::Fn
)
128 .map(|t
| def_id
== t
)
131 Some(chalk_solve
::rust_ir
::WellKnownTrait
::FnOnce
)
137 .map(|t
| def_id
== t
)
140 Some(chalk_solve
::rust_ir
::WellKnownTrait
::FnMut
)
144 Arc
::new(chalk_solve
::rust_ir
::TraitDatum
{
146 binders
: chalk_ir
::Binders
::new(
148 chalk_solve
::rust_ir
::TraitDatumBound { where_clauses }
,
150 flags
: chalk_solve
::rust_ir
::TraitFlags
{
151 auto: trait_def
.has_auto_impl
,
152 marker
: trait_def
.is_marker
,
153 upstream
: !def_id
.is_local(),
154 fundamental
: self.interner
.tcx
.has_attr(def_id
, sym
::fundamental
),
155 non_enumerable
: true,
165 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
166 ) -> Arc
<chalk_solve
::rust_ir
::AdtDatum
<RustInterner
<'tcx
>>> {
167 let adt_def
= adt_id
.0;
169 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, adt_def
.did
);
170 let binders
= binders_for(&self.interner
, bound_vars
);
172 let where_clauses
= self.where_clauses_for(adt_def
.did
, bound_vars
);
174 let variants
: Vec
<_
> = adt_def
177 .map(|variant
| chalk_solve
::rust_ir
::AdtVariantDatum
{
181 .map(|field
| field
.ty(self.interner
.tcx
, bound_vars
).lower_into(&self.interner
))
185 Arc
::new(chalk_solve
::rust_ir
::AdtDatum
{
187 binders
: chalk_ir
::Binders
::new(
189 chalk_solve
::rust_ir
::AdtDatumBound { variants, where_clauses }
,
191 flags
: chalk_solve
::rust_ir
::AdtFlags
{
192 upstream
: !adt_def
.did
.is_local(),
193 fundamental
: adt_def
.is_fundamental(),
194 phantom_data
: adt_def
.is_phantom_data(),
196 kind
: match adt_def
.adt_kind() {
197 ty
::AdtKind
::Struct
=> chalk_solve
::rust_ir
::AdtKind
::Struct
,
198 ty
::AdtKind
::Union
=> chalk_solve
::rust_ir
::AdtKind
::Union
,
199 ty
::AdtKind
::Enum
=> chalk_solve
::rust_ir
::AdtKind
::Enum
,
206 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
207 ) -> chalk_solve
::rust_ir
::AdtRepr
{
208 let adt_def
= adt_id
.0;
209 chalk_solve
::rust_ir
::AdtRepr
{
210 repr_c
: adt_def
.repr
.c(),
211 repr_packed
: adt_def
.repr
.packed(),
217 fn_def_id
: chalk_ir
::FnDefId
<RustInterner
<'tcx
>>,
218 ) -> Arc
<chalk_solve
::rust_ir
::FnDefDatum
<RustInterner
<'tcx
>>> {
219 let def_id
= fn_def_id
.0;
220 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
221 let binders
= binders_for(&self.interner
, bound_vars
);
223 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
225 let sig
= self.interner
.tcx
.fn_sig(def_id
);
226 let (inputs_and_output
, iobinders
, _
) = crate::chalk
::lowering
::collect_bound_vars(
229 &sig
.inputs_and_output().subst(self.interner
.tcx
, bound_vars
),
232 let argument_types
= inputs_and_output
[..inputs_and_output
.len() - 1]
234 .map(|t
| t
.subst(self.interner
.tcx
, &bound_vars
).lower_into(&self.interner
))
237 let return_type
= inputs_and_output
[inputs_and_output
.len() - 1]
238 .subst(self.interner
.tcx
, &bound_vars
)
239 .lower_into(&self.interner
);
241 let bound
= chalk_solve
::rust_ir
::FnDefDatumBound
{
242 inputs_and_output
: chalk_ir
::Binders
::new(
244 chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum { argument_types, return_type }
,
248 Arc
::new(chalk_solve
::rust_ir
::FnDefDatum
{
250 sig
: sig
.lower_into(&self.interner
),
251 binders
: chalk_ir
::Binders
::new(binders
, bound
),
257 impl_id
: chalk_ir
::ImplId
<RustInterner
<'tcx
>>,
258 ) -> Arc
<chalk_solve
::rust_ir
::ImplDatum
<RustInterner
<'tcx
>>> {
259 let def_id
= impl_id
.0;
260 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
261 let binders
= binders_for(&self.interner
, bound_vars
);
263 let trait_ref
= self.interner
.tcx
.impl_trait_ref(def_id
).expect("not an impl");
264 let trait_ref
= trait_ref
.subst(self.interner
.tcx
, bound_vars
);
265 let mut regions_substitutor
= lowering
::RegionsSubstitutor
::new(
267 self.restatic_placeholder
,
268 self.reempty_placeholder
,
270 let trait_ref
= trait_ref
.fold_with(&mut regions_substitutor
);
272 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
274 let value
= chalk_solve
::rust_ir
::ImplDatumBound
{
275 trait_ref
: trait_ref
.lower_into(&self.interner
),
279 Arc
::new(chalk_solve
::rust_ir
::ImplDatum
{
280 polarity
: chalk_solve
::rust_ir
::Polarity
::Positive
,
281 binders
: chalk_ir
::Binders
::new(binders
, value
),
282 impl_type
: chalk_solve
::rust_ir
::ImplType
::Local
,
283 associated_ty_value_ids
: vec
![],
289 trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
290 parameters
: &[chalk_ir
::GenericArg
<RustInterner
<'tcx
>>],
291 _binders
: &chalk_ir
::CanonicalVarKinds
<RustInterner
<'tcx
>>,
292 ) -> Vec
<chalk_ir
::ImplId
<RustInterner
<'tcx
>>> {
293 let def_id
= trait_id
.0;
295 // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will
296 // require us to be able to interconvert `Ty<'tcx>`, and we're
299 let all_impls
= self.interner
.tcx
.all_impls(def_id
);
300 let matched_impls
= all_impls
.filter(|impl_def_id
| {
301 use chalk_ir
::could_match
::CouldMatch
;
302 let trait_ref
= self.interner
.tcx
.impl_trait_ref(*impl_def_id
).unwrap();
303 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, *impl_def_id
);
305 let self_ty
= trait_ref
.self_ty();
306 let self_ty
= self_ty
.subst(self.interner
.tcx
, bound_vars
);
307 let mut regions_substitutor
= lowering
::RegionsSubstitutor
::new(
309 self.restatic_placeholder
,
310 self.reempty_placeholder
,
312 let self_ty
= self_ty
.fold_with(&mut regions_substitutor
);
313 let lowered_ty
= self_ty
.lower_into(&self.interner
);
315 parameters
[0].assert_ty_ref(&self.interner
).could_match(&self.interner
, &lowered_ty
)
318 let impls
= matched_impls
.map(chalk_ir
::ImplId
).collect();
322 fn impl_provided_for(
324 auto_trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
325 app_ty
: &chalk_ir
::ApplicationTy
<RustInterner
<'tcx
>>,
327 use chalk_ir
::Scalar
::*;
328 use chalk_ir
::TypeName
::*;
330 let trait_def_id
= auto_trait_id
.0;
331 let all_impls
= self.interner
.tcx
.all_impls(trait_def_id
);
332 for impl_def_id
in all_impls
{
333 let trait_ref
= self.interner
.tcx
.impl_trait_ref(impl_def_id
).unwrap();
334 let self_ty
= trait_ref
.self_ty();
335 let provides
= match (self_ty
.kind(), app_ty
.name
) {
336 (&ty
::Adt(impl_adt_def
, ..), Adt(id
)) => impl_adt_def
.did
== id
.0.did
,
337 (_
, AssociatedType(_ty_id
)) => {
338 // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774
341 (ty
::Bool
, Scalar(Bool
)) => true,
342 (ty
::Char
, Scalar(Char
)) => true,
343 (ty
::Int(ty1
), Scalar(Int(ty2
))) => match (ty1
, ty2
) {
344 (ast
::IntTy
::Isize
, chalk_ir
::IntTy
::Isize
)
345 | (ast
::IntTy
::I8
, chalk_ir
::IntTy
::I8
)
346 | (ast
::IntTy
::I16
, chalk_ir
::IntTy
::I16
)
347 | (ast
::IntTy
::I32
, chalk_ir
::IntTy
::I32
)
348 | (ast
::IntTy
::I64
, chalk_ir
::IntTy
::I64
)
349 | (ast
::IntTy
::I128
, chalk_ir
::IntTy
::I128
) => true,
352 (ty
::Uint(ty1
), Scalar(Uint(ty2
))) => match (ty1
, ty2
) {
353 (ast
::UintTy
::Usize
, chalk_ir
::UintTy
::Usize
)
354 | (ast
::UintTy
::U8
, chalk_ir
::UintTy
::U8
)
355 | (ast
::UintTy
::U16
, chalk_ir
::UintTy
::U16
)
356 | (ast
::UintTy
::U32
, chalk_ir
::UintTy
::U32
)
357 | (ast
::UintTy
::U64
, chalk_ir
::UintTy
::U64
)
358 | (ast
::UintTy
::U128
, chalk_ir
::UintTy
::U128
) => true,
361 (ty
::Float(ty1
), Scalar(Float(ty2
))) => match (ty1
, ty2
) {
362 (ast
::FloatTy
::F32
, chalk_ir
::FloatTy
::F32
)
363 | (ast
::FloatTy
::F64
, chalk_ir
::FloatTy
::F64
) => true,
366 (&ty
::Tuple(..), Tuple(..)) => true,
367 (&ty
::Array(..), Array
) => true,
368 (&ty
::Slice(..), Slice
) => true,
369 (&ty
::RawPtr(type_and_mut
), Raw(mutability
)) => {
370 match (type_and_mut
.mutbl
, mutability
) {
371 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Mut
) => true,
372 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Not
) => false,
373 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Mut
) => false,
374 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Not
) => true,
377 (&ty
::Ref(.., mutability1
), Ref(mutability2
)) => match (mutability1
, mutability2
) {
378 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Mut
) => true,
379 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Not
) => false,
380 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Mut
) => false,
381 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Not
) => true,
383 (&ty
::Opaque(def_id
, ..), OpaqueType(opaque_ty_id
)) => def_id
== opaque_ty_id
.0,
384 (&ty
::FnDef(def_id
, ..), FnDef(fn_def_id
)) => def_id
== fn_def_id
.0,
385 (&ty
::Str
, Str
) => true,
386 (&ty
::Never
, Never
) => true,
387 (&ty
::Closure(def_id
, ..), Closure(closure_id
)) => def_id
== closure_id
.0,
388 (&ty
::Foreign(def_id
), Foreign(foreign_def_id
)) => def_id
== foreign_def_id
.0,
389 (&ty
::Error(..), Error
) => false,
399 fn associated_ty_value(
401 associated_ty_id
: chalk_solve
::rust_ir
::AssociatedTyValueId
<RustInterner
<'tcx
>>,
402 ) -> Arc
<chalk_solve
::rust_ir
::AssociatedTyValue
<RustInterner
<'tcx
>>> {
403 let def_id
= associated_ty_id
.0;
404 let assoc_item
= self.interner
.tcx
.associated_item(def_id
);
405 let impl_id
= match assoc_item
.container
{
406 AssocItemContainer
::TraitContainer(def_id
) => def_id
,
407 _
=> unimplemented
!("Not possible??"),
409 match assoc_item
.kind
{
410 AssocKind
::Type
=> {}
411 _
=> unimplemented
!("Not possible??"),
413 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
414 let binders
= binders_for(&self.interner
, bound_vars
);
415 let ty
= self.interner
.tcx
.type_of(def_id
);
417 Arc
::new(chalk_solve
::rust_ir
::AssociatedTyValue
{
418 impl_id
: chalk_ir
::ImplId(impl_id
),
419 associated_ty_id
: chalk_ir
::AssocTypeId(def_id
),
420 value
: chalk_ir
::Binders
::new(
422 chalk_solve
::rust_ir
::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }
,
427 fn custom_clauses(&self) -> Vec
<chalk_ir
::ProgramClause
<RustInterner
<'tcx
>>> {
431 fn local_impls_to_coherence_check(
433 _trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
434 ) -> Vec
<chalk_ir
::ImplId
<RustInterner
<'tcx
>>> {
440 opaque_ty_id
: chalk_ir
::OpaqueTyId
<RustInterner
<'tcx
>>,
441 ) -> Arc
<chalk_solve
::rust_ir
::OpaqueTyDatum
<RustInterner
<'tcx
>>> {
442 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, opaque_ty_id
.0);
443 let binders
= binders_for(&self.interner
, bound_vars
);
444 let where_clauses
= self.where_clauses_for(opaque_ty_id
.0, bound_vars
);
446 let value
= chalk_solve
::rust_ir
::OpaqueTyDatumBound
{
447 bounds
: chalk_ir
::Binders
::new(binders
.clone(), vec
![]),
448 where_clauses
: chalk_ir
::Binders
::new(binders
, where_clauses
),
450 Arc
::new(chalk_solve
::rust_ir
::OpaqueTyDatum
{
452 bound
: chalk_ir
::Binders
::empty(&self.interner
, value
),
456 fn program_clauses_for_env(
458 environment
: &chalk_ir
::Environment
<RustInterner
<'tcx
>>,
459 ) -> chalk_ir
::ProgramClauses
<RustInterner
<'tcx
>> {
460 chalk_solve
::program_clauses_for_env(self, environment
)
463 fn well_known_trait_id(
465 well_known_trait
: chalk_solve
::rust_ir
::WellKnownTrait
,
466 ) -> Option
<chalk_ir
::TraitId
<RustInterner
<'tcx
>>> {
467 use chalk_solve
::rust_ir
::WellKnownTrait
::*;
468 let lang_items
= self.interner
.tcx
.lang_items();
469 let def_id
= match well_known_trait
{
470 Sized
=> lang_items
.sized_trait(),
471 Copy
=> lang_items
.copy_trait(),
472 Clone
=> lang_items
.clone_trait(),
473 Drop
=> lang_items
.drop_trait(),
474 Fn
=> lang_items
.fn_trait(),
475 FnMut
=> lang_items
.fn_mut_trait(),
476 FnOnce
=> lang_items
.fn_once_trait(),
477 Unsize
=> lang_items
.unsize_trait(),
478 Unpin
=> lang_items
.unpin_trait(),
479 CoerceUnsized
=> lang_items
.coerce_unsized_trait(),
481 def_id
.map(chalk_ir
::TraitId
)
484 fn is_object_safe(&self, trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>) -> bool
{
485 self.interner
.tcx
.is_object_safe(trait_id
.0)
488 fn hidden_opaque_type(
490 _id
: chalk_ir
::OpaqueTyId
<RustInterner
<'tcx
>>,
491 ) -> chalk_ir
::Ty
<RustInterner
<'tcx
>> {
492 // FIXME(chalk): actually get hidden ty
495 .mk_ty(ty
::Tuple(self.interner
.tcx
.intern_substs(&[])))
496 .lower_into(&self.interner
)
501 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
502 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
503 ) -> chalk_solve
::rust_ir
::ClosureKind
{
504 let kind
= &substs
.as_slice(&self.interner
)[substs
.len(&self.interner
) - 3];
505 match kind
.assert_ty_ref(&self.interner
).data(&self.interner
) {
506 chalk_ir
::TyData
::Apply(apply
) => match apply
.name
{
507 chalk_ir
::TypeName
::Scalar(scalar
) => match scalar
{
508 chalk_ir
::Scalar
::Int(int_ty
) => match int_ty
{
509 chalk_ir
::IntTy
::I8
=> chalk_solve
::rust_ir
::ClosureKind
::Fn
,
510 chalk_ir
::IntTy
::I16
=> chalk_solve
::rust_ir
::ClosureKind
::FnMut
,
511 chalk_ir
::IntTy
::I32
=> chalk_solve
::rust_ir
::ClosureKind
::FnOnce
,
512 _
=> bug
!("bad closure kind"),
514 _
=> bug
!("bad closure kind"),
516 _
=> bug
!("bad closure kind"),
518 _
=> bug
!("bad closure kind"),
522 fn closure_inputs_and_output(
524 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
525 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
526 ) -> chalk_ir
::Binders
<chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum
<RustInterner
<'tcx
>>>
528 let sig
= &substs
.as_slice(&self.interner
)[substs
.len(&self.interner
) - 2];
529 match sig
.assert_ty_ref(&self.interner
).data(&self.interner
) {
530 chalk_ir
::TyData
::Function(f
) => {
531 let substitution
= f
.substitution
.as_slice(&self.interner
);
533 substitution
.last().unwrap().assert_ty_ref(&self.interner
).clone();
534 // Closure arguments are tupled
535 let argument_tuple
= substitution
[0].assert_ty_ref(&self.interner
);
536 let argument_types
= match argument_tuple
.data(&self.interner
) {
537 chalk_ir
::TyData
::Apply(apply
) => match apply
.name
{
538 chalk_ir
::TypeName
::Tuple(_
) => apply
540 .iter(&self.interner
)
541 .map(|arg
| arg
.assert_ty_ref(&self.interner
))
544 _
=> bug
!("Expecting closure FnSig args to be tupled."),
546 _
=> bug
!("Expecting closure FnSig args to be tupled."),
549 chalk_ir
::Binders
::new(
550 chalk_ir
::VariableKinds
::from_iter(
552 (0..f
.num_binders
).map(|_
| chalk_ir
::VariableKind
::Lifetime
),
554 chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum { argument_types, return_type }
,
557 _
=> panic
!("Invalid sig."),
563 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
564 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
565 ) -> chalk_ir
::Binders
<chalk_ir
::Ty
<RustInterner
<'tcx
>>> {
566 let inputs_and_output
= self.closure_inputs_and_output(_closure_id
, substs
);
567 let tuple
= substs
.as_slice(&self.interner
).last().unwrap().assert_ty_ref(&self.interner
);
568 inputs_and_output
.map_ref(|_
| tuple
.clone())
571 fn closure_fn_substitution(
573 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
574 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
575 ) -> chalk_ir
::Substitution
<RustInterner
<'tcx
>> {
576 let substitution
= &substs
.as_slice(&self.interner
)[0..substs
.len(&self.interner
) - 3];
577 chalk_ir
::Substitution
::from_iter(&self.interner
, substitution
)
581 /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
582 /// var bound at index `0`. For types, we use a `BoundVar` index equal to
583 /// the type parameter index. For regions, we use the `BoundRegion::BrNamed`
584 /// variant (which has a `DefId`).
585 fn bound_vars_for_item(tcx
: TyCtxt
<'tcx
>, def_id
: DefId
) -> SubstsRef
<'tcx
> {
586 InternalSubsts
::for_item(tcx
, def_id
, |param
, substs
| match param
.kind
{
587 ty
::GenericParamDefKind
::Type { .. }
=> tcx
591 var
: ty
::BoundVar
::from(param
.index
),
592 kind
: ty
::BoundTyKind
::Param(param
.name
),
597 ty
::GenericParamDefKind
::Lifetime
=> tcx
598 .mk_region(ty
::RegionKind
::ReLateBound(
600 ty
::BoundRegion
::BrAnon(substs
.len() as u32),
604 ty
::GenericParamDefKind
::Const
=> tcx
605 .mk_const(ty
::Const
{
606 val
: ty
::ConstKind
::Bound(ty
::INNERMOST
, ty
::BoundVar
::from(param
.index
)),
607 ty
: tcx
.type_of(param
.def_id
),
613 fn binders_for
<'tcx
>(
614 interner
: &RustInterner
<'tcx
>,
615 bound_vars
: SubstsRef
<'tcx
>,
616 ) -> chalk_ir
::VariableKinds
<RustInterner
<'tcx
>> {
617 chalk_ir
::VariableKinds
::from_iter(
619 bound_vars
.iter().map(|arg
| match arg
.unpack() {
620 ty
::subst
::GenericArgKind
::Lifetime(_re
) => chalk_ir
::VariableKind
::Lifetime
,
621 ty
::subst
::GenericArgKind
::Type(_ty
) => {
622 chalk_ir
::VariableKind
::Ty(chalk_ir
::TyKind
::General
)
624 ty
::subst
::GenericArgKind
::Const(c
) => {
625 chalk_ir
::VariableKind
::Const(c
.ty
.lower_into(interner
))