-
-
Notifications
You must be signed in to change notification settings - Fork 670
Change assertion failure to unreachable statement #1205
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
Change assertion failure to unreachable statement #1205
Conversation
@dcodeIO any issues with this? |
src/compiler.ts
Outdated
@@ -7915,7 +7915,9 @@ export class Compiler extends DiagnosticEmitter { | |||
return module.unreachable(); | |||
} | |||
let globalType = global.type; | |||
assert(globalType != Type.void); | |||
if(globalType == Type.void) { |
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.
Missing a whitespace here, and wondering if the fix should instead make compileGlobal
above return false
. Might have unforeseen consequences.
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.
It shouldn't compile regardless- since a global resolving into a void is already an error:
if (resolvedType == Type.void) {
this.error(
DiagnosticCode.Type_expected,
typeNode.range
);
return false;
}
Given that, this is really just a question of what gets displayed when it does fail. I suppose the worst case here is that there is some edge case where this will append additional errors which don't make sense to the error which the dev needs to see, but that doesn't seem like huge problem.
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.
I agree that this requires a fix, just questioning the chosen location. If compileGlobal
would return false
if it failed to compile that same global earlier already, which gives us an unreachable
as well, this would be much clearer than checking for Type.void
.
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.
compileGlobal does in fact return false for the first statement- and that false was being ignored by compileTopLevelStatement. If I move the unreachable call there it will also work:
if (!this.compileGlobal(<Global>element)) this.module.unreachable();
Most other calls to compileGlobal do the same, checking its result and then returning unreachable if it failed. Is this what you mean?
For this to work however I'd still need to delete the globalType != void assertion, otherwise none of these errors will ever print.
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.
Most other calls to compileGlobal do the same, checking its result and then returning unreachable if it failed. Is this what you mean?
Yeah, plus that it currently seems that only the first call to compileGlobal
for the same global returns false
if compilation fails currently, while subsequent calls see that it is already CommonFlags.COMPILED
and return true
. I think we should fix that, instead of adding checks for Type.void
that are only necessary due to a more general problem.
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.
Updated to move the unreachable call- looking into a more general fix as well
Updated such that we don't return true on the second call to compileGlobal- the issue now is that if you do anything self referential: |
|
What if we keep the compileGlobal(global: Global): bool {
if (global.is(CommonFlags.COMPILED)) return !this.failedGlobals.has(global);
// whenever returning `false`, also add to `failedGlobals` |
Issue: #1165
Right now if you have a global which fails to resolve its own type, and is also used in another constant, you get an assertion failure which prevents any errors from being printed to the console.
This PR just returns unreachable instead of panicking, allowing error messages to be printed.
Example:
Before: AssertionFailure with stack trace
After:
I don't think I need to add an error to the line where the assertion fails- there's not much useful information here since they didn't set their type to void, it's really just an internal thing. AFAIK there's no way to make this global void without causing another error, so the dev should always get enough information to fix the bug