Skip to content
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

Merged
merged 30 commits into from
Sep 25, 2024
Merged

Flatten typesets #677

merged 30 commits into from
Sep 25, 2024

Conversation

CohenArthur
Copy link
Member

@CohenArthur CohenArthur commented Aug 29, 2024

Fixes #674

@CohenArthur CohenArthur marked this pull request as draft August 29, 2024 10:12
@CohenArthur
Copy link
Member Author

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 NullableInt's definition with a proper one (int | Nothing) causes the code to no longer work 🙃

@CohenArthur
Copy link
Member Author

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);

@CohenArthur
Copy link
Member Author

  • Add as a testcase:
ext func magic() -> int;

type Nothing;
type NullableInt = int | Nothing;

func g(n: NullableInt) {}

g(magic());

@CohenArthur
Copy link
Member Author

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"

@CohenArthur
Copy link
Member Author

There is an issue when formatting empty typesets, for example the char type if there are no characters in the program. this will be fixed once we address the formatting issues

@CohenArthur
Copy link
Member Author

the only blocker now is the handling of builtin types for arithmetic operations

@CohenArthur
Copy link
Member Author

The issue with arithmetic builtins lie in the expected_arithmetic_types function, where we need to do something a little smarter than recreate our union types.

CohenArthur added a commit that referenced this pull request Sep 13, 2024
@CohenArthur CohenArthur force-pushed the flatten-typesets branch 2 times, most recently from 5394fd2 to 3804872 Compare September 25, 2024 20:42
@CohenArthur CohenArthur marked this pull request as ready for review September 25, 2024 20:47
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)
Copy link
Member Author

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?

Copy link
Member Author

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

Copy link
Member Author

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!("}};");
        }
    }
}

@CohenArthur CohenArthur merged commit 526f964 into master Sep 25, 2024
9 checks passed
CohenArthur added a commit that referenced this pull request Sep 25, 2024
@CohenArthur CohenArthur deleted the flatten-typesets branch September 25, 2024 22:34
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.

Add typeset flattening
1 participant