Provides methods to compare types.
Constructors
Members
Indicates whether a previous subtype check used GADT bounds
Indicates whether a previous subtype check used GADT bounds
For statistics: count how many isSubTypes are part of successful comparisons
For statistics: count how many isSubTypes are part of successful comparisons
Record that GADT bounds of sym
were used in a subtype check.
But exclude constructor type parameters, as these are aliased
to the corresponding class pa...
Record that GADT bounds of sym
were used in a subtype check.
But exclude constructor type parameters, as these are aliased
to the corresponding class parameters, which does not constitute
a true usage of a GADT symbol.
Indicates whether a previous subtype check used GADT bounds
Indicates whether a previous subtype check used GADT bounds
Form a normalized conjunction of two types.
Note: For certain types, &
is distributed inside the type. This holds for
all types which are not value type...
Form a normalized conjunction of two types.
Note: For certain types, &
is distributed inside the type. This holds for
all types which are not value types (e.g. TypeBounds, ClassInfo,
ExprType, MethodType, PolyType). Also, when forming an &
,
instantiated TypeVars are dereferenced and annotations are stripped.
Finally, refined types with the same refined name are
opportunistically merged.
Sometimes, the conjunction of two types cannot be formed because the types are in conflict of each other. In particular:
- Two different class types are conflicting.
- A class type conflicts with a type bounds that does not include the class reference.
- Two method or poly types with different (type) parameters but the same signature are conflicting
In these cases, a MergeError is thrown.
Form a normalized conjunction of two types.
Note: For certain types, &
is distributed inside the type. This holds for
all types which are not value type...
Form a normalized conjunction of two types.
Note: For certain types, &
is distributed inside the type. This holds for
all types which are not value types (e.g. TypeBounds, ClassInfo,
ExprType, MethodType, PolyType). Also, when forming an &
,
instantiated TypeVars are dereferenced and annotations are stripped.
Finally, refined types with the same refined name are
opportunistically merged.
Sometimes, the conjunction of two types cannot be formed because the types are in conflict of each other. In particular:
- Two different class types are conflicting.
- A class type conflicts with a type bounds that does not include the class reference.
- Two method or poly types with different (type) parameters but the same signature are conflicting
In these cases, a MergeError is thrown.
Subtype test for the hk application tp1 = tycon1[args1]
.
Subtype test for the hk application tp1 = tycon1[args1]
.
Subtype test for the hk application tp2 = tycon2[args2]
.
Subtype test for the hk application tp2 = tycon2[args2]
.
A new type comparer of the same type as this one, using the given context.
A new type comparer of the same type as this one, using the given context.
Try to distribute |
inside type, detect and handle conflicts
Note that, unlike for &
, a disjunction cannot be pushed into
a refined or applied type. Exa...
[T][U][T | U]
Try to distribute |
inside type, detect and handle conflicts
Note that, unlike for &
, a disjunction cannot be pushed into
a refined or applied type. Example:
List[T] | List[U] is not the same as List[T | U].
The rhs is a proper supertype of the lhs.
Returns true iff the result of evaluating either op1
or op2
is true,
trying at the same time to keep the constraint as wide as possible.
E.g, if
tp11 <:<...
Returns true iff the result of evaluating either op1
or op2
is true,
trying at the same time to keep the constraint as wide as possible.
E.g, if
tp11 <:< tp12 = true with post-constraint c1 tp12 <:< tp22 = true with post-constraint c2
and c1 subsumes c2, then c2 is kept as the post-constraint of the result, otherwise c1 is kept.
This method is used to approximate a solution in one of the following cases
T1 & T2 <:< T3 T1 <:< T2 | T3
In the first case (the second one is analogous), we have a choice whether we want to establish the subtyping judgement using
T1 <:< T3 or T2 <:< T3
as a precondition. Either precondition might constrain type variables. The purpose of this method is to pick the precondition that constrains less. The method is not complete, because sometimes there is no best solution. Example:
A? & B? <: T
Here, each precondition leads to a different constraint, and neither of the two post-constraints subsumes the other.
Replace any top-level recursive type { z => T }
in tp
with
[z := anchor]T
.
Replace any top-level recursive type { z => T }
in tp
with
[z := anchor]T
.
The greatest lower bound of two types
The greatest lower bound of two types
The greatest lower bound of a list types
The greatest lower bound of a list types
Does type tp1
have a member with name name
whose normalized type is a subtype of
the normalized type of the refinement tp2
?
Normalization is as follows:...
Does type tp1
have a member with name name
whose normalized type is a subtype of
the normalized type of the refinement tp2
?
Normalization is as follows: If tp2
contains a skolem to its refinement type,
rebase both itself and the member info of tp
on a freshly created skolem type.
A comparison function to pick a winner in case of a merge conflict
A comparison function to pick a winner in case of a merge conflict
Can type tp
be constrained from above by adding a constraint to
a typevar that it refers to? In that case we have to be careful not
to approximate with...
Can type tp
be constrained from above by adding a constraint to
a typevar that it refers to? In that case we have to be careful not
to approximate with the lower bound of a type in thirdTry
. Instead,
we should first unroll tp1
until we hit the type variable and bind the
type variable with (the corresponding type in) tp2
instead.
A type has been covered previously in subtype checking if it is some combination of TypeRefs that point to classes, where the combiners are RefinedTypes...
A type has been covered previously in subtype checking if it is some combination of TypeRefs that point to classes, where the combiners are RefinedTypes, RecTypes, AndTypes or AnnotatedTypes. One exception: Refinements referring to basetype args are never considered to be already covered. This is necessary because such refined types might still need to be compared with a compareAliasRefined.
Defer constraining type variables when compared against prototypes
Defer constraining type variables when compared against prototypes
Like tp1 <:< tp2, but returns false immediately if we know that the case was covered previously during subtyping.
Like tp1 <:< tp2, but returns false immediately if we know that the case was covered previously during subtyping.
Same as isSameType
but also can be applied to overloaded TermRefs, where
two overloaded refs are the same if they have pairwise equal alternatives
Same as isSameType
but also can be applied to overloaded TermRefs, where
two overloaded refs are the same if they have pairwise equal alternatives
Two types are the same if are mutual subtypes of each other
Two types are the same if are mutual subtypes of each other
Subtype test for corresponding arguments in args1
, args2
according to
variances in type parameters tparams
.
Subtype test for corresponding arguments in args1
, args2
according to
variances in type parameters tparams
.
Are refinements in tp1
pairwise subtypes of the refinements of tp2
up to parent type limit
?
Are refinements in tp1
pairwise subtypes of the refinements of tp2
up to parent type limit
?
op(tp1, tp2)
unless tp1
and tp2
are type-constructors with at least
some unnamed type parameters.
In the latter case, combine tp1
and tp2
under a type l...
[X1, ..., Xn][X1, ..., Xn][X1, ..., Xn]
[type T][type U]
op(tp1, tp2)
unless tp1
and tp2
are type-constructors with at least
some unnamed type parameters.
In the latter case, combine tp1
and tp2
under a type lambda like this:
[X1, ..., Xn] -> op(tp1[X1, ..., Xn], tp2[X1, ..., Xn])
Note: There is a tension between named and positional parameters here, which is impossible to resolve completely. Say you have
C[type T], D[type U]
Then do you expand C & D
to [T] -> C[T] & D[T]
or not? Under the named
type parameter interpretation, this would be wrong whereas under the traditional
higher-kinded interpretation this would be required. The problem arises from
allowing both interpretations. A possible remedy is to be somehow stricter
in where we allow which interpretation.
The least upper bound of a list of types
The least upper bound of a list of types
A function implementing tp1
matches tp2
.
A function implementing tp1
matches tp2
.
Are syms1
and syms2
parameter lists with pairwise equivalent types?
Are syms1
and syms2
parameter lists with pairwise equivalent types?
Do generic types poly1
and poly2
have type parameters that
have the same bounds (after renaming one set to the other)?
Do generic types poly1
and poly2
have type parameters that
have the same bounds (after renaming one set to the other)?
Merge tp1
into tp2
if tp1 is a supertype of some |-summand of tp2.
Merge tp1
into tp2
if tp1 is a supertype of some |-summand of tp2.
Narrow gadt.bounds for the type parameter referenced by tr
to include
bound
as an upper or lower bound (which depends on isUpper
).
Test that the resulti...
Narrow gadt.bounds for the type parameter referenced by tr
to include
bound
as an upper or lower bound (which depends on isUpper
).
Test that the resulting bounds are still satisfiable.
Form a normalized conjunction of two types.
Note: For certain types, |
is distributed inside the type. This holds for
all types which are not value type...
Form a normalized conjunction of two types.
Note: For certain types, |
is distributed inside the type. This holds for
all types which are not value types (e.g. TypeBounds, ClassInfo,
ExprType, MethodType, PolyType). Also, when forming an |
,
instantiated TypeVars are dereferenced and annotations are stripped.
Sometimes, the disjunction of two types cannot be formed because
the types are in conflict of each other. (@see andType
for an enumeration
of these cases). In cases of conflict a MergeError
is raised.
Form a normalized conjunction of two types.
Note: For certain types, |
is distributed inside the type. This holds for
all types which are not value type...
Form a normalized conjunction of two types.
Note: For certain types, |
is distributed inside the type. This holds for
all types which are not value types (e.g. TypeBounds, ClassInfo,
ExprType, MethodType, PolyType). Also, when forming an |
,
instantiated TypeVars are dereferenced and annotations are stripped.
Sometimes, the disjunction of two types cannot be formed because
the types are in conflict of each other. (@see andType
for an enumeration
of these cases). In cases of conflict a MergeError
is raised.
Record statistics about the total number of subtype checks and the number of "successful" subtype checks, i.e. checks that form part of a subtype deriva...
Record statistics about the total number of subtype checks and the number of "successful" subtype checks, i.e. checks that form part of a subtype derivation tree that's ultimately successful.
Show subtype goal that led to an assertion failure
Show subtype goal that led to an assertion failure
Show type, handling type types better than the default
Show type, handling type types better than the default
Skip refinements in tp2
which match corresponding refinements in tp1
.
"Match" means:
- they appear in the same order,
- they refine the same names,
- the...
Skip refinements in tp2
which match corresponding refinements in tp1
.
"Match" means:
- they appear in the same order,
- they refine the same names,
- the refinement in tp1
is an alias type, and
- neither refinement refers back to the refined type via a refined this.
Is a subtype check in progress? In that case we may not permanently instantiate type variables, because the corresponding constraint might still be retr...
Is a subtype check in progress? In that case we may not permanently instantiate type variables, because the corresponding constraint might still be retracted and the instantiation should then be reversed.
For statistics: count how many isSubTypes are part of successful comparisons
For statistics: count how many isSubTypes are part of successful comparisons
Test whether tp1
has a base type of the form B[T1, ..., Tn]
where
- B
derives from one of the class symbols of tp2
,
- the type parameters of B
match one...
Test whether tp1
has a base type of the form B[T1, ..., Tn]
where
- B
derives from one of the class symbols of tp2
,
- the type parameters of B
match one-by-one the variances of tparams
,
- B
satisfies predicate p
.
A hook for showing subtype traces. Overridden in ExplainingTypeComparer
A hook for showing subtype traces. Overridden in ExplainingTypeComparer