]>
Commit | Line | Data |
---|---|---|
f9f354fc XL |
1 | use crate::clauses::builtin_traits::needs_impl_for_tys; |
2 | use crate::clauses::ClauseBuilder; | |
3 | use crate::{Interner, RustIrDatabase, TraitRef}; | |
3dfed10e XL |
4 | use chalk_ir::{ |
5 | ApplicationTy, CanonicalVarKinds, Substitution, TyData, TyKind, TypeName, VariableKind, | |
6 | }; | |
f035d41b | 7 | use std::iter; |
3dfed10e | 8 | use tracing::instrument; |
f9f354fc XL |
9 | |
10 | fn push_tuple_copy_conditions<I: Interner>( | |
11 | db: &dyn RustIrDatabase<I>, | |
12 | builder: &mut ClauseBuilder<'_, I>, | |
13 | trait_ref: &TraitRef<I>, | |
14 | arity: usize, | |
15 | substitution: &Substitution<I>, | |
16 | ) { | |
17 | // Empty tuples are always Copy | |
18 | if arity == 0 { | |
19 | builder.push_fact(trait_ref.clone()); | |
20 | return; | |
21 | } | |
22 | ||
23 | let interner = db.interner(); | |
24 | ||
25 | needs_impl_for_tys( | |
26 | db, | |
27 | builder, | |
28 | trait_ref, | |
29 | substitution | |
30 | .iter(interner) | |
f035d41b | 31 | .map(|param| param.assert_ty_ref(interner).clone()), |
f9f354fc XL |
32 | ); |
33 | } | |
34 | ||
3dfed10e | 35 | #[instrument(skip(db, builder))] |
f9f354fc XL |
36 | pub fn add_copy_program_clauses<I: Interner>( |
37 | db: &dyn RustIrDatabase<I>, | |
38 | builder: &mut ClauseBuilder<'_, I>, | |
39 | trait_ref: &TraitRef<I>, | |
40 | ty: &TyData<I>, | |
3dfed10e | 41 | binders: &CanonicalVarKinds<I>, |
f9f354fc | 42 | ) { |
f9f354fc XL |
43 | match ty { |
44 | TyData::Apply(ApplicationTy { name, substitution }) => match name { | |
45 | TypeName::Tuple(arity) => { | |
46 | push_tuple_copy_conditions(db, builder, trait_ref, *arity, substitution) | |
47 | } | |
f035d41b XL |
48 | TypeName::Array => { |
49 | let interner = db.interner(); | |
50 | needs_impl_for_tys( | |
51 | db, | |
52 | builder, | |
53 | trait_ref, | |
54 | iter::once(substitution.at(interner, 0).assert_ty_ref(interner).clone()), | |
55 | ); | |
56 | } | |
57 | TypeName::FnDef(_) => { | |
58 | builder.push_fact(trait_ref.clone()); | |
59 | } | |
60 | TypeName::Closure(closure_id) => { | |
61 | let closure_fn_substitution = db.closure_fn_substitution(*closure_id, substitution); | |
62 | let upvars = db.closure_upvars(*closure_id, substitution); | |
63 | let upvars = upvars.substitute(db.interner(), &closure_fn_substitution); | |
64 | needs_impl_for_tys(db, builder, trait_ref, Some(upvars).into_iter()); | |
65 | } | |
3dfed10e XL |
66 | |
67 | // these impls are in libcore | |
68 | TypeName::Ref(_) | |
69 | | TypeName::Raw(_) | |
70 | | TypeName::Scalar(_) | |
71 | | TypeName::Never | |
72 | | TypeName::Str => {} | |
73 | ||
74 | TypeName::Adt(_) | |
75 | | TypeName::AssociatedType(_) | |
76 | | TypeName::Slice | |
77 | | TypeName::OpaqueType(_) | |
1b1a35ee | 78 | | TypeName::Foreign(_) |
3dfed10e | 79 | | TypeName::Error => {} |
f9f354fc | 80 | }, |
3dfed10e | 81 | |
f9f354fc | 82 | TyData::Function(_) => builder.push_fact(trait_ref.clone()), |
3dfed10e XL |
83 | |
84 | TyData::InferenceVar(_, kind) => match kind { | |
85 | TyKind::Integer | TyKind::Float => builder.push_fact(trait_ref.clone()), | |
86 | TyKind::General => {} | |
87 | }, | |
88 | ||
89 | TyData::BoundVar(bound_var) => { | |
90 | let var_kind = &binders.at(db.interner(), bound_var.index).kind; | |
91 | match var_kind { | |
92 | VariableKind::Ty(TyKind::Integer) | VariableKind::Ty(TyKind::Float) => { | |
93 | builder.push_fact(trait_ref.clone()) | |
94 | } | |
95 | VariableKind::Ty(_) | VariableKind::Const(_) | VariableKind::Lifetime => {} | |
96 | } | |
97 | } | |
98 | ||
99 | TyData::Alias(_) | TyData::Dyn(_) | TyData::Placeholder(_) => {} | |
f9f354fc XL |
100 | }; |
101 | } |