How to assert type after if-else


Suppose my code looks like this:

    if condition
        x = complicated_expression
        y = another_complicated_expression
        x = a_third_complicated_expression
        y = a fourth_complicated_expression

Suppose I know that x has type T and y has type U after this if-else block, but I suspect that the compiler may not be able to determine this. Therefore, I want to assert the types of x and y after then if-else block so that subsequent code that uses these variables can be properly specialized. What is the correct, idiomatic and performant way to make such an assertion? For example, what about

    x = x::T 
    y = y::U

at the end of the block? Do I actually need an assignment statement, or is the statement x::T a valid type assertion? Or is it better to put a declaration before the block?


The pattern you’ve shown,

x = x::T
y = y::U

is actually used in a number of places in Base. One random example is in inference. Thus I think it’s reasonable to use that pattern in your own code. At least if it’s good enough for the folks who write the type inference code, it’s good enough for me. :slight_smile:


I don’t think the assignment is needed in x = x::T as the part x::T is a type assertion and will throw an error. So there is no point in re-assining x to x. Have a look at the documentation

Alternatively, you can use a convert declaration local x::T which will work irrespective of where in the scope block it is. Both should help the compiler equally but have slightly different semantics.


x::T do not have the same parsing on 0.5.


One possible way to do it would be

if condition
    x = complicated_expression::T
    y = another_complicated_expression::U
    x = a_third_complicated_expression::T
    y = a fourth_complicated_expression::U

But you would need to be in a hard local scope to use x::T


What about

x = (condition ? complicated_expression : another_complicated_expression)::T
y = (condition ? a_third_complicated_expression :

If the compiler had difficulties with x and this is the only thing that prevents inference in y, you may be able to omit the ::U.