]> git.proxmox.com Git - rustc.git/blob - vendor/chalk-solve-0.25.0/src/clauses/builtin_traits/copy.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / vendor / chalk-solve-0.25.0 / src / clauses / builtin_traits / copy.rs
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::{
5 ApplicationTy, CanonicalVarKinds, Substitution, TyData, TyKind, TypeName, VariableKind,
6 };
7 use std::iter;
8 use tracing::instrument;
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)
31 .map(|param| param.assert_ty_ref(interner).clone()),
32 );
33 }
34
35 #[instrument(skip(db, builder))]
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>,
41 binders: &CanonicalVarKinds<I>,
42 ) {
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 }
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 }
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(_)
78 | TypeName::Error => {}
79 },
80
81 TyData::Function(_) => builder.push_fact(trait_ref.clone()),
82
83 TyData::InferenceVar(_, kind) => match kind {
84 TyKind::Integer | TyKind::Float => builder.push_fact(trait_ref.clone()),
85 TyKind::General => {}
86 },
87
88 TyData::BoundVar(bound_var) => {
89 let var_kind = &binders.at(db.interner(), bound_var.index).kind;
90 match var_kind {
91 VariableKind::Ty(TyKind::Integer) | VariableKind::Ty(TyKind::Float) => {
92 builder.push_fact(trait_ref.clone())
93 }
94 VariableKind::Ty(_) | VariableKind::Const(_) | VariableKind::Lifetime => {}
95 }
96 }
97
98 TyData::Alias(_) | TyData::Dyn(_) | TyData::Placeholder(_) => {}
99 };
100 }