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
::{self, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}
;
11 use rustc_middle
::ty
::{InternalSubsts, SubstsRef}
;
14 use rustc_attr
as attr
;
16 use rustc_hir
::def_id
::DefId
;
18 use rustc_span
::symbol
::sym
;
23 use crate::chalk
::lowering
::LowerInto
;
25 pub struct RustIrDatabase
<'tcx
> {
26 pub(crate) interner
: RustInterner
<'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_defined_on(def_id
).predicates
;
44 .map(|(wc
, _
)| EarlyBinder(*wc
).subst(self.interner
.tcx
, bound_vars
))
45 .filter_map(|wc
| LowerInto
::<
46 Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>
47 >::lower_into(wc
, self.interner
)).collect()
50 fn bounds_for
<T
>(&self, def_id
: DefId
, bound_vars
: SubstsRef
<'tcx
>) -> Vec
<T
>
52 ty
::Predicate
<'tcx
>: LowerInto
<'tcx
, std
::option
::Option
<T
>>,
54 let bounds
= self.interner
.tcx
.bound_explicit_item_bounds(def_id
);
58 .map(|(bound
, _
)| bounds
.rebind(*bound
).subst(self.interner
.tcx
, &bound_vars
))
59 .filter_map(|bound
| LowerInto
::<Option
<_
>>::lower_into(bound
, self.interner
))
64 impl<'tcx
> chalk_solve
::RustIrDatabase
<RustInterner
<'tcx
>> for RustIrDatabase
<'tcx
> {
65 fn interner(&self) -> RustInterner
<'tcx
> {
69 fn associated_ty_data(
71 assoc_type_id
: chalk_ir
::AssocTypeId
<RustInterner
<'tcx
>>,
72 ) -> Arc
<chalk_solve
::rust_ir
::AssociatedTyDatum
<RustInterner
<'tcx
>>> {
73 let def_id
= assoc_type_id
.0;
74 let assoc_item
= self.interner
.tcx
.associated_item(def_id
);
75 let Some(trait_def_id
) = assoc_item
.trait_container(self.interner
.tcx
) else {
76 unimplemented
!("Not possible??");
78 match assoc_item
.kind
{
80 _
=> unimplemented
!("Not possible??"),
82 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
83 let binders
= binders_for(self.interner
, bound_vars
);
85 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
86 let bounds
= self.bounds_for(def_id
, bound_vars
);
88 Arc
::new(chalk_solve
::rust_ir
::AssociatedTyDatum
{
89 trait_id
: chalk_ir
::TraitId(trait_def_id
),
92 binders
: chalk_ir
::Binders
::new(
94 chalk_solve
::rust_ir
::AssociatedTyDatumBound { bounds, where_clauses }
,
101 trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
102 ) -> Arc
<chalk_solve
::rust_ir
::TraitDatum
<RustInterner
<'tcx
>>> {
103 use chalk_solve
::rust_ir
::WellKnownTrait
::*;
105 let def_id
= trait_id
.0;
106 let trait_def
= self.interner
.tcx
.trait_def(def_id
);
108 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
109 let binders
= binders_for(self.interner
, bound_vars
);
111 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
113 let associated_ty_ids
: Vec
<_
> = self
116 .associated_items(def_id
)
117 .in_definition_order()
118 .filter(|i
| i
.kind
== AssocKind
::Type
)
119 .map(|i
| chalk_ir
::AssocTypeId(i
.def_id
))
122 let lang_items
= self.interner
.tcx
.lang_items();
123 let well_known
= if lang_items
.sized_trait() == Some(def_id
) {
125 } else if lang_items
.copy_trait() == Some(def_id
) {
127 } else if lang_items
.clone_trait() == Some(def_id
) {
129 } else if lang_items
.drop_trait() == Some(def_id
) {
131 } else if lang_items
.fn_trait() == Some(def_id
) {
133 } else if lang_items
.fn_once_trait() == Some(def_id
) {
135 } else if lang_items
.fn_mut_trait() == Some(def_id
) {
137 } else if lang_items
.unsize_trait() == Some(def_id
) {
139 } else if lang_items
.unpin_trait() == Some(def_id
) {
141 } else if lang_items
.coerce_unsized_trait() == Some(def_id
) {
143 } else if lang_items
.dispatch_from_dyn_trait() == Some(def_id
) {
144 Some(DispatchFromDyn
)
148 Arc
::new(chalk_solve
::rust_ir
::TraitDatum
{
150 binders
: chalk_ir
::Binders
::new(
152 chalk_solve
::rust_ir
::TraitDatumBound { where_clauses }
,
154 flags
: chalk_solve
::rust_ir
::TraitFlags
{
155 auto: trait_def
.has_auto_impl
,
156 marker
: trait_def
.is_marker
,
157 upstream
: !def_id
.is_local(),
158 fundamental
: self.interner
.tcx
.has_attr(def_id
, sym
::fundamental
),
159 non_enumerable
: true,
169 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
170 ) -> Arc
<chalk_solve
::rust_ir
::AdtDatum
<RustInterner
<'tcx
>>> {
171 let adt_def
= adt_id
.0;
173 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, adt_def
.did());
174 let binders
= binders_for(self.interner
, bound_vars
);
176 let where_clauses
= self.where_clauses_for(adt_def
.did(), bound_vars
);
178 let variants
: Vec
<_
> = adt_def
181 .map(|variant
| chalk_solve
::rust_ir
::AdtVariantDatum
{
185 .map(|field
| field
.ty(self.interner
.tcx
, bound_vars
).lower_into(self.interner
))
189 Arc
::new(chalk_solve
::rust_ir
::AdtDatum
{
191 binders
: chalk_ir
::Binders
::new(
193 chalk_solve
::rust_ir
::AdtDatumBound { variants, where_clauses }
,
195 flags
: chalk_solve
::rust_ir
::AdtFlags
{
196 upstream
: !adt_def
.did().is_local(),
197 fundamental
: adt_def
.is_fundamental(),
198 phantom_data
: adt_def
.is_phantom_data(),
200 kind
: match adt_def
.adt_kind() {
201 ty
::AdtKind
::Struct
=> chalk_solve
::rust_ir
::AdtKind
::Struct
,
202 ty
::AdtKind
::Union
=> chalk_solve
::rust_ir
::AdtKind
::Union
,
203 ty
::AdtKind
::Enum
=> chalk_solve
::rust_ir
::AdtKind
::Enum
,
210 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
211 ) -> Arc
<chalk_solve
::rust_ir
::AdtRepr
<RustInterner
<'tcx
>>> {
212 let adt_def
= adt_id
.0;
213 let int
= |i
| chalk_ir
::TyKind
::Scalar(chalk_ir
::Scalar
::Int(i
)).intern(self.interner
);
214 let uint
= |i
| chalk_ir
::TyKind
::Scalar(chalk_ir
::Scalar
::Uint(i
)).intern(self.interner
);
215 Arc
::new(chalk_solve
::rust_ir
::AdtRepr
{
216 c
: adt_def
.repr().c(),
217 packed
: adt_def
.repr().packed(),
218 int
: adt_def
.repr().int
.map(|i
| match i
{
219 attr
::IntType
::SignedInt(ty
) => match ty
{
220 ast
::IntTy
::Isize
=> int(chalk_ir
::IntTy
::Isize
),
221 ast
::IntTy
::I8
=> int(chalk_ir
::IntTy
::I8
),
222 ast
::IntTy
::I16
=> int(chalk_ir
::IntTy
::I16
),
223 ast
::IntTy
::I32
=> int(chalk_ir
::IntTy
::I32
),
224 ast
::IntTy
::I64
=> int(chalk_ir
::IntTy
::I64
),
225 ast
::IntTy
::I128
=> int(chalk_ir
::IntTy
::I128
),
227 attr
::IntType
::UnsignedInt(ty
) => match ty
{
228 ast
::UintTy
::Usize
=> uint(chalk_ir
::UintTy
::Usize
),
229 ast
::UintTy
::U8
=> uint(chalk_ir
::UintTy
::U8
),
230 ast
::UintTy
::U16
=> uint(chalk_ir
::UintTy
::U16
),
231 ast
::UintTy
::U32
=> uint(chalk_ir
::UintTy
::U32
),
232 ast
::UintTy
::U64
=> uint(chalk_ir
::UintTy
::U64
),
233 ast
::UintTy
::U128
=> uint(chalk_ir
::UintTy
::U128
),
241 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
242 ) -> Arc
<chalk_solve
::rust_ir
::AdtSizeAlign
> {
243 let tcx
= self.interner
.tcx
;
244 let did
= adt_id
.0.did();
246 // Grab the ADT and the param we might need to calculate its layout
247 let param_env
= tcx
.param_env(did
);
248 let adt_ty
= tcx
.type_of(did
);
250 // The ADT is a 1-zst if it's a ZST and its alignment is 1.
251 // Mark the ADT as _not_ a 1-zst if there was a layout error.
252 let one_zst
= if let Ok(layout
) = tcx
.layout_of(param_env
.and(adt_ty
)) {
253 layout
.is_zst() && layout
.align
.abi
.bytes() == 1
258 Arc
::new(chalk_solve
::rust_ir
::AdtSizeAlign
::from_one_zst(one_zst
))
263 fn_def_id
: chalk_ir
::FnDefId
<RustInterner
<'tcx
>>,
264 ) -> Arc
<chalk_solve
::rust_ir
::FnDefDatum
<RustInterner
<'tcx
>>> {
265 let def_id
= fn_def_id
.0;
266 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
267 let binders
= binders_for(self.interner
, bound_vars
);
269 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
271 let sig
= self.interner
.tcx
.bound_fn_sig(def_id
);
272 let (inputs_and_output
, iobinders
, _
) = crate::chalk
::lowering
::collect_bound_vars(
275 sig
.map_bound(|s
| s
.inputs_and_output()).subst(self.interner
.tcx
, bound_vars
),
278 let argument_types
= inputs_and_output
[..inputs_and_output
.len() - 1]
280 .map(|t
| sig
.rebind(*t
).subst(self.interner
.tcx
, &bound_vars
).lower_into(self.interner
))
283 let return_type
= sig
284 .rebind(inputs_and_output
[inputs_and_output
.len() - 1])
285 .subst(self.interner
.tcx
, &bound_vars
)
286 .lower_into(self.interner
);
288 let bound
= chalk_solve
::rust_ir
::FnDefDatumBound
{
289 inputs_and_output
: chalk_ir
::Binders
::new(
291 chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum { argument_types, return_type }
,
295 Arc
::new(chalk_solve
::rust_ir
::FnDefDatum
{
297 sig
: sig
.0.lower_into(self.interner
),
298 binders
: chalk_ir
::Binders
::new(binders
, bound
),
304 impl_id
: chalk_ir
::ImplId
<RustInterner
<'tcx
>>,
305 ) -> Arc
<chalk_solve
::rust_ir
::ImplDatum
<RustInterner
<'tcx
>>> {
306 let def_id
= impl_id
.0;
307 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
308 let binders
= binders_for(self.interner
, bound_vars
);
310 let trait_ref
= self.interner
.tcx
.bound_impl_trait_ref(def_id
).expect("not an impl");
311 let trait_ref
= trait_ref
.subst(self.interner
.tcx
, bound_vars
);
313 let where_clauses
= self.where_clauses_for(def_id
, bound_vars
);
315 let value
= chalk_solve
::rust_ir
::ImplDatumBound
{
316 trait_ref
: trait_ref
.lower_into(self.interner
),
320 let associated_ty_value_ids
: Vec
<_
> = self
323 .associated_items(def_id
)
324 .in_definition_order()
325 .filter(|i
| i
.kind
== AssocKind
::Type
)
326 .map(|i
| chalk_solve
::rust_ir
::AssociatedTyValueId(i
.def_id
))
329 Arc
::new(chalk_solve
::rust_ir
::ImplDatum
{
330 polarity
: self.interner
.tcx
.impl_polarity(def_id
).lower_into(self.interner
),
331 binders
: chalk_ir
::Binders
::new(binders
, value
),
332 impl_type
: chalk_solve
::rust_ir
::ImplType
::Local
,
333 associated_ty_value_ids
,
339 trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
340 parameters
: &[chalk_ir
::GenericArg
<RustInterner
<'tcx
>>],
341 _binders
: &chalk_ir
::CanonicalVarKinds
<RustInterner
<'tcx
>>,
342 ) -> Vec
<chalk_ir
::ImplId
<RustInterner
<'tcx
>>> {
343 let def_id
= trait_id
.0;
345 // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will
346 // require us to be able to interconvert `Ty<'tcx>`, and we're
349 let all_impls
= self.interner
.tcx
.all_impls(def_id
);
350 let matched_impls
= all_impls
.filter(|impl_def_id
| {
351 use chalk_ir
::could_match
::CouldMatch
;
352 let trait_ref
= self.interner
.tcx
.bound_impl_trait_ref(*impl_def_id
).unwrap();
353 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, *impl_def_id
);
355 let self_ty
= trait_ref
.map_bound(|t
| t
.self_ty());
356 let self_ty
= self_ty
.subst(self.interner
.tcx
, bound_vars
);
357 let lowered_ty
= self_ty
.lower_into(self.interner
);
359 parameters
[0].assert_ty_ref(self.interner
).could_match(
361 self.unification_database(),
366 let impls
= matched_impls
.map(chalk_ir
::ImplId
).collect();
370 fn impl_provided_for(
372 auto_trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
373 chalk_ty
: &chalk_ir
::TyKind
<RustInterner
<'tcx
>>,
375 use chalk_ir
::Scalar
::*;
376 use chalk_ir
::TyKind
::*;
378 let trait_def_id
= auto_trait_id
.0;
379 let all_impls
= self.interner
.tcx
.all_impls(trait_def_id
);
380 for impl_def_id
in all_impls
{
381 let trait_ref
= self.interner
.tcx
.impl_trait_ref(impl_def_id
).unwrap();
382 let self_ty
= trait_ref
.self_ty();
383 let provides
= match (self_ty
.kind(), chalk_ty
) {
384 (&ty
::Adt(impl_adt_def
, ..), Adt(id
, ..)) => impl_adt_def
.did() == id
.0.did(),
385 (_
, AssociatedType(_ty_id
, ..)) => {
386 // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774
389 (ty
::Bool
, Scalar(Bool
)) => true,
390 (ty
::Char
, Scalar(Char
)) => true,
391 (ty
::Int(ty1
), Scalar(Int(ty2
))) => matches
!(
393 (ty
::IntTy
::Isize
, chalk_ir
::IntTy
::Isize
)
394 | (ty
::IntTy
::I8
, chalk_ir
::IntTy
::I8
)
395 | (ty
::IntTy
::I16
, chalk_ir
::IntTy
::I16
)
396 | (ty
::IntTy
::I32
, chalk_ir
::IntTy
::I32
)
397 | (ty
::IntTy
::I64
, chalk_ir
::IntTy
::I64
)
398 | (ty
::IntTy
::I128
, chalk_ir
::IntTy
::I128
)
400 (ty
::Uint(ty1
), Scalar(Uint(ty2
))) => matches
!(
402 (ty
::UintTy
::Usize
, chalk_ir
::UintTy
::Usize
)
403 | (ty
::UintTy
::U8
, chalk_ir
::UintTy
::U8
)
404 | (ty
::UintTy
::U16
, chalk_ir
::UintTy
::U16
)
405 | (ty
::UintTy
::U32
, chalk_ir
::UintTy
::U32
)
406 | (ty
::UintTy
::U64
, chalk_ir
::UintTy
::U64
)
407 | (ty
::UintTy
::U128
, chalk_ir
::UintTy
::U128
)
409 (ty
::Float(ty1
), Scalar(Float(ty2
))) => matches
!(
411 (ty
::FloatTy
::F32
, chalk_ir
::FloatTy
::F32
)
412 | (ty
::FloatTy
::F64
, chalk_ir
::FloatTy
::F64
)
414 (&ty
::Tuple(substs
), Tuple(len
, _
)) => substs
.len() == *len
,
415 (&ty
::Array(..), Array(..)) => true,
416 (&ty
::Slice(..), Slice(..)) => true,
417 (&ty
::RawPtr(type_and_mut
), Raw(mutability
, _
)) => {
418 match (type_and_mut
.mutbl
, mutability
) {
419 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Mut
) => true,
420 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Not
) => false,
421 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Mut
) => false,
422 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Not
) => true,
425 (&ty
::Ref(.., mutability1
), Ref(mutability2
, ..)) => {
426 match (mutability1
, mutability2
) {
427 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Mut
) => true,
428 (ast
::Mutability
::Mut
, chalk_ir
::Mutability
::Not
) => false,
429 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Mut
) => false,
430 (ast
::Mutability
::Not
, chalk_ir
::Mutability
::Not
) => true,
433 (&ty
::Opaque(def_id
, ..), OpaqueType(opaque_ty_id
, ..)) => def_id
== opaque_ty_id
.0,
434 (&ty
::FnDef(def_id
, ..), FnDef(fn_def_id
, ..)) => def_id
== fn_def_id
.0,
435 (&ty
::Str
, Str
) => true,
436 (&ty
::Never
, Never
) => true,
437 (&ty
::Closure(def_id
, ..), Closure(closure_id
, _
)) => def_id
== closure_id
.0,
438 (&ty
::Foreign(def_id
), Foreign(foreign_def_id
)) => def_id
== foreign_def_id
.0,
439 (&ty
::Error(..), Error
) => false,
449 fn associated_ty_value(
451 associated_ty_id
: chalk_solve
::rust_ir
::AssociatedTyValueId
<RustInterner
<'tcx
>>,
452 ) -> Arc
<chalk_solve
::rust_ir
::AssociatedTyValue
<RustInterner
<'tcx
>>> {
453 let def_id
= associated_ty_id
.0;
454 let assoc_item
= self.interner
.tcx
.associated_item(def_id
);
455 let impl_id
= assoc_item
.container_id(self.interner
.tcx
);
456 match assoc_item
.kind
{
457 AssocKind
::Type
=> {}
458 _
=> unimplemented
!("Not possible??"),
461 let trait_item_id
= assoc_item
.trait_item_def_id
.expect("assoc_ty with no trait version");
462 let bound_vars
= bound_vars_for_item(self.interner
.tcx
, def_id
);
463 let binders
= binders_for(self.interner
, bound_vars
);
467 .bound_type_of(def_id
)
468 .subst(self.interner
.tcx
, bound_vars
)
469 .lower_into(self.interner
);
471 Arc
::new(chalk_solve
::rust_ir
::AssociatedTyValue
{
472 impl_id
: chalk_ir
::ImplId(impl_id
),
473 associated_ty_id
: chalk_ir
::AssocTypeId(trait_item_id
),
474 value
: chalk_ir
::Binders
::new(
476 chalk_solve
::rust_ir
::AssociatedTyValueBound { ty }
,
481 fn custom_clauses(&self) -> Vec
<chalk_ir
::ProgramClause
<RustInterner
<'tcx
>>> {
485 fn local_impls_to_coherence_check(
487 _trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>,
488 ) -> Vec
<chalk_ir
::ImplId
<RustInterner
<'tcx
>>> {
494 opaque_ty_id
: chalk_ir
::OpaqueTyId
<RustInterner
<'tcx
>>,
495 ) -> Arc
<chalk_solve
::rust_ir
::OpaqueTyDatum
<RustInterner
<'tcx
>>> {
496 let bound_vars
= ty
::fold
::shift_vars(
498 bound_vars_for_item(self.interner
.tcx
, opaque_ty_id
.0),
501 let where_clauses
= self.where_clauses_for(opaque_ty_id
.0, bound_vars
);
503 let identity_substs
= InternalSubsts
::identity_for_item(self.interner
.tcx
, opaque_ty_id
.0);
505 let explicit_item_bounds
= self.interner
.tcx
.bound_explicit_item_bounds(opaque_ty_id
.0);
511 explicit_item_bounds
.rebind(*bound
).subst(self.interner
.tcx
, &bound_vars
)
514 bound
.fold_with(&mut ReplaceOpaqueTyFolder
{
515 tcx
: self.interner
.tcx
,
518 binder_index
: ty
::INNERMOST
,
521 .filter_map(|bound
| {
523 Option
<chalk_ir
::QuantifiedWhereClause
<RustInterner
<'tcx
>>>
524 >::lower_into(bound
, self.interner
)
528 // Binder for the bound variable representing the concrete impl Trait type.
529 let existential_binder
= chalk_ir
::VariableKinds
::from1(
531 chalk_ir
::VariableKind
::Ty(chalk_ir
::TyVariableKind
::General
),
534 let value
= chalk_solve
::rust_ir
::OpaqueTyDatumBound
{
535 bounds
: chalk_ir
::Binders
::new(existential_binder
.clone(), bounds
),
536 where_clauses
: chalk_ir
::Binders
::new(existential_binder
, where_clauses
),
539 let binders
= binders_for(self.interner
, bound_vars
);
540 Arc
::new(chalk_solve
::rust_ir
::OpaqueTyDatum
{
542 bound
: chalk_ir
::Binders
::new(binders
, value
),
546 fn program_clauses_for_env(
548 environment
: &chalk_ir
::Environment
<RustInterner
<'tcx
>>,
549 ) -> chalk_ir
::ProgramClauses
<RustInterner
<'tcx
>> {
550 chalk_solve
::program_clauses_for_env(self, environment
)
553 fn well_known_trait_id(
555 well_known_trait
: chalk_solve
::rust_ir
::WellKnownTrait
,
556 ) -> Option
<chalk_ir
::TraitId
<RustInterner
<'tcx
>>> {
557 use chalk_solve
::rust_ir
::WellKnownTrait
::*;
558 let lang_items
= self.interner
.tcx
.lang_items();
559 let def_id
= match well_known_trait
{
560 Sized
=> lang_items
.sized_trait(),
561 Copy
=> lang_items
.copy_trait(),
562 Clone
=> lang_items
.clone_trait(),
563 Drop
=> lang_items
.drop_trait(),
564 Fn
=> lang_items
.fn_trait(),
565 FnMut
=> lang_items
.fn_mut_trait(),
566 FnOnce
=> lang_items
.fn_once_trait(),
567 Generator
=> lang_items
.gen_trait(),
568 Unsize
=> lang_items
.unsize_trait(),
569 Unpin
=> lang_items
.unpin_trait(),
570 CoerceUnsized
=> lang_items
.coerce_unsized_trait(),
571 DiscriminantKind
=> lang_items
.discriminant_kind_trait(),
572 DispatchFromDyn
=> lang_items
.dispatch_from_dyn_trait(),
574 def_id
.map(chalk_ir
::TraitId
)
577 fn is_object_safe(&self, trait_id
: chalk_ir
::TraitId
<RustInterner
<'tcx
>>) -> bool
{
578 self.interner
.tcx
.is_object_safe(trait_id
.0)
581 fn hidden_opaque_type(
583 _id
: chalk_ir
::OpaqueTyId
<RustInterner
<'tcx
>>,
584 ) -> chalk_ir
::Ty
<RustInterner
<'tcx
>> {
585 // FIXME(chalk): actually get hidden ty
588 .mk_ty(ty
::Tuple(self.interner
.tcx
.intern_type_list(&[])))
589 .lower_into(self.interner
)
594 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
595 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
596 ) -> chalk_solve
::rust_ir
::ClosureKind
{
597 let kind
= &substs
.as_slice(self.interner
)[substs
.len(self.interner
) - 3];
598 match kind
.assert_ty_ref(self.interner
).kind(self.interner
) {
599 chalk_ir
::TyKind
::Scalar(chalk_ir
::Scalar
::Int(int_ty
)) => match int_ty
{
600 chalk_ir
::IntTy
::I8
=> chalk_solve
::rust_ir
::ClosureKind
::Fn
,
601 chalk_ir
::IntTy
::I16
=> chalk_solve
::rust_ir
::ClosureKind
::FnMut
,
602 chalk_ir
::IntTy
::I32
=> chalk_solve
::rust_ir
::ClosureKind
::FnOnce
,
603 _
=> bug
!("bad closure kind"),
605 _
=> bug
!("bad closure kind"),
609 fn closure_inputs_and_output(
611 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
612 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
613 ) -> chalk_ir
::Binders
<chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum
<RustInterner
<'tcx
>>>
615 let sig
= &substs
.as_slice(self.interner
)[substs
.len(self.interner
) - 2];
616 match sig
.assert_ty_ref(self.interner
).kind(self.interner
) {
617 chalk_ir
::TyKind
::Function(f
) => {
618 let substitution
= f
.substitution
.0.as_slice(self.interner
);
619 let return_type
= substitution
.last().unwrap().assert_ty_ref(self.interner
).clone();
620 // Closure arguments are tupled
621 let argument_tuple
= substitution
[0].assert_ty_ref(self.interner
);
622 let argument_types
= match argument_tuple
.kind(self.interner
) {
623 chalk_ir
::TyKind
::Tuple(_len
, substitution
) => substitution
625 .map(|arg
| arg
.assert_ty_ref(self.interner
))
628 _
=> bug
!("Expecting closure FnSig args to be tupled."),
631 chalk_ir
::Binders
::new(
632 chalk_ir
::VariableKinds
::from_iter(
634 (0..f
.num_binders
).map(|_
| chalk_ir
::VariableKind
::Lifetime
),
636 chalk_solve
::rust_ir
::FnDefInputsAndOutputDatum { argument_types, return_type }
,
639 _
=> panic
!("Invalid sig."),
645 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
646 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
647 ) -> chalk_ir
::Binders
<chalk_ir
::Ty
<RustInterner
<'tcx
>>> {
648 let inputs_and_output
= self.closure_inputs_and_output(_closure_id
, substs
);
649 let tuple
= substs
.as_slice(self.interner
).last().unwrap().assert_ty_ref(self.interner
);
650 inputs_and_output
.map_ref(|_
| tuple
.clone())
653 fn closure_fn_substitution(
655 _closure_id
: chalk_ir
::ClosureId
<RustInterner
<'tcx
>>,
656 substs
: &chalk_ir
::Substitution
<RustInterner
<'tcx
>>,
657 ) -> chalk_ir
::Substitution
<RustInterner
<'tcx
>> {
658 let substitution
= &substs
.as_slice(self.interner
)[0..substs
.len(self.interner
) - 3];
659 chalk_ir
::Substitution
::from_iter(self.interner
, substitution
)
664 _generator_id
: chalk_ir
::GeneratorId
<RustInterner
<'tcx
>>,
665 ) -> Arc
<chalk_solve
::rust_ir
::GeneratorDatum
<RustInterner
<'tcx
>>> {
669 fn generator_witness_datum(
671 _generator_id
: chalk_ir
::GeneratorId
<RustInterner
<'tcx
>>,
672 ) -> Arc
<chalk_solve
::rust_ir
::GeneratorWitnessDatum
<RustInterner
<'tcx
>>> {
676 fn unification_database(&self) -> &dyn chalk_ir
::UnificationDatabase
<RustInterner
<'tcx
>> {
680 fn discriminant_type(
682 _
: chalk_ir
::Ty
<RustInterner
<'tcx
>>,
683 ) -> chalk_ir
::Ty
<RustInterner
<'tcx
>> {
688 impl<'tcx
> chalk_ir
::UnificationDatabase
<RustInterner
<'tcx
>> for RustIrDatabase
<'tcx
> {
691 def_id
: chalk_ir
::FnDefId
<RustInterner
<'tcx
>>,
692 ) -> chalk_ir
::Variances
<RustInterner
<'tcx
>> {
693 let variances
= self.interner
.tcx
.variances_of(def_id
.0);
694 chalk_ir
::Variances
::from_iter(
696 variances
.iter().map(|v
| v
.lower_into(self.interner
)),
702 adt_id
: chalk_ir
::AdtId
<RustInterner
<'tcx
>>,
703 ) -> chalk_ir
::Variances
<RustInterner
<'tcx
>> {
704 let variances
= self.interner
.tcx
.variances_of(adt_id
.0.did());
705 chalk_ir
::Variances
::from_iter(
707 variances
.iter().map(|v
| v
.lower_into(self.interner
)),
712 /// Creates an `InternalSubsts` that maps each generic parameter to a higher-ranked
713 /// var bound at index `0`. For types, we use a `BoundVar` index equal to
714 /// the type parameter index. For regions, we use the `BoundRegionKind::BrNamed`
715 /// variant (which has a `DefId`).
716 fn bound_vars_for_item
<'tcx
>(tcx
: TyCtxt
<'tcx
>, def_id
: DefId
) -> SubstsRef
<'tcx
> {
717 InternalSubsts
::for_item(tcx
, def_id
, |param
, substs
| match param
.kind
{
718 ty
::GenericParamDefKind
::Type { .. }
=> tcx
722 var
: ty
::BoundVar
::from(param
.index
),
723 kind
: ty
::BoundTyKind
::Param(param
.name
),
728 ty
::GenericParamDefKind
::Lifetime
=> {
729 let br
= ty
::BoundRegion
{
730 var
: ty
::BoundVar
::from_usize(substs
.len()),
731 kind
: ty
::BrAnon(substs
.len() as u32),
733 tcx
.mk_region(ty
::ReLateBound(ty
::INNERMOST
, br
)).into()
736 ty
::GenericParamDefKind
::Const { .. }
=> tcx
737 .mk_const(ty
::ConstS
{
738 kind
: ty
::ConstKind
::Bound(ty
::INNERMOST
, ty
::BoundVar
::from(param
.index
)),
739 ty
: tcx
.type_of(param
.def_id
),
745 fn binders_for
<'tcx
>(
746 interner
: RustInterner
<'tcx
>,
747 bound_vars
: SubstsRef
<'tcx
>,
748 ) -> chalk_ir
::VariableKinds
<RustInterner
<'tcx
>> {
749 chalk_ir
::VariableKinds
::from_iter(
751 bound_vars
.iter().map(|arg
| match arg
.unpack() {
752 ty
::subst
::GenericArgKind
::Lifetime(_re
) => chalk_ir
::VariableKind
::Lifetime
,
753 ty
::subst
::GenericArgKind
::Type(_ty
) => {
754 chalk_ir
::VariableKind
::Ty(chalk_ir
::TyVariableKind
::General
)
756 ty
::subst
::GenericArgKind
::Const(c
) => {
757 chalk_ir
::VariableKind
::Const(c
.ty().lower_into(interner
))
763 struct ReplaceOpaqueTyFolder
<'tcx
> {
765 opaque_ty_id
: chalk_ir
::OpaqueTyId
<RustInterner
<'tcx
>>,
766 identity_substs
: SubstsRef
<'tcx
>,
767 binder_index
: ty
::DebruijnIndex
,
770 impl<'tcx
> ty
::TypeFolder
<'tcx
> for ReplaceOpaqueTyFolder
<'tcx
> {
771 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'tcx
> {
775 fn fold_binder
<T
: TypeFoldable
<'tcx
>>(
777 t
: ty
::Binder
<'tcx
, T
>,
778 ) -> ty
::Binder
<'tcx
, T
> {
779 self.binder_index
.shift_in(1);
780 let t
= t
.super_fold_with(self);
781 self.binder_index
.shift_out(1);
785 fn fold_ty(&mut self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
786 if let ty
::Opaque(def_id
, substs
) = *ty
.kind() {
787 if def_id
== self.opaque_ty_id
.0 && substs
== self.identity_substs
{
788 return self.tcx
.mk_ty(ty
::Bound(
790 ty
::BoundTy
::from(ty
::BoundVar
::from_u32(0)),