-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Feature Request/Question: Lift the explicit type requirement in assertions for participation in CFA #45385
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
Comments
This rule exists so that the feature could be added without drastically impacting performance. Let's say you had some sequence of calls let x = `e`;
fn1(x);
fn2(x);
fn3(x);
fn4(x);
let m = x; // <- where all of Without the rule, we would have to compute types for all The worst-case scenario here could look something like declare function mut1(x: unknown): asserts x is (n: unknown) => asserts n is (m: unknown) => m is string;
function nightmare(a: unknown, b: unknown, c: unknown, n: unknown) {
mut1(a);
a(b);
b(c);
c(n);
const a = n;
} where the computation of |
TLDR: Got it, explicitness is the only way to avoid a negative impact on performance -- but explicitness can be achieved by a new less-annoying syntax too! -- for example Thanks a lot for the explanation! I'm convinced that it indeed is a hard problem to solve without impacting the performance, I did thought about this for a while and it's true that requiring an explicit annotation is the only solution that "gets it right". Although I think I have an improvement on that. So if I understand it correctly I think when you said "today there is only one step required -- compute the type of
Okay we saved ourselves from resolving types of But the problem here is it's too much of a requirement, if we want a marker for "this function might be making an assertion" one could introduce a syntax for it -- say So basically this... let aFoo = a.literal("foo") as assertion would be equivalent to writing this... let _aFoo = a.literal("foo")
let aFoo: typeof _aFoo = _aFoo And now the error would say "Assertions require call target to be annotated with 'as assertion' or every name in the call target to be declared with an explicit type annotation" Afaict this would not add much cost, in fact checking if a function asserts via "as assertion" would be faster than checking if all call targets are explicitly annotated (not sure tho maybe both would be just flags on the node) And if I were to make a critic: using explicit type annotation as a first pass for assertions is a bit cheating as both have no correlation as such, it took me a while to get that the ultimate goal is to have a first-pass that is cheap to check I think this is a pretty new feature and people aren't leveraging it like I'm doing -- I already found myself redeclaring 6 assertions and the project isn't even complete yet :P -- ultimately it just makes the complier look a little stupid, the explicitness requirement for a first-pass is very much valid, I totally get it, but it would be nice if there was a syntax to aid it. What are your thoughts? (Imagine if I got this all wrong hahaha xD) |
@RyanCavanaugh senpai wdyt? Also you haven't labelled it anything yet. |
I definitely want this, but since it's apparently too hard to do it, could this at least be a request for a "quick fix" that gives you some idea what you should be doing? #34596 (comment) |
Suggestion
π Search Terms
explicit type, assertion, CFA
β Viability Checklist
β Suggestion
As stated in #32695, functions using
asserts
require explicitly typed/annotated like so:The reason stated in the PR is "This particular rule exists so that control flow analysis of potential assertion calls doesn't circularly trigger further analysis."
My question is, umm, what does this mean in more layman terms? My impression was it's to not allow recursive usage but looks like that's not the case because this compiles... So not sure what the above statement means
Also I understand it's a "design limitation" but, excuse my ignorance, is it really that hard to lift it? Because it's quite annoying to make make two variables for the same function then annotated the other, makes me think "Eh why can't the compiler do this for itself" haha. Maybe lift the restriction in some scenarios?
π Motivating Example
π» Use Cases
I was writing a fail-fast parser that basically composes assertion functions something like this... But I have to use the mentioned workaround. Even if this is too much of a feature request, an explanation why the requirement exists would make me feel less annoyed when I redeclare and annotate assertions :P
Playground (Hit on run to see the
ParseError
with message"At Person.age: Expected a number"
)The text was updated successfully, but these errors were encountered: