Open abgruszecki opened 2 years ago
More explanation: after having a closer inspection of the issue, the call site mentioned in the original comment is incorrect and misleading. What actually happens:
X <: Tag{T <: B}
,TypeComparer
will end up calling hasMatchingMember(T, X, Tag{T<:B})
, which asks whether the type member T
or LHS is a subtype of the RHS.hasMatchingMember
queries the member T
of X
, which implicitly upcasts X
to its upper bound Tag{T <: A}
, leading to the unsoundness.To verify, I added the tracing expression trace.force(i"$tp1 . $name", show = true) { tp1.member(name) }
. This is what it prints:
==> X . T?
<== X . T = type T
The query returns the type member T
of the upper bound of X
. This implicitly upcasts X
.
This issue was picked for the Issue Spree n° 19 of August 16th which takes place in a week from now. @dwijnand @nmcb will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here.
Originally posted by @Linyxus in https://github.com/lampepfl/dotty/issues/15175#issuecomment-1152619492
Regarding the soundness holes caused by resetting approx state: yes, we have more soundness holes caused by this. Each time
isSubType(S, T)
(instead ofrecur(S, T)
) is called insideisSubType
, the approx state is reset, and it will be a potential soundness hole. For example, I find another callsite ofisSubType
here, and we can make a counter-example showing the unsoundness brought by this:In this example, we are trying to extract necessary constraint from
X <: Tag{type T <: B}
, whereX
is known to be a subtype ofTag{type T <: A}
. During this we will try upcasting LHS and compareTag{type T <: A} <: Tag{type T <: B}
with LHS approximated. Since when comparing the refinement info the approx state is reset, we derive the unsound constraintA <: B
.