1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
use crate::clauses::ClauseBuilder;
use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait};
use chalk_ir::{
AliasTy, Floundered, Normalize, ProjectionTy, Substitution, Ty, TyKind, TyVariableKind,
};
pub fn add_discriminant_clauses<I: Interner>(
db: &dyn RustIrDatabase<I>,
builder: &mut ClauseBuilder<'_, I>,
self_ty: Ty<I>,
) -> Result<(), Floundered> {
let interner = db.interner();
let can_determine_discriminant = match self_ty.data(interner).kind {
TyKind::Adt(..)
| TyKind::Array(..)
| TyKind::Tuple(..)
| TyKind::Slice(..)
| TyKind::Raw(..)
| TyKind::Ref(..)
| TyKind::Scalar(_)
| TyKind::Str
| TyKind::Never
| TyKind::FnDef(..)
| TyKind::Generator(..)
| TyKind::Closure(..)
| TyKind::GeneratorWitness(..)
| TyKind::Foreign(_)
| TyKind::Dyn(_)
| TyKind::Function(..)
| TyKind::InferenceVar(_, TyVariableKind::Integer)
| TyKind::InferenceVar(_, TyVariableKind::Float) => true,
TyKind::OpaqueType(..)
| TyKind::Alias(_)
| TyKind::BoundVar(_)
| TyKind::Placeholder(_)
| TyKind::AssociatedType(..)
| TyKind::Error
| TyKind::InferenceVar(..) => false,
};
if !can_determine_discriminant {
return Err(Floundered);
}
let disc_ty = db.discriminant_type(self_ty.clone());
let trait_id = db
.well_known_trait_id(WellKnownTrait::DiscriminantKind)
.unwrap();
let trait_datum = db.trait_datum(trait_id);
let associated_ty_id = trait_datum.associated_ty_ids[0];
let substitution = Substitution::from1(interner, self_ty);
let trait_ref = TraitRef {
trait_id,
substitution: substitution.clone(),
};
let normalize = Normalize {
alias: AliasTy::Projection(ProjectionTy {
associated_ty_id,
substitution,
}),
ty: disc_ty,
};
builder.push_fact(trait_ref);
builder.push_fact(normalize);
Ok(())
}
|