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

Subtype: Fix some diagonal rule related false alarm #53034

Merged
merged 3 commits into from
Jan 26, 2024

Conversation

N5N3
Copy link
Member

@N5N3 N5N3 commented Jan 24, 2024

close #33137
close #53021

@N5N3 N5N3 requested a review from vtjnash January 24, 2024 13:25
@N5N3 N5N3 added the types and dispatch Types, subtyping and method dispatch label Jan 24, 2024
@nsajko
Copy link
Contributor

nsajko commented Jan 24, 2024

This decreases the number of intransitive triplets found in the experiment from 6035 to 5123. Here's a sample of those which are not fixed with this PR:

(Tuple{Any, X} where X<:A, Tuple{X, X, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{Any}} where X>:Any, Tuple{X, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{A}} where X<:Union{}, Tuple{X, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{X}} where X<:A, Tuple{X, Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, C, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where X>:C, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{Any}} where A<:X<:A, Tuple{Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, Any, Vararg{A}}, Tuple{X, Any, Vararg{A}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{A}} where A<:X<:A, Tuple{X, A, Vararg{A}} where X>:Any, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{A}} where X, Tuple{X, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, Any, Vararg{A}}, Tuple{X, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X} where X<:Union{}, Tuple{X, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, X, Vararg{Any}} where A<:X<:A, Tuple{X, Any, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X} where C<:X<:A, Tuple{X, Any, Vararg{Any}} where X>:C, Tuple{Vararg{X}} where X>:A)
(Tuple{A, A, Vararg{X}} where X<:A, Tuple{X, Any, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X} where X<:C, Tuple{X, Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{A}} where X>:Any, Tuple{Any, Vararg{Any}}, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, X} where C<:X<:A, Tuple{X, Any} where X>:Any, Tuple{Vararg{X}} where X>:A)
(Tuple{A, A, Vararg{X}} where X, Tuple{X, Any, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{X}} where X<:Union{}, Tuple{X, Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, A, Vararg{X}} where X<:C, Tuple{X, Any, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, A, Vararg{A}}, Tuple{X, A, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A)
(Tuple{A, A, Vararg{X}} where X<:A, Tuple{X, X, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, Any, Vararg{A}}, Tuple{X, Any, Vararg{A}} where X>:Any, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, X, Vararg{C}} where C<:X<:C, Tuple{X, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, A, Vararg{X}} where X<:A, Tuple{X, A, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, Any, Vararg{C}}, Tuple, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, X} where A<:X<:A, Tuple{X, X, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, X, Vararg{X}} where C<:X<:A, Tuple{X, Any, Vararg{A}} where A<:X<:A, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, X, Vararg{X}} where X<:C, Tuple{X, X, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, X} where X>:Any, Tuple{X, Any} where X>:A, Tuple{Vararg{X}} where X>:A)
(Tuple{A, A, Vararg{X}} where X>:A, Tuple{X, Any, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A)
(Tuple{Any, X} where X>:C, Tuple{X, Any, Vararg{A}} where X>:C, Tuple{Vararg{X}} where X>:A)

Here, as in the issue, A is an abstract type, and C is a struct that subtypes A.

@N5N3
Copy link
Member Author

N5N3 commented Jan 24, 2024

Not surprising to me though. The remaining might no be caused by diagonal check.
I guess an assertation build is helpful here to figure out if some of these failure comes from obvious_subtype optimization.

@vtjnash
Copy link
Member

vtjnash commented Jan 24, 2024

current CI failure is related, though seems like a test issue

Error in testset core:
Test Failed at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-XG3Q6T6R70.0/build/default-honeycrisp-XG3Q6T6R70-0/julialang/julia-master/julia-afee770a4f/share/julia/test/core.jl:243
  Expression: f20511(Union{Integer, T} where T <: Unsigned) == 1
   Evaluated: 0 == 1

src/jltypes.c Outdated
if (jl_is_typevar(a)) {
jl_value_t *na = ((jl_tvar_t*)a)->ub;
hasfree &= jl_has_free_typevars(na);
return simple_subtype(na, b, hasfree);
Copy link
Member

Choose a reason for hiding this comment

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

In Tuple{Union{Integer,T}, T} where T, would this cause the result to become Tuple{T, T} where T, instead of the correct result with a switched Union:

julia> (Union{Tuple{Integer,T}, Tuple{T, T}} where T) == (Tuple{Union{Integer,T}, T} where T)
true

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! That would happen only when T has a lb >: Integer, which also relax the diagonal rule. So it should be fine for this example. But if we replace Integer with a leaf type then diagonal rule still holds, so the next branch need a non leaf check.

Copy link
Member Author

Choose a reason for hiding this comment

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

Well it turns out this branch might affect method definition.
On master

julia> f(x::Union{AbstractArray,T}) where {T<:Vector} = T
f (generic function with 1 method)

julia> f([1])
ERROR: UndefVarError: `T` not defined
Stacktrace:
 [1] f(x::Vector{Int64})
   @ Main .\REPL[3]:1
 [2] top-level scope
   @ REPL[4]:1

This PR

julia> f(x::Union{AbstractArray,T}) where {T<:Vector} = T
WARNING: method definition for f at REPL[1]:1 declares type variable T but does not use it.
f (generic function with 1 method)

julia> f([1])
ERROR: UndefVarError: `T` not defined in static parameter matching
Suggestion: run Test.detect_unbound_args to detect method arguments that do not fully constrain a type parameter.
Stacktrace:
 [1] f(x::Vector{Int64})
   @ Main .\REPL[1]:1
 [2] top-level scope
   @ REPL[2]:1

Not sure if this is a regression.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this is a regression.

IMO this is an improvement, not a regression, because it's better to throw than be ambiguous.

Copy link
Contributor

Choose a reason for hiding this comment

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

I.e., you may have fixed a correctness bug?

Copy link
Member

Choose a reason for hiding this comment

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

@N5N3 That is an interesting observation. It is sort of awkward that whether we catch that issue at definition or runtime depends somewhat on what normalizations are implemented for Union. I think I am okay with that change however. It seems fairly unlikely packages would have written that, and the solution is quite simple (just don't write that TypeVar in that place to fix the warning). In particular, it was already doing a similar normalization in several cases, so it is at least not an unexpected new behavior:

(on master)

julia> Union{Integer,T} where T<:Integer
Union{Integer, T} where T<:Integer

julia> Union{Any,T} where T<:Integer
Any # not a Union or TypeVar

julia> Union{Int64, T} where T<:Integer
Union{Int64, T} where T<:Integer

julia> Union{Union{},T} where T<:Integer
Integery # not a Union or TypeVar

No, this was not fixing a correctness bug. There is no ambiguity there.

Copy link
Member

Choose a reason for hiding this comment

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

Unrelatedly, this PR is now very close to the unrelated issue encountered in #51637 (comment), where it may error when the normalization fails, instead of simply not doing this normalization, if you are interested in taking a look at how it can avoid throwing the exception from normalization in the example there (for a later PR).

@nsajko
Copy link
Contributor

nsajko commented Jan 25, 2024

This PR introduces some new counterexamples to the expected transitivity of <:.

Julia script /tmp/pr_regressions.jl:

abstract type A end
struct C <: A end

triplets = [
  (Tuple{A, X, Vararg{X}} where X<:C, Tuple{A, Vararg{X}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, X, Vararg{X}} where X<:C, Tuple{A, Vararg{X}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, X, Vararg{X}} where X<:C, Tuple{Any, Vararg{X}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, X, Vararg{X}} where X<:C, Tuple{Any, Vararg{X}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, X, Vararg{X}} where X<:Union{}, Tuple{A, Vararg{X}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, X, Vararg{X}} where X<:Union{}, Tuple{A, Vararg{X}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, X, Vararg{X}} where X<:Union{}, Tuple{Any, Vararg{X}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, X, Vararg{X}} where X<:Union{}, Tuple{Any, Vararg{X}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{Any, X, Vararg{X}} where X<:C, Tuple{Any, Vararg{X}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{Any, X, Vararg{X}} where X<:C, Tuple{Any, Vararg{X}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{Any, X, Vararg{X}} where X<:Union{}, Tuple{Any, Vararg{X}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{Any, X, Vararg{X}} where X<:Union{}, Tuple{Any, Vararg{X}} where X>:C, Tuple{Vararg{X}} where X>:A),
]

f(t) = t[1] <: t[2] <: t[3]
g(t) = t[1] <: t[3]

println(f.(triplets))
println(g.(triplets))

Results:

$ ./julia-nightly/bin/julia /tmp/pr_regressions.jl 
Bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
$ ./julia-pr_53034/bin/julia /tmp/pr_regressions.jl 
Bool[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

@aviatesk
Copy link
Member

Will this allow #48205 to be merged safely, or at least fix the first part of Jameson's concerns (xref: #48205 (comment))?

@N5N3 N5N3 force-pushed the more_norm branch 2 times, most recently from ab2aefd to 443e135 Compare January 25, 2024 11:58
@N5N3
Copy link
Member Author

N5N3 commented Jan 25, 2024

Will this allow #48205 to be merged safely, or at least fix the first part of Jameson's concerns (xref: #48205 (comment))?

We do more normalization after replacing simple_join with simple_union.
But the concern on datatype_name_cmp still holds, perhaps #48205 needs some type complexity check?

@N5N3
Copy link
Member Author

N5N3 commented Jan 25, 2024

@nsajko These new counterexamples seems fine.
They didn't appear on master just because the bad normalization breaks t[1] <: t[2].
And t[1] <: t[3] is still broken.

@N5N3 N5N3 changed the title Add more normalization path for Union and simple_union Subtype: Fix some diagonal rule related false alarm Jan 25, 2024
@N5N3
Copy link
Member Author

N5N3 commented Jan 25, 2024

@nsajko local test shows that f8c20cc fixes all of the remaining counterexamples.

@nsajko
Copy link
Contributor

nsajko commented Jan 25, 2024

Nice! However I still get 3815 counterexamples (with the version of the experiment code as available on Gitlab): counterexamples.jl.txt

EDIT: to clarify, the same experiment for Julia master yields 15595 counterexamples. The results for the master branch are available in the repo.

Inline sample, with just the initial few counterexamples:

abstract type A end
struct C <: A end

triplets = [
  (Tuple{A, A, Any, Vararg{Any}}, Tuple, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, A, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, A, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, Any, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{Any}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{Any}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{A, X, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, A, Any, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, A, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, A, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, Any, Any, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, Any, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, Vararg{Any}}, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{Any}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{Any}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{Any, X, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{Any}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{Any}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, A, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{Any}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Any, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{Any}} where C<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{Any}} where X, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{Any}} where X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{Any}} where X>:C, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, X, Vararg{Any}} where A<:X<:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, X, Vararg{Any}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, X, Vararg{Any}} where X>:Any, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{Any}}, Tuple{X, X, Vararg{X}} where X>:A, Tuple{Vararg{X}} where X>:A),
  (Tuple{A, A, Any, Vararg{A}}, Tuple, Tuple{Vararg{X}} where X>:A),
]

f(t) = t[1] <: t[2] <: t[3]
g(t) = t[1] <: t[3]

function d(v)
  allequal(v) || error("not all elements are equal")
  first(v)
end

println(d(f.(triplets)))
println(d(g.(triplets)))

@N5N3
Copy link
Member Author

N5N3 commented Jan 25, 2024

Opps I didn't update the test code.
I should have gone through the whole code as a similar bad diagonal check is down there.
Anyway, now the list should be clean.

test/core.jl Outdated Show resolved Hide resolved
@N5N3 N5N3 merged commit 5cf1021 into JuliaLang:master Jan 26, 2024
5 of 7 checks passed
@N5N3 N5N3 deleted the more_norm branch January 26, 2024 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
4 participants