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

Inference regression in julia 1.7 #43296

Closed
jw3126 opened this issue Dec 2, 2021 · 9 comments · Fixed by #50694
Closed

Inference regression in julia 1.7 #43296

jw3126 opened this issue Dec 2, 2021 · 9 comments · Fixed by #50694
Labels
compiler:inference Type inference kind:regression Regression in behavior compared to a previous version

Comments

@jw3126
Copy link
Contributor

jw3126 commented Dec 2, 2021

The following snipped infers in 1.6 and even 1.7-rc1 but does not anymore. Came up here:

using Accessors
using Test
struct TT{A,B}
    a::A
    b::B
end
lens = @optic(_.b.a.b[2])
obj = TT(2, TT(TT(3,(4,4)), 2))
@inferred modify(identity, obj, lens)
@dkarrasch dkarrasch added compiler:inference Type inference kind:regression Regression in behavior compared to a previous version labels Dec 2, 2021
@JeffBezanson
Copy link
Sponsor Member

Could you try bisecting this?

@jw3126
Copy link
Contributor Author

jw3126 commented Dec 7, 2021

@JeffBezanson bisected to e8caa27

@maleadt
Copy link
Member

maleadt commented Dec 9, 2021

MWE:

r(b) = r(typeof(b))
r(::Type) = nothing
r(::Nothing) = nonexistent

struct C{t,I} end
r(::Type{C{c,d}}) where {c,d} = f(r(c), e)
f(::Nothing, :) = nothing
f(g, :) = h

k(b, j, :) = l
k(b, j, ::Nothing) = b

i(b, j) = k(b, j, r(j))
struct A{d} end
Base.return_types(i, (Int64, C{C{C{A, Tuple}, Tuple}}))

@vtjnash
Copy link
Sponsor Member

vtjnash commented Dec 9, 2021

i, k, and f there are unrelated, and are just playing the role of a type-unstable conditional

This is now explicitly disallowed in inference:

r(::Type{C{c,d}}) where {c,d} = f(r(c), e)

Since it is inferring / calling:

r(::Type{C{C{C{A}}}}) -> r(::Type{C{C{A}}}) -> r(::Type{C{A}}) -> r(::Type{C{A}}) -> r(::Type{A}) -> nothing

And we decided (e8caa27) that this pattern is not something we care about, relative to other patterns.

@jw3126
Copy link
Contributor Author

jw3126 commented Dec 9, 2021

And we decided (e8caa27) that this pattern is not something we care about, relative to other patterns.

Does this mean this bug won't be fixed?

@jw3126
Copy link
Contributor Author

jw3126 commented Dec 10, 2021

And we decided (e8caa27) that this pattern is not something we care about, relative to other patterns.

This pattern can arise in the wild, when you combine trait based dispatch with recursion. This is the cause in Accessors.jl:

OpticStyle(optic) = OpticStyle(typeof(optic))
OpticStyle(::Type{MyOptic}) = ...
doit(optic) = _doit(optic, OpticStyle(optic))
function _doit(optic::ComposedOptic, ::SomeStyle)
    x1 = doit(optic.inner)
    ...
    x2 = doit(optic.outer)
    ...
end

A workaround is to replace

OpticStyle(::Type{MyOptic}) = ...

by

OpticStyle(::MyOptic) = ...

@vtjnash
Copy link
Sponsor Member

vtjnash commented Dec 10, 2021

Ah, interesting. I wonder if we can do something about that too.

@cscherrer
Copy link

cscherrer commented Dec 10, 2021

Maybe try

@generated function OpticStyle(optic::T) where {T}
    OpticStyle(T)
end

This worked for me in a similar situation.

@jw3126
Copy link
Contributor Author

jw3126 commented Dec 13, 2021

Maybe try

@generated function OpticStyle(optic::T) where {T}
    OpticStyle(T)
end

This worked for me in a similar situation.

If I do this, it seems dispatch selects the wrong method in some situations. I thought

@generated function OpticStyle(optic::T) where {T}
    OpticStyle(T)
end

and

function OpticStyle(optic::T) where {T}
    OpticStyle(T)
end

have exactly the same semantics, but seems not to be the case.

Base.@pure OpticStyle(obj) = OpticStyle(typeof(obj)) 

solves the problem, but will probably lead to bugs.

vtjnash added a commit that referenced this issue Jul 27, 2023
We had a special case for Type that disallowed type trait recursion in
favor of a pattern that almost never appears in code (only once in the
compiler by accident where it doesn't matter). This was unnecessarily
confusing and unexpected to predict what can infer, and made traits
harder than necessary (such as Broadcast.ndims since 70fc3cd).

Fix #43296
Fix #43368
vtjnash added a commit that referenced this issue Jul 31, 2023
We had a special case for Type that disallowed type trait recursion in
favor of a pattern that almost never appears in code (only once in the
compiler by accident where it doesn't matter). This was unnecessarily
confusing and unexpected to predict what can infer, and made traits
harder than necessary (such as Broadcast.ndims since 70fc3cd).

Fix #43296
Fix #43368
vtjnash added a commit that referenced this issue Aug 2, 2023
We had a special case for Type that disallowed type trait recursion in
favor of a pattern that almost never appears in code (only once in the
compiler by accident where it doesn't matter). This was unnecessarily
confusing and unexpected to predict what can infer, and made traits
harder than necessary (such as Broadcast.ndims since 70fc3cd).

Fix #43296
Fix #43368
IanButterworth pushed a commit that referenced this issue Aug 19, 2023
We had a special case for Type that disallowed type trait recursion in
favor of a pattern that almost never appears in code (only once in the
compiler by accident where it doesn't matter). This was unnecessarily
confusing and unexpected to predict what can infer, and made traits
harder than necessary (such as Broadcast.ndims since 70fc3cd).

Fix #43296
Fix #43368

(cherry picked from commit 33e3d9f)
nalimilan pushed a commit that referenced this issue Nov 5, 2023
We had a special case for Type that disallowed type trait recursion in
favor of a pattern that almost never appears in code (only once in the
compiler by accident where it doesn't matter). This was unnecessarily
confusing and unexpected to predict what can infer, and made traits
harder than necessary (such as Broadcast.ndims since 70fc3cd).

Fix #43296
Fix #43368

(cherry picked from commit 33e3d9f)
aviatesk added a commit that referenced this issue Nov 9, 2023
aviatesk added a commit that referenced this issue Nov 9, 2023
KristofferC pushed a commit that referenced this issue Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:inference Type inference kind:regression Regression in behavior compared to a previous version
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants