diff options
Diffstat (limited to 'vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/copy.rs')
-rw-r--r-- | vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/copy.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/copy.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/copy.rs new file mode 100644 index 000000000..c0174b21e --- /dev/null +++ b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/copy.rs @@ -0,0 +1,99 @@ +use crate::clauses::builtin_traits::needs_impl_for_tys; +use crate::clauses::ClauseBuilder; +use crate::{Interner, RustIrDatabase, TraitRef}; +use chalk_ir::{CanonicalVarKinds, Floundered, Substitution, TyKind, TyVariableKind, VariableKind}; +use std::iter; +use tracing::instrument; + +fn push_tuple_copy_conditions<I: Interner>( + db: &dyn RustIrDatabase<I>, + builder: &mut ClauseBuilder<'_, I>, + trait_ref: TraitRef<I>, + arity: usize, + substitution: &Substitution<I>, +) { + // Empty tuples are always Copy + if arity == 0 { + builder.push_fact(trait_ref); + return; + } + + let interner = db.interner(); + + needs_impl_for_tys( + db, + builder, + trait_ref, + substitution + .iter(interner) + .map(|param| param.assert_ty_ref(interner).clone()), + ); +} + +#[instrument(skip(db, builder))] +pub fn add_copy_program_clauses<I: Interner>( + db: &dyn RustIrDatabase<I>, + builder: &mut ClauseBuilder<'_, I>, + trait_ref: TraitRef<I>, + ty: TyKind<I>, + binders: &CanonicalVarKinds<I>, +) -> Result<(), Floundered> { + match ty { + TyKind::Tuple(arity, ref substitution) => { + push_tuple_copy_conditions(db, builder, trait_ref, arity, substitution) + } + TyKind::Array(ty, _) => { + needs_impl_for_tys(db, builder, trait_ref, iter::once(ty)); + } + TyKind::FnDef(_, _) => { + builder.push_fact(trait_ref); + } + TyKind::Closure(closure_id, ref substitution) => { + let closure_fn_substitution = db.closure_fn_substitution(closure_id, substitution); + let upvars = db.closure_upvars(closure_id, substitution); + let upvars = upvars.substitute(db.interner(), &closure_fn_substitution); + needs_impl_for_tys(db, builder, trait_ref, Some(upvars).into_iter()); + } + + // these impls are in libcore + TyKind::Ref(_, _, _) + | TyKind::Raw(_, _) + | TyKind::Scalar(_) + | TyKind::Never + | TyKind::Str => {} + + TyKind::Adt(_, _) + | TyKind::AssociatedType(_, _) + | TyKind::Slice(_) + | TyKind::OpaqueType(_, _) + | TyKind::Foreign(_) + | TyKind::Generator(_, _) + | TyKind::GeneratorWitness(_, _) + | TyKind::Error => {} + + TyKind::Function(_) => builder.push_fact(trait_ref), + + TyKind::InferenceVar(_, TyVariableKind::Float) + | TyKind::InferenceVar(_, TyVariableKind::Integer) => builder.push_fact(trait_ref), + + TyKind::BoundVar(bound_var) => { + let var_kind = &binders.at(db.interner(), bound_var.index).kind; + match var_kind { + VariableKind::Ty(TyVariableKind::Integer) + | VariableKind::Ty(TyVariableKind::Float) => builder.push_fact(trait_ref), + + // Don't know enough + VariableKind::Ty(TyVariableKind::General) => return Err(Floundered), + + VariableKind::Const(_) | VariableKind::Lifetime => {} + } + } + + // Don't know enough + TyKind::InferenceVar(_, TyVariableKind::General) => return Err(Floundered), + + // These should be handled elsewhere + TyKind::Alias(_) | TyKind::Dyn(_) | TyKind::Placeholder(_) => {} + }; + Ok(()) +} |