Skip to content
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

tfuncs: Be more robust in the face of uninhabited types #37945

Merged
merged 1 commit into from
Oct 19, 2020
Merged

Conversation

Keno
Copy link
Member

@Keno Keno commented Oct 8, 2020

Fixes #37943

@@ -853,6 +853,14 @@ function getfield_tfunc(@nospecialize(s00), @nospecialize(name))
if isa(name, Conditional)
return Bottom # can't index fields with Bool
end
for _ft in ftypes
if (!isa(_ft, Type) && !isa(_ft, TypeVar)) || _ft === Bottom
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about a type like this:

struct Foo
    x
    y::Union{}
    Foo(x) = new(x)
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or similarly this, but this case should possibly be disallowed on construction:

struct Bar{T}
    x
    y::T
    Bar{T}(x) where {T} = new(x)
end
Bar{false}(1)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that legal? I guess there's nothing technically wrong with it, but boy. I guess I'll add a check to only bail if it's one of the initialized fields.

Copy link
Member

@JeffBezanson JeffBezanson Oct 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one is definitely legal. The second one is currently allowed but probably shouldn't be, since a constructable type needs a layout, and if a field type is a non-type it's impossible to say what its layout is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also s.has_concrete_subtype which has already checked for conditions such as that?

It's not impossible to describe the layout, but impossible for that field to have a value. We could also treat it similar to apply_type failures, which returns the uninhabited type for the fieldtype and expand the check there (in inst_ftypes) instead of here:

julia> struct Bar{T}
           x
           y::Complex{T}
           Bar{T}(x) where {T} = new(x)
       end

julia> fieldtypes(Bar{false})
(Any, Union{})

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure I understand what you're saying. Are you saying we should do this check when we construct the datatype and set any bad type to Union{}, in which case the existing tfunc would go through fine?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there's no particular necessity in saying the field has type "false", when it's not even valid as a type

@Keno
Copy link
Member Author

Keno commented Oct 18, 2020

Updated as discussed.

@Keno Keno merged commit 8c11d3c into master Oct 19, 2020
@Keno Keno deleted the kf/37943 branch October 19, 2020 22:38
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.

Tfuncs error on invalid types
3 participants