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