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
use crate::functions::follow_type::follow_type_id;
use crate::records::substitution::Substitution;
use crate::type_aliases::type_id::TypeId;
impl Substitution {
/// C++ `Substitution::foundDirty(TypeId)` (`Substitution.cpp:724-735`).
///
/// The `isDirty` / `clean` calls are virtual in C++ and dispatch into the
/// concrete subclass; here they go through the subclass-installed
/// [`SubstitutionVtable`](crate::records::tarjan::SubstitutionVtable). The
/// first `follow` is `log->follow`; the second is `Luau::follow` (the free
/// function `follow_type_id`).
pub fn found_dirty_type_id(&mut self, ty: TypeId) {
let ty = unsafe { (*self.base.log).follow_type_id(ty) };
if self.new_types.contains(&ty) {
return;
}
let owner = self.base.vtable.owner;
let is_dirty = self
.base
.vtable
.is_dirty_ty
.expect("Substitution::isDirty(TypeId) override not installed");
let new_ty = if is_dirty(owner, ty) {
let clean = self
.base
.vtable
.clean_ty
.expect("Substitution::clean(TypeId) override not installed");
let cleaned = clean(owner, ty);
unsafe { follow_type_id(cleaned) }
} else {
let cloned = self.clone_type_id(ty);
unsafe { follow_type_id(cloned) }
};
*self.new_types.get_or_insert(ty) = new_ty;
}
}