Skip to content

inference: remove hacks around type-system incorrectness #21892

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

Merged
merged 1 commit into from
May 30, 2017

Conversation

vtjnash
Copy link
Member

@vtjnash vtjnash commented May 15, 2017

infers a missing method (MethodError) as returning Union{}
and fix tests that were wrong, but not detected previously!

@vtjnash vtjnash requested a review from martinholters May 15, 2017 22:24
@ararslan ararslan added the compiler:inference Type inference label May 16, 2017
@@ -1397,10 +1395,6 @@ function abstract_call_gf_by_type(f::ANY, atype::ANY, sv::InferenceState)
add_mt_backedge(ftname.mt, argtype, sv)
update_valid_age!(min_valid[1], max_valid[1], sv)
end
if isempty(applicable)
# TODO: this is needed because type intersection is wrong in some cases
return Any
Copy link
Member

Choose a reason for hiding this comment

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

Are we sure we are ready for this? Admittedly, of the typeintersect bugs I have seen recently, none was erroneously giving Bottom, but since proposing this in #20866, I have lost some confidence in typeintersect... Anyway, we can try, and if there are problems and we can't straighten it out in subype.c in time, we can just add this back.

@@ -3546,7 +3533,7 @@ function invoke_NF(argexprs, etype::ANY, atypes, sv, atype_unlimited::ANY,
all = false
end
end
if UNION_SPLIT_MISMATCH_ERROR && all
Copy link
Member

Choose a reason for hiding this comment

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

Just to be sure: This was also about wrongly missing a method due to a wrongly empty type intersection?

@testset "Exactness of cumsum # 21666" begin
# test that cumsum uses more stable algorithm
# for types with unknown/rounding arithmetic
Base.TypeArithmetic(::Type{F21666{T}}) where {T} = T
Base.:+(x::F, y::F) where {F <: F21666} = F(x.x + y.x)
Base.convert(::Type{Float64}, x::F21666) = Float64(x.x)
Copy link
Member

Choose a reason for hiding this comment

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

This change is fine, of course, but...
Is everything in a @testset always happening at the same world age? Somehow, I was under the impression that some method definitions took effect immediately, but I fail to reproduce now, so I was probably wrong. Could you drop a comment at #21769?

Copy link
Member

Choose a reason for hiding this comment

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

Thinking about it again, the + and convert definitions must have been available inside the @testset for the tests to have worked, or am I missing something here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Inference is willing to get everything wrong if you write method definitions like this. (ref #21570)

@martinholters
Copy link
Member

Travis on OSX timed out because it was building LLVM. Was that to be expected?

@tkelman
Copy link
Contributor

tkelman commented May 16, 2017

that can happen if it fails to download the llvm homebrew bottle. hopefully transient.

@@ -2059,12 +2059,12 @@ struct F21666{T <: Base.TypeArithmetic}
x::Float32
end

Base.TypeArithmetic(::Type{F21666{T}}) where {T} = T()
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to leave a note for the posterity why struct F21666 and these definitions should be outside of @testset?

Copy link
Member

Choose a reason for hiding this comment

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

Might make more sense to expand the Methods/Redefining Methods manual section a bit to explain how things behave inside let/try/... blocks at top level and add a warning note to the Unit Testing/Working with Test Sets section. If we just add a comment here, that won't stop the same mistake from being made elsewhere. (Assuming proper documentation will is pretty optimistic, I know, but still...)

@martinholters
Copy link
Member

Current thinking: Let's go with this, hoping that we will weed out some more typeintersect bugs (uncovered by this or otherwise) during the release cycle. Merge before I change my mind once again?

@KristofferC
Copy link
Member

@nanosoldier runbenchmarks(ALL, vs = ":master")

@martinholters
Copy link
Member

Worth a PkgEval run, too? (I haven't set it up here and I'm afraid I don't have the time to do so at the moment, but maybe someone else could run it?)

@nanosoldier
Copy link
Collaborator

Something went wrong when running your job:

NanosoldierError: failed to run benchmarks against primary commit: failed process: Process(`sudo cset shield -e su nanosoldier -- -c ./benchscript.sh`, ProcessExited(132)) [132]

Logs and partial data can be found here
cc @jrevels

@KristofferC
Copy link
Member

https://github.com/JuliaCI/BaseBenchmarkReports/blob/b5c7db227cca2c6e74253a1307daf5395ecd0be9/2d56182_vs_31f798e/logs/2d56182650f6fe68e1db062d256c1bae8cad4436_primary.err#L347 :

signal (4): Illegal instruction
while loading /home/nanosoldier/workdir/tmpeFa97x/benchscript.jl, in expression starting on line 16

@martinholters
Copy link
Member

Hah, I guess we've already found another bug we definitely should fix before merging this.

@martinholters
Copy link
Member

I cannot reproduce exactly the crash seen on nanosoldier, but load!("misc") crashes for me, which I believe is related to this:

julia> methods(string, Tuple{Char})
# 1 method for generic function "string":
string(a::Union{Char, String}...) in Base at strings/string.jl:351

julia> using LegacyStrings;

julia> methods(string, Tuple{Char})
# 0 methods for generic function "string":

julia> string('0')
"0"

Now, LegacyStrings indeed introduces an ambiguity here:

julia> methods(string)
# 17 methods for generic function "string":
# ...
string(a::Union{Char, String}...) in Base at strings/string.jl:351
#...
string(a::Union{Char, LegacyStrings.ASCIIString, LegacyStrings.UTF8String}...) in LegacyStrings at LegacyStrings/src/utf8.jl:161
#...

So string('0') should raise a MethodError and that is what inference assumes. Looks like this time, the bug is that string('0') is sill callable when really it shouldn't be.

@martinholters
Copy link
Member

Fixing the ambiguity in LegacyStrings lets the benchmarks finish successfully, at least locally.

infers a missing method (MethodError) as returning `Union{}`
and fix tests that were wrong, but not detected previously!
@vtjnash vtjnash force-pushed the jn/typeinf-more branch from b17b3b1 to 753fbef Compare May 29, 2017 18:14
@martinholters
Copy link
Member

Let's see if it works now: @nanosoldier runbenchmarks(ALL, vs = ":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels

@vtjnash vtjnash merged commit e3794ee into master May 30, 2017
@vtjnash vtjnash deleted the jn/typeinf-more branch May 30, 2017 17:07
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.

7 participants