-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flatten typesets #677
Flatten typesets #677
Conversation
One issue is that this code does work, when it should not: type Nothing;
type NullableInt = 15 | Nothing;
func g(n: NullableInt) {}
where x = 16;
g(15);
g(x);
g(Nothing); and replacing |
Getting closer. Another testcase we must handle before merging this: type unit;
type bool;
type char;
type int;
type float;
type string;
func fifteen(inner: int) {}
where x = fifteen(14);
where y = fifteen(14 * 12); |
ext func magic() -> int;
type Nothing;
type NullableInt = int | Nothing;
func g(n: NullableInt) {}
g(magic()); |
One other issue is that we show type errors with the flattened version of the type, so for example it'll show as "expected 15 | 16, got string" |
There is an issue when formatting empty typesets, for example the |
the only blocker now is the handling of builtin types for arithmetic operations |
The issue with arithmetic builtins lie in the |
649c428
to
e9004f3
Compare
5394fd2
to
3804872
Compare
dedup/src/lib.rs
Outdated
) -> Result<Node<FlattenData<'ast>>, Error> { | ||
match data.ast { | ||
// if we're dealing with a floating point constant, then we can't deduplicate - equality rules | ||
// are not great around floats and we can't use them as literal types anyway (and for that reason) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So turns out we can actually use them as literal types right now :( hmmmm... maybe we could sidestep this and compare their string representation? We can probably do that for all types actually?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, their string representation probably isn't stored in our symbol table right now... so we'd have to generate it dynamically which sounds worse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running benchmarks show that storing a string in ast::Node::Constant
alongside the Value
(so turning the variant into Constant(Value, String)
) and making these strings during parsing, using &'ast str
as keys instead is just as fast as adding a new Float
variant to HashableValue
which stores the string representation of the float. Furthermore, this uses a tiny bit more memory, and makes the parser code heavier and harder to read IMO.
Benching code:
fn main() {
println!("type unit;");
println!("type bool;");
println!("type int;");
println!("type char;");
println!("type float;");
println!("type string;");
for i in 0..99 {
for _ in 0..100 {
println!("{{");
println!("where a{0}i = {0} + {0};", i);
println!("where a{0}f = {0}.{0} + {0}.{0};", i);
println!("}};");
}
}
}
Fixes #674