gleam
gleam copied to clipboard
Do not exit analysis when a constant is invalid
Register an error and continue analysis of the rest of the module.
If the constant expression is invalid but it has a valid type annotation then we can register the constant into the environment using the type annotation to get the type.
If the constant expression is valid but the type annotation is invalid we can register the constant into the environment using the type inferred from the expression.
If both the constant expression and the type annotation are valid but disagree we can register the constant into the environment using the type annotation.
Split from https://github.com/gleam-lang/gleam/issues/2766
Questions
If a constant definition is invalid and it had no type annotation then it could produce a large number of error messages from the rest of the module as any place that references this type will get a "undefined value" error. Should we in keep track of there being a failed constant with this name and suppress unknown value error messages relating to it? I think it would be a nice experience to only see the root error.
I started looking into this tonight and wanted to write out some initial notes/details to get feedback.
- I started out by passing down the errors through all the infer functions/methods so that we can append errors more conveniently when we run into each one (lots of passing since inference is so recursive but straightforward overall)
- Handling valid constant expressions with invalid annotations is working as expected/described above
- For handling valid constant expressions with valid but not matching annotations, we have some difficulty if we try to use the annotation type instead of the inferred type. Since https://github.com/gleam-lang/gleam/blob/main/compiler-core/src/ast/constant.rs#L62-L68 the type for simple enum variants is static we can't override the type and maintain the value. It might make more sense for constants to keep the inferred type instead of the annotation one? Otherwise we'll need to rethink the type tagging to attach a tag to all the variants (definitely doable but wanna get your thoughts here)
- Still need to think about how to properly construct a constant to insert if the expression is invalid and the annotation is valid. For now I'm just using a Constant::Var with no name or module, which seems to be working ok but Idk if that would have further issues later
Since https://github.com/gleam-lang/gleam/blob/main/compiler-core/src/ast/constant.rs#L62-L68 the type for simple enum variants is static we can't override the type and maintain the value. It might make more sense for constants to keep the inferred type instead of the annotation one? Otherwise we'll need to rethink the type tagging to attach a tag to all the variants (definitely doable but wanna get your thoughts here)
I'm not following what you are saying here but I'm happy to go ahead with whatever you think is the best way to move forward as you have more context than I do. If there's some way we could improve it in future we can make an issue for that.
Still need to think about how to properly construct a constant to insert if the expression is invalid and the annotation is valid. For now I'm just using a Constant::Var with no name or module, which seems to be working ok but Idk if that would have further issues later
Sounds good as the constants should not be used as this point. Alternatively we could have some sort of variant to represent an invalid value and panic if it is ever seen in any post-analysis code.
Ultimately realized going with your suggestion for a new constant variant solved both problems since at that point we'd only need the type to be correct and not the value.
Thank you :D