1 use crate::clauses
::builtin_traits
::needs_impl_for_tys
;
2 use crate::clauses
::ClauseBuilder
;
3 use crate::{Interner, RustIrDatabase, TraitRef}
;
4 use chalk_ir
::{CanonicalVarKinds, Floundered, Substitution, TyKind, TyVariableKind, VariableKind}
;
6 use tracing
::instrument
;
8 fn push_tuple_copy_conditions
<I
: Interner
>(
9 db
: &dyn RustIrDatabase
<I
>,
10 builder
: &mut ClauseBuilder
<'_
, I
>,
11 trait_ref
: TraitRef
<I
>,
13 substitution
: &Substitution
<I
>,
15 // Empty tuples are always Copy
17 builder
.push_fact(trait_ref
);
21 let interner
= db
.interner();
29 .map(|param
| param
.assert_ty_ref(interner
).clone()),
33 #[instrument(skip(db, builder))]
34 pub fn add_copy_program_clauses
<I
: Interner
>(
35 db
: &dyn RustIrDatabase
<I
>,
36 builder
: &mut ClauseBuilder
<'_
, I
>,
37 trait_ref
: TraitRef
<I
>,
39 binders
: &CanonicalVarKinds
<I
>,
40 ) -> Result
<(), Floundered
> {
42 TyKind
::Tuple(arity
, ref substitution
) => {
43 push_tuple_copy_conditions(db
, builder
, trait_ref
, arity
, substitution
)
45 TyKind
::Array(ty
, _
) => {
46 needs_impl_for_tys(db
, builder
, trait_ref
, iter
::once(ty
));
48 TyKind
::FnDef(_
, _
) => {
49 builder
.push_fact(trait_ref
);
51 TyKind
::Closure(closure_id
, ref substitution
) => {
52 let closure_fn_substitution
= db
.closure_fn_substitution(closure_id
, substitution
);
53 let upvars
= db
.closure_upvars(closure_id
, substitution
);
54 let upvars
= upvars
.substitute(db
.interner(), &closure_fn_substitution
);
55 needs_impl_for_tys(db
, builder
, trait_ref
, Some(upvars
).into_iter());
58 // these impls are in libcore
66 | TyKind
::AssociatedType(_
, _
)
68 | TyKind
::OpaqueType(_
, _
)
70 | TyKind
::Generator(_
, _
)
71 | TyKind
::GeneratorWitness(_
, _
)
74 TyKind
::Function(_
) => builder
.push_fact(trait_ref
),
76 TyKind
::InferenceVar(_
, TyVariableKind
::Float
)
77 | TyKind
::InferenceVar(_
, TyVariableKind
::Integer
) => builder
.push_fact(trait_ref
),
79 TyKind
::BoundVar(bound_var
) => {
80 let var_kind
= &binders
.at(db
.interner(), bound_var
.index
).kind
;
82 VariableKind
::Ty(TyVariableKind
::Integer
)
83 | VariableKind
::Ty(TyVariableKind
::Float
) => builder
.push_fact(trait_ref
),
86 VariableKind
::Ty(TyVariableKind
::General
) => return Err(Floundered
),
88 VariableKind
::Const(_
) | VariableKind
::Lifetime
=> {}
93 TyKind
::InferenceVar(_
, TyVariableKind
::General
) => return Err(Floundered
),
95 // These should be handled elsewhere
96 TyKind
::Alias(_
) | TyKind
::Dyn(_
) | TyKind
::Placeholder(_
) => {}