1 use super::{builder::ClauseBuilder, generalize}
;
2 use crate::{CanonicalVarKinds, Interner, RustIrDatabase, TraitRef, WellKnownTrait}
;
3 use chalk_ir
::{Floundered, Substitution, Ty}
;
12 /// For well known traits we have special hard-coded impls, either as an
13 /// optimization or to enforce special rules for correctness.
14 pub fn add_builtin_program_clauses
<I
: Interner
>(
15 db
: &dyn RustIrDatabase
<I
>,
16 builder
: &mut ClauseBuilder
<'_
, I
>,
17 well_known
: WellKnownTrait
,
18 trait_ref
: TraitRef
<I
>,
19 binders
: &CanonicalVarKinds
<I
>,
20 ) -> Result
<(), Floundered
> {
21 // If `trait_ref` contains bound vars, we want to universally quantify them.
22 // `Generalize` collects them for us.
23 let generalized
= generalize
::Generalize
::apply(db
.interner(), trait_ref
);
25 builder
.push_binders(generalized
, |builder
, trait_ref
| {
26 let self_ty
= trait_ref
.self_type_parameter(db
.interner());
27 let ty
= self_ty
.kind(db
.interner()).clone();
30 WellKnownTrait
::Sized
=> {
31 sized
::add_sized_program_clauses(db
, builder
, trait_ref
, ty
, binders
)?
;
33 WellKnownTrait
::Copy
=> {
34 copy
::add_copy_program_clauses(db
, builder
, trait_ref
, ty
, binders
)?
;
36 WellKnownTrait
::Clone
=> {
37 clone
::add_clone_program_clauses(db
, builder
, trait_ref
, ty
, binders
)?
;
39 WellKnownTrait
::FnOnce
| WellKnownTrait
::FnMut
| WellKnownTrait
::Fn
=> {
40 fn_family
::add_fn_trait_program_clauses(db
, builder
, well_known
, self_ty
)?
42 WellKnownTrait
::Unsize
=> {
43 unsize
::add_unsize_program_clauses(db
, builder
, trait_ref
, ty
)
45 // DiscriminantKind is automatically implemented for all types
46 WellKnownTrait
::DiscriminantKind
=> builder
.push_fact(trait_ref
),
47 // There are no builtin impls provided for the following traits:
48 WellKnownTrait
::Unpin
| WellKnownTrait
::Drop
| WellKnownTrait
::CoerceUnsized
=> (),
54 /// Like `add_builtin_program_clauses`, but for `DomainGoal::Normalize` involving
55 /// a projection (e.g. `<fn(u8) as FnOnce<(u8,)>>::Output`)
56 pub fn add_builtin_assoc_program_clauses
<I
: Interner
>(
57 db
: &dyn RustIrDatabase
<I
>,
58 builder
: &mut ClauseBuilder
<'_
, I
>,
59 well_known
: WellKnownTrait
,
61 ) -> Result
<(), Floundered
> {
63 WellKnownTrait
::FnOnce
=> {
64 // If `self_ty` contains bound vars, we want to universally quantify them.
65 // `Generalize` collects them for us.
66 let generalized
= generalize
::Generalize
::apply(db
.interner(), self_ty
);
68 builder
.push_binders(generalized
, |builder
, self_ty
| {
69 fn_family
::add_fn_trait_program_clauses(db
, builder
, well_known
, self_ty
)?
;
73 WellKnownTrait
::DiscriminantKind
=> {
74 discriminant_kind
::add_discriminant_clauses(db
, builder
, self_ty
)
80 /// Given a trait ref `T0: Trait` and a list of types `U0..Un`, pushes a clause of the form
81 /// `Implemented(T0: Trait) :- Implemented(U0: Trait) .. Implemented(Un: Trait)`
82 pub fn needs_impl_for_tys
<I
: Interner
>(
83 db
: &dyn RustIrDatabase
<I
>,
84 builder
: &mut ClauseBuilder
<'_
, I
>,
85 trait_ref
: TraitRef
<I
>,
86 tys
: impl Iterator
<Item
= Ty
<I
>>,
88 let trait_id
= trait_ref
.trait_id
;
90 // The trait must take one parameter (a type)
91 debug_assert_eq
!(db
.trait_datum(trait_id
).binders
.len(db
.interner()), 1,);
94 tys
.map(|ty
| TraitRef
{
96 substitution
: Substitution
::from1(db
.interner(), ty
),