Skip to content

Conversation

@aviatesk
Copy link
Member

Currently our inference isn't able to propagate isa-based type constraint for cases like isa(Type{<:...}, DataType) since typeintersect may return Type object itself when taking Type object and iskindtype-object.

This case happens in the following kind of situation (motivated by the discussion at #46553 (comment)):

julia> function isa_kindtype(T::Type{<:AbstractVector})
           if isa(T, DataType)
               # `T` here should be inferred as `DataType` rather than `Type{<:AbstractVector}`
               return T.name.name # should be inferred as ::Symbol
           end
           return nothing
       end
isa_kindtype (generic function with 1 method)

julia> only(code_typed(isa_kindtype; optimize=false))
CodeInfo(
1%1 = (T isa Main.DataType)::Bool
└──      goto #3 if not %1
2%3 = Base.getproperty(T, :name)::Any%4 = Base.getproperty(%3, :name)::Any
└──      return %4
3return Main.nothing
) => Any

This commit improves the situation by adding a special casing for abstract interpretation, rather than changing the behavior of typeintersect.

@aviatesk aviatesk added the compiler:inference Type inference label Sep 12, 2022
@aviatesk aviatesk requested a review from vtjnash September 12, 2022 09:36
Currently our inference isn't able to propagate `isa`-based type
constraint for cases like `isa(Type{<:...}, DataType)` since
`typeintersect` may return `Type` object itself when taking `Type`
object and `iskindtype`-object.

This case happens in the following kind of situation (motivated by the
discussion at <#46553 (comment)>):
```julia
julia> function isa_kindtype(T::Type{<:AbstractVector})
           if isa(T, DataType)
               # `T` here should be inferred as `DataType` rather than `Type{<:AbstractVector}`
               return T.name.name # should be inferred as ::Symbol
           end
           return nothing
       end
isa_kindtype (generic function with 1 method)

julia> only(code_typed(isa_kindtype; optimize=false))
CodeInfo(
1 ─ %1 = (T isa Main.DataType)::Bool
└──      goto #3 if not %1
2 ─ %3 = Base.getproperty(T, :name)::Any
│   %4 = Base.getproperty(%3, :name)::Any
└──      return %4
3 ─      return Main.nothing
) => Any
```

This commit improves the situation by adding a special casing for
abstract interpretation, rather than changing the behavior of
`typeintersect`.
@aviatesk
Copy link
Member Author

Test failures looks unrelated.

@aviatesk aviatesk merged commit 0b38483 into master Sep 13, 2022
@aviatesk aviatesk deleted the avi/typetypeinf2 branch September 13, 2022 02:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler:inference Type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants