]> git.proxmox.com Git - rustc.git/blob - vendor/chalk-solve-0.55.0/src/clauses/builtin_traits.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / vendor / chalk-solve-0.55.0 / src / clauses / builtin_traits.rs
1 use super::{builder::ClauseBuilder, generalize};
2 use crate::{CanonicalVarKinds, Interner, RustIrDatabase, TraitRef, WellKnownTrait};
3 use chalk_ir::{Floundered, Substitution, Ty};
4
5 mod clone;
6 mod copy;
7 mod discriminant_kind;
8 mod fn_family;
9 mod sized;
10 mod unsize;
11
12 /// For well known traits we have special hard-coded impls, either as an
13 /// optimization or to enforce special rules for correctness.
14 pub fn add_builtin_program_clauses<I: Interner>(
15 db: &dyn RustIrDatabase<I>,
16 builder: &mut ClauseBuilder<'_, I>,
17 well_known: WellKnownTrait,
18 trait_ref: TraitRef<I>,
19 binders: &CanonicalVarKinds<I>,
20 ) -> Result<(), Floundered> {
21 // If `trait_ref` contains bound vars, we want to universally quantify them.
22 // `Generalize` collects them for us.
23 let generalized = generalize::Generalize::apply(db.interner(), trait_ref);
24
25 builder.push_binders(generalized, |builder, trait_ref| {
26 let self_ty = trait_ref.self_type_parameter(db.interner());
27 let ty = self_ty.kind(db.interner()).clone();
28
29 match well_known {
30 WellKnownTrait::Sized => {
31 sized::add_sized_program_clauses(db, builder, trait_ref, ty, binders)?;
32 }
33 WellKnownTrait::Copy => {
34 copy::add_copy_program_clauses(db, builder, trait_ref, ty, binders)?;
35 }
36 WellKnownTrait::Clone => {
37 clone::add_clone_program_clauses(db, builder, trait_ref, ty, binders)?;
38 }
39 WellKnownTrait::FnOnce | WellKnownTrait::FnMut | WellKnownTrait::Fn => {
40 fn_family::add_fn_trait_program_clauses(db, builder, well_known, self_ty)?
41 }
42 WellKnownTrait::Unsize => {
43 unsize::add_unsize_program_clauses(db, builder, trait_ref, ty)
44 }
45 // DiscriminantKind is automatically implemented for all types
46 WellKnownTrait::DiscriminantKind => builder.push_fact(trait_ref),
47 // There are no builtin impls provided for the following traits:
48 WellKnownTrait::Unpin | WellKnownTrait::Drop | WellKnownTrait::CoerceUnsized => (),
49 }
50 Ok(())
51 })
52 }
53
54 /// Like `add_builtin_program_clauses`, but for `DomainGoal::Normalize` involving
55 /// a projection (e.g. `<fn(u8) as FnOnce<(u8,)>>::Output`)
56 pub fn add_builtin_assoc_program_clauses<I: Interner>(
57 db: &dyn RustIrDatabase<I>,
58 builder: &mut ClauseBuilder<'_, I>,
59 well_known: WellKnownTrait,
60 self_ty: Ty<I>,
61 ) -> Result<(), Floundered> {
62 match well_known {
63 WellKnownTrait::FnOnce => {
64 // If `self_ty` contains bound vars, we want to universally quantify them.
65 // `Generalize` collects them for us.
66 let generalized = generalize::Generalize::apply(db.interner(), self_ty);
67
68 builder.push_binders(generalized, |builder, self_ty| {
69 fn_family::add_fn_trait_program_clauses(db, builder, well_known, self_ty)?;
70 Ok(())
71 })
72 }
73 WellKnownTrait::DiscriminantKind => {
74 discriminant_kind::add_discriminant_clauses(db, builder, self_ty)
75 }
76 _ => Ok(()),
77 }
78 }
79
80 /// Given a trait ref `T0: Trait` and a list of types `U0..Un`, pushes a clause of the form
81 /// `Implemented(T0: Trait) :- Implemented(U0: Trait) .. Implemented(Un: Trait)`
82 pub fn needs_impl_for_tys<I: Interner>(
83 db: &dyn RustIrDatabase<I>,
84 builder: &mut ClauseBuilder<'_, I>,
85 trait_ref: TraitRef<I>,
86 tys: impl Iterator<Item = Ty<I>>,
87 ) {
88 let trait_id = trait_ref.trait_id;
89
90 // The trait must take one parameter (a type)
91 debug_assert_eq!(db.trait_datum(trait_id).binders.len(db.interner()), 1,);
92 builder.push_clause(
93 trait_ref,
94 tys.map(|ty| TraitRef {
95 trait_id: trait_id,
96 substitution: Substitution::from1(db.interner(), ty),
97 }),
98 );
99 }