Eliminate dead code for clj-nil and types that don't admit falsey

Description

If the test of an if has a tag of clj-nil then the else branch will always be taken so we can replace such code with the else branch.

Likewise if the test of an if has a tag that cannot yield a falsey value (for example #{number string}), then the then branch will always be taken and we can replace such code with the then branch.

We already have dead code elimination for constants, this ticket asks that we extend it to cases where we can definitely determine a branch will be taken based on inferred types.

Environment

None

Activity

Show:
Mike Fikes
August 22, 2019, 9:30 PM
Mike Fikes
August 22, 2019, 9:59 PM
Edited

In Canary, Planck was one of the failures, but this can be reproduced directly in a plain Node REPL when CLJS-2875-3.patch is applied:

Mike Fikes
August 23, 2019, 1:14 AM
Edited

In Canary, a test in Coal Mine is one of the failures. It appears to be a consequence of an improperly inferred clj-nil type for a loop local (as a result of ) causing the optimization in this ticket to result in bad code gen. (In other words, not a defect in this patch.)

Mike Fikes
August 25, 2019, 2:35 PM
Edited

The ns-publics issue is related to the use of reify inside cljs.core/nil-iter's definition and incorrect type information being established: A Var is created, which is tagged as being of function type, when in fact the Var's value is nil. Then when the var special is applied to the Var's symbol, there is a bit of code that would normally conditionally include test meta in the generated Var:

https://github.com/clojure/clojurescript/blob/8f38049d543b04b8da55029f140b6577e3ec245a/src/main/clojure/cljs/analyzer.cljc#L1485

but, since the type tag on the Var is (incorrectly) function, the optimization in this ticket causes unconditional code to be generated, which derails when the cljs$lang$test field is extracted from the nil Var value.

A simple way to repro what is being describe above is to force a REPL, which would return a Var for a def, to fail to do so by tagging the Var with a type and then violating that type hint by initializing it with nil:

See CLJS-3160.

Assignee

Mike Fikes

Reporter

Mike Fikes

Labels

None

Approval

None

Patch

Code and Test

Priority

Major
Configure