ptal / oak

A typed parser generator embedded in Rust code for Parsing Expression Grammars
Apache License 2.0
142 stars 14 forks source link

Type analysis of sum branches #39

Closed ptal closed 8 years ago

ptal commented 9 years ago

For example r1 / r2 in a typed context cannot be typed because we don't have name for the sum type. However r1 > make_r1 / r2 > make_r2 can be typed but the return types of make_r1 and make_r2 must be the same.

ptal commented 8 years ago

This is clearly harder than I first thought because we need to compare two syntax::ast::Ty which is not easy at all.

ptal commented 8 years ago

We completely removed this analysis due to #80 but it leads to awful errors. I want to re-introduce it, but contrarily to what is said in #73, we take the approach of considering any Rust type as equals and thus, only comparing Oak types.

pczarn commented 8 years ago

How about letting the Rust compiler compare types like this

fn _unused_fn_() {
    let mut same_type = make_r1(unreachable!());
    same_type = make_r2(unreachable!());
}

I suppose getting unclear error messages from the compiler will be bad, but the right solution is adding custom error messages to the compiler.

ptal commented 8 years ago

It's not a bad idea. However, how can you ensure that the Rust compiler will try this first, and if it fails, won't try the other rules and generate even more errors? It is an interesting hack and I need to think it over but for now, let's suppose two Rust types are equals and let the Rust compiler generate messages if they are not!

pczarn commented 8 years ago

and if it fails, won't try the other rules and generate even more errors?

Is that necessarily a bad things? Assuming it is bad, we can add the right attributes to the compiler that would ask it to produce truly fatal errors, in addition to setting custom error messages.

There's a problem with my exact example. Functions such as make_r1 can be generic, which means they can return ! given an argument of type !*. We would need to generate an expression with r1's type, which is fed to make_r1.

* The type of unreachable!() is !.