Skip to content

Conversation

@osa1
Copy link
Member

@osa1 osa1 commented Nov 22, 2025

This starts type checking expressions.


It seems like the module envs are not quite right currently. Variables that refer to global things point to their definitions after the name resolving pass, so the module envs only need schemes, tycons etc. of things that they define, without the imported things. If I have a variable use foo of type use Foo, regardless of how these are defined or imported I get a reference to the definition (defining module + name in the defining module).

We should also document why we persist the name resolving state in Program: we want to reuse the state of the modules that don't change.

I'm also unsure why in the converted constructor field types we use a tree map instead of hash map:

#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub enum FunArgs {
Positional(Vec<Ty>),
Named(TreeMap<Id, Ty>),
}

This is because these are used in Fun types (i.e. in Ty), and we sort predicates of schemes when comparing two schemes for equality:

fir/src/type_checker/ty.rs

Lines 398 to 406 in 6c15469

let mut left_preds: Vec<Pred> = self.preds.to_vec();
left_preds.sort();
let mut right_preds: Vec<Pred> = other.preds.to_vec();
right_preds.sort();
if left_preds.len() != right_preds.len() {
return false;
}

We do this comparison when comparing an impl method scheme with the trait's method scheme.

We should be able to just check for each predicate on the left each predicate on the right (quadratic), because the number of predicates will always be tiny (less than 5 for most applications, definitely less than 10 in general).

@osa1 osa1 marked this pull request as draft November 22, 2025 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants