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