Skip to content

Refactor error handling #294

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

Merged
merged 4 commits into from
Apr 26, 2019
Merged

Refactor error handling #294

merged 4 commits into from
Apr 26, 2019

Conversation

aykevl
Copy link
Member

@aykevl aykevl commented Apr 21, 2019

This PR refactors error handling. The primary motivation is to be able to show multiple compiler errors to the user at the same time. For example, if you have this code:

    c64 := complex(f32, 1.2)
    c64 += 2
    c64 *= 2
    c64 /= 2
    println(c64)

Before this PR, it would result in the following error because these operations have not yet been implemented on complex numbers:

testdata/float.go:56:2: todo: binop on complex number: +

After this change, it will show all the errors:

testdata/float.go:56:2: todo: binop on complex number: +
testdata/float.go:57:2: todo: binop on complex number: *
testdata/float.go:58:2: todo: binop on complex number: /

But the main part of this PR (the first 3 commits) is a huge refactor of large parts of the compiler to make error handling much easier. These changes may be controversial: they convert a few errors into panics. However, I think the simplicity in other parts of the compiler is worth it and perhaps a panic would be the best way to deal with it anyway: they happen when unknown types are used in the code and as far as I'm aware all Go types have at least a partial/stub implementation and new types get added very infrequently to Go (and would only need to be implemented by TinyGo after updating the x/tools/go/ssa dependency).

aykevl added 4 commits April 21, 2019 14:04
The LLVM library we use does not (yet) provide a llvm.Zero (like it
provides a llvm.Undef) so we have implemented our own. However, in
theory it might return an error in some cases.

No real-world errors have been seen in a while and errors would likely
indicate a serious compiler bug anyway (not an external error), so make
it panic instead of returning an error.
This commit replaces "unknown type" errors in getLLVMType with panics.

The main reason this is done is that it simplifies the code *a lot*.
Many `if err != nil` lines were there just because of type information.
Additionally, simply panicking is probably a better approach as the only
way this error can be produced is either with big new language features
or a serious compiler bug. Panicking is probably a better way to handle
this error anyway.
This commit adds getValue which gets a const, global, or result of a
local SSA expression and replaces (almost) all uses of parseExpr with
getValue. The only remaining use is in parseInstr, which makes sure an
instruction is only evaluated once.
Most of these errors are actually "todo" or "unimplemented" errors, so
the return type is known. This means that compilation can proceed (with
errors) even though the output will be incorrect. This is useful because
this way, all errors in a compilation unit can be shown together to the
user.
@aykevl aykevl force-pushed the refactor-error-handling branch from 4c1ce3c to ca1dd49 Compare April 21, 2019 14:40
@aykevl
Copy link
Member Author

aykevl commented Apr 22, 2019

I intend to refactor diagnostics even further in the future as part of #285, but this is a good starting point.

@aykevl aykevl requested a review from deadprogram April 25, 2019 18:23
@deadprogram
Copy link
Member

Took a little while to look over all this code. I agree with the philosophy and also agree that this is a really useful change. There is no way for "unknown types to used in the code" in Go, so that is indeed a moot point when it comes to TinyGo.

Now merging.

@deadprogram deadprogram merged commit d155e31 into dev Apr 26, 2019
@deadprogram deadprogram deleted the refactor-error-handling branch April 26, 2019 09:17
aykevl added a commit that referenced this pull request May 13, 2019
No error is produced, so no error needs to be returned. It was missed in
#294.
@aykevl aykevl mentioned this pull request May 13, 2019
aykevl added a commit that referenced this pull request May 13, 2019
No error is produced, so no error needs to be returned. It was missed in
#294.

Also, it fixes this smelly code:

    if err != nil {
        return <something>, nil
    }

There could never be an error, so the code was already dead.
aykevl added a commit that referenced this pull request May 13, 2019
No error is produced, so no error needs to be returned. It was missed in
#294.

Also, it fixes this smelly code:

    if err != nil {
        return <something>, nil
    }

There could never be an error, so the code was already dead.
deadprogram pushed a commit that referenced this pull request May 14, 2019
No error is produced, so no error needs to be returned. It was missed in
#294.

Also, it fixes this smelly code:

    if err != nil {
        return <something>, nil
    }

There could never be an error, so the code was already dead.
torntrousers pushed a commit to HarringayMakerSpace/tinygo that referenced this pull request May 18, 2019
No error is produced, so no error needs to be returned. It was missed in
tinygo-org#294.

Also, it fixes this smelly code:

    if err != nil {
        return <something>, nil
    }

There could never be an error, so the code was already dead.
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.

2 participants