]> git.proxmox.com Git - rustc.git/blame - vendor/chalk-solve/src/clauses/builtin_traits/generator.rs
Update unsuspicious file list
[rustc.git] / vendor / chalk-solve / src / clauses / builtin_traits / generator.rs
CommitLineData
a2a8927a
XL
1use crate::clauses::ClauseBuilder;
2use crate::rust_ir::WellKnownTrait;
3use crate::{Interner, RustIrDatabase, TraitRef};
4use chalk_ir::cast::Cast;
5use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTy, Substitution, Ty, TyKind};
6
7/// Add implicit impls of the generator trait, i.e., add a clause that all generators implement
8/// `Generator` and clauses for `Generator`'s associated types.
9pub fn add_generator_program_clauses<I: Interner>(
10 db: &dyn RustIrDatabase<I>,
11 builder: &mut ClauseBuilder<'_, I>,
12 self_ty: Ty<I>,
13) -> Result<(), Floundered> {
14 let interner = db.interner();
15
16 match self_ty.kind(interner) {
17 TyKind::Generator(id, substitution) => {
18 let generator_datum = db.generator_datum(*id);
19 let generator_io_datum = generator_datum
20 .input_output
21 .clone()
22 .substitute(interner, &substitution);
23
24 let trait_id = db.well_known_trait_id(WellKnownTrait::Generator).unwrap();
25 let trait_datum = db.trait_datum(trait_id);
26 assert_eq!(
27 trait_datum.associated_ty_ids.len(),
28 2,
29 "Generator trait should have exactly two associated types, found {:?}",
30 trait_datum.associated_ty_ids
31 );
32
33 let substitution = Substitution::from_iter(
34 interner,
35 &[
36 self_ty.cast(interner),
37 generator_io_datum.resume_type.cast(interner),
38 ],
39 );
40
41 // generator: Generator<resume_type>
42 builder.push_fact(TraitRef {
43 trait_id,
44 substitution: substitution.clone(),
45 });
46
47 // `Generator::Yield`
48 let yield_id = trait_datum.associated_ty_ids[0];
49 let yield_alias = AliasTy::Projection(ProjectionTy {
50 associated_ty_id: yield_id,
51 substitution: substitution.clone(),
52 });
53 builder.push_fact(Normalize {
54 alias: yield_alias,
55 ty: generator_io_datum.yield_type,
56 });
57
58 // `Generator::Return`
59 let return_id = trait_datum.associated_ty_ids[1];
60 let return_alias = AliasTy::Projection(ProjectionTy {
61 associated_ty_id: return_id,
62 substitution,
63 });
64 builder.push_fact(Normalize {
65 alias: return_alias,
66 ty: generator_io_datum.return_type,
67 });
68
69 Ok(())
70 }
71
72 // Generator trait is non-enumerable
73 TyKind::InferenceVar(..) | TyKind::BoundVar(_) | TyKind::Alias(..) => Err(Floundered),
74 _ => Ok(()),
75 }
76}