]> git.proxmox.com Git - rustc.git/blame - vendor/chalk-solve/src/clauses/builtin_traits/copy.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / vendor / chalk-solve / src / clauses / builtin_traits / copy.rs
CommitLineData
f9f354fc
XL
1use crate::clauses::builtin_traits::needs_impl_for_tys;
2use crate::clauses::ClauseBuilder;
3use crate::{Interner, RustIrDatabase, TraitRef};
5869c6ff 4use chalk_ir::{CanonicalVarKinds, Floundered, Substitution, TyKind, TyVariableKind, VariableKind};
f035d41b 5use std::iter;
3dfed10e 6use tracing::instrument;
f9f354fc
XL
7
8fn 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
34pub 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}