ExplainingTypeComparer

dotty.tools.dotc.core.ExplainingTypeComparer

A type comparer that can record traces of subtype operations

Attributes

Graph
Supertypes
class Object
trait Matchable
class Any

Members list

Concise view

Type members

Inherited classlikes

class LevelAvoidMap(topLevelVariance: Int, maxLevel: Int)(using x$3: Context) extends AvoidMap

An approximating map that prevents types nested deeper than maxLevel as well as WildcardTypes from leaking into the constraint.

An approximating map that prevents types nested deeper than maxLevel as well as WildcardTypes from leaking into the constraint.

Attributes

Inherited from:
ConstraintHandling
Graph
Supertypes
class AvoidMap
class TypeMap
trait Type => Type
class Object
trait Matchable
class Any

Value members

Concrete methods

override def addConstraint(param: TypeParamRef, bound: Type, fromBelow: Boolean)(using Context): Boolean

Add constraint param <: bound if fromBelow is false, param >: bound otherwise. bound is assumed to be in normalized form, as specified in firstTry and secondTry of TypeComparer. In particular, it should not be an alias type, lazy ref, typevar, wildcard type, error type. In addition, upper bounds may not be AndTypes and lower bounds may not be OrTypes. This is assured by the way isSubType is organized.

Add constraint param <: bound if fromBelow is false, param >: bound otherwise. bound is assumed to be in normalized form, as specified in firstTry and secondTry of TypeComparer. In particular, it should not be an alias type, lazy ref, typevar, wildcard type, error type. In addition, upper bounds may not be AndTypes and lower bounds may not be OrTypes. This is assured by the way isSubType is organized.

Attributes

Definition Classes

Attributes

Definition Classes
override def gadtAddBound(sym: Symbol, b: Type, isUpper: Boolean): Boolean

Attributes

Definition Classes
override def glb(tp1: Type, tp2: Type): Type

The greatest lower bound of two types

The greatest lower bound of two types

Attributes

Definition Classes
override def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean

Does type tp1 have a member with name name whose normalized type is a subtype of the normalized type of the refinement of 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.

Does type tp1 have a member with name name whose normalized type is a subtype of the normalized type of the refinement of 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.

Attributes

Definition Classes
def lastTrace(header: String): String
override def lub(tp1: Type, tp2: Type, canConstrain: Boolean, isSoft: Boolean): Type

The least upper bound of two types

The least upper bound of two types

Attributes

canConstrain

If true, new constraints might be added to simplify the lub.

isSoft

If the lub is a union, this determines whether it's a soft union.

Note:

We do not admit singleton types in or-types as lubs.

Definition Classes
override def recur(tp1: Type, tp2: Type): Boolean

The inner loop of the isSubType comparison. Recursive calls from recur should go to recur directly if the two types compared in the callee are essentially the same as the types compared in the caller. "The same" means: represent essentially the same sets of values. recur should not be used to compare components of types. In this case one should use isSubType(_, _). recur should also not be used to compare approximated versions of the original types (as when we go from an abstract type to one of its bounds). In that case one should use isSubType(_, _, a) where a defines the kind of approximation.

The inner loop of the isSubType comparison. Recursive calls from recur should go to recur directly if the two types compared in the callee are essentially the same as the types compared in the caller. "The same" means: represent essentially the same sets of values. recur should not be used to compare components of types. In this case one should use isSubType(_, _). recur should also not be used to compare approximated versions of the original types (as when we go from an abstract type to one of its bounds). In that case one should use isSubType(_, _, a) where a defines the kind of approximation.

Note: Logically, recur could be nested in isSubType, which would avoid the instance state consisting approx and leftRoot. But then the implemented code would have two extra parameters for each of the many calls that go from one sub-part of isSubType to another.

Attributes

Definition Classes
override def subCaptures(refs1: CaptureSet, refs2: CaptureSet, frozen: Boolean)(using Context): CompareResult

Attributes

Definition Classes
override def traceIndented[T](str: String)(op: => T): T

A hook for showing subtype traces. Overridden in ExplainingTypeComparer

A hook for showing subtype traces. Overridden in ExplainingTypeComparer

Attributes

Definition Classes

Inherited methods

protected def addBoundTransitively(param: TypeParamRef, rawBound: Type, isUpper: Boolean)(using Context): Boolean

Attributes

Inherited from:
ConstraintHandling
protected def addLess(p1: TypeParamRef, p2: TypeParamRef)(using Context): Boolean

Attributes

Inherited from:
ConstraintHandling
protected def addOneBound(param: TypeParamRef, rawBound: Type, isUpper: Boolean)(using Context): Boolean

Attributes

Inherited from:
ConstraintHandling

Add type lambda tl, possibly with type variables tvars, to current constraint and propagate all bounds.

Add type lambda tl, possibly with type variables tvars, to current constraint and propagate all bounds.

Attributes

tvars

See Constraint#add

Inherited from:
ConstraintHandling
final def andType(tp1: Type, tp2: Type, isErased: Boolean): 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, LambdaType). Also, when forming an &, instantiated TypeVars are dereferenced and annotations are stripped. Finally, refined types with the same refined name are opportunistically merged.

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, LambdaType). Also, when forming an &, instantiated TypeVars are dereferenced and annotations are stripped. Finally, refined types with the same refined name are opportunistically merged.

Attributes

Inherited from:
TypeComparer
final def approximation(param: TypeParamRef, fromBelow: Boolean, maxLevel: Int)(using Context): Type

Solve constraint set for given type parameter param. If fromBelow is true the parameter is approximated by its lower bound, otherwise it is approximated by its upper bound, unless the upper bound contains a reference to the parameter itself (such occurrences can arise for F-bounded types, addOneBound ensures that they never occur in the lower bound). The solved type is not allowed to contain references to types nested deeper than maxLevel. Wildcard types in bounds are approximated by their upper or lower bounds. The constraint is left unchanged.

Solve constraint set for given type parameter param. If fromBelow is true the parameter is approximated by its lower bound, otherwise it is approximated by its upper bound, unless the upper bound contains a reference to the parameter itself (such occurrences can arise for F-bounded types, addOneBound ensures that they never occur in the lower bound). The solved type is not allowed to contain references to types nested deeper than maxLevel. Wildcard types in bounds are approximated by their upper or lower bounds. The constraint is left unchanged.

Attributes

Returns:

the instantiating type

Inherited from:
ConstraintHandling
final def assumedTrue(param: TypeParamRef)(using Context): Boolean

Is param assumed to be a sub- and super-type of any other type? This holds if TypeVarsMissContext is set unless param is a part of a MatchType that is currently normalized.

Is param assumed to be a sub- and super-type of any other type? This holds if TypeVarsMissContext is set unless param is a part of a MatchType that is currently normalized.

Attributes

Inherited from:
ConstraintHandling
def atLevel(maxLevel: Int, param: TypeParamRef)(using Context): TypeParamRef

If param is nested deeper than maxLevel, try to instantiate it to a fresh type variable of level maxLevel and return the new variable. If this isn't possible, throw a TypeError.

If param is nested deeper than maxLevel, try to instantiate it to a fresh type variable of level maxLevel and return the new variable. If this isn't possible, throw a TypeError.

Attributes

Inherited from:
ConstraintHandling

The current bounds of type parameter param

The current bounds of type parameter param

Attributes

Inherited from:
ConstraintHandling
final def canConstrain(param: TypeParamRef): Boolean

Can param be constrained with new bounds?

Can param be constrained with new bounds?

Attributes

Inherited from:
ConstraintHandling
def checkPropagated(msg: => String)(result: Boolean)(using Context): Boolean

Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated

Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated

Attributes

Inherited from:
ConstraintHandling
override def checkReset(): Unit

Attributes

Definition Classes
Inherited from:
TypeComparer
def compareAtoms(tp1: Type, tp2: Type, knownSingletons: Boolean): Option[Boolean]

If both tp1 and tp2 have atoms information, compare the atoms in a Some, otherwise None.

If both tp1 and tp2 have atoms information, compare the atoms in a Some, otherwise None.

Attributes

knownSingletons

If true, we are coming from a comparison of two singleton types This influences the comparison as shown below: Say you have singleton types p.type and q.type the atoms of p.type are {p.type}..{p.type}, and the atoms of q.type are {}..{p.type}. Normally the atom comparison between p's atoms and q's atoms gives false. But in this case we know that q.type is an alias of p.type so we are still allowed to conclude that p.type <:< q.type. A situation where this happens is in i6635.scala. Here, p: A, q: B & p.type and we want to conclude that p.type <: q.type.

Inherited from:
TypeComparer

Attributes

Inherited from:
TypeComparer

Optionally, the constant c such that tp <:< ConstantType(c)

Optionally, the constant c such that tp <:< ConstantType(c)

Attributes

Inherited from:
TypeComparer

Attributes

Inherited from:
ConstraintHandling
def constrainPatternType(pat: Type, scrut: Type, forceInvariantRefinement: Boolean): Boolean

Derive type and GADT constraints that necessarily follow from a pattern with the given type matching a scrutinee of the given type.

Derive type and GADT constraints that necessarily follow from a pattern with the given type matching a scrutinee of the given type.

This function breaks down scrutinee and pattern types into subcomponents between which there must be a subtyping relationship, and derives constraints from those relationships. We have the following situation in case of a (dynamic) pattern match:

 StaticScrutineeType           PatternType
                   \            /
                DynamicScrutineeType

In simple cases, it must hold that PatternType <: StaticScrutineeType:

      StaticScrutineeType
            |         \
            |          PatternType
            |         /
         DynamicScrutineeType

A good example of a situation where the above must hold is when static scrutinee type is the root of an enum, and the pattern is an unapply of a case class, or a case object literal (of that enum).

In slightly more complex cases, we may need to upcast StaticScrutineeType:

     SharedPatternScrutineeSuperType
            /         \

StaticScrutineeType PatternType \ / DynamicScrutineeType

This may be the case if the scrutinee is a singleton type or a path-dependent type. It is also the case for the following definitions:

trait Expr[T] trait IntExpr extends Expr[T] trait Const[T] extends Expr[T]

StaticScrutineeType = Const[T] PatternType = IntExpr

Union and intersection types are an additional complication - if either scrutinee or pattern are a union type, then the above relationships only need to hold for the "leaves" of the types.

Finally, if pattern type contains hk-types applied to concrete types (as opposed to type variables), or either scrutinee or pattern type contain type member refinements, the above relationships do not need to hold at all. Consider (where T1, T2 are unrelated traits):

StaticScrutineeType = { type T <: T1 } PatternType = { type T <: T2 }

In the above situation, DynamicScrutineeType can equal { type T = T1 & T2 }, but there is no useful relationship between StaticScrutineeType and PatternType (nor any of their subcomponents). Similarly:

StaticScrutineeType = Option[T1] PatternType = Some[T2]

Again, DynamicScrutineeType may equal Some[T1 & T2], and there's no useful relationship between the static scrutinee and pattern types. This does not apply if the pattern type is only applied to type variables, in which case the subtyping relationship "heals" the type.

Attributes

Inherited from:
PatternTypeConstrainer
def constrainSimplePatternType(patternTp: Type, scrutineeTp: Type, forceInvariantRefinement: Boolean): Boolean

Constrain "simple" patterns (see constrainPatternType).

Constrain "simple" patterns (see constrainPatternType).

This function expects to receive two types (scrutinee and pattern), both of which have class symbols, one of which is derived from another. If the type "being derived from" is an applied type, it will 1) "upcast" the deriving type to an applied type with the same constructor and 2) infer constraints for the applied types' arguments that follow from both types being inhabited by one value (the scrutinee).

Importantly, note that the pattern type may contain type variables, which are used to infer type arguments to Unapply trees.

Invariant refinement

Essentially, we say that D[B] extends C[B] s.t. refines parameter A of trait C[A] invariantly if when c: C[T] and c is instance of D, then necessarily c: D[T]. This is violated if A is variant:

trait C[+A] trait D[+B](val b: B) extends C[B] trait E extends DAny with C[String]

E is a counter-example to the above - if e: E, then e: C[String] and e is instance of D, but it is false that e: D[String]! This is a problem if we're constraining a pattern like the below:

def foo[T](c: C[T]): T = c match { case d: D[t] => d.b }

It'd be unsound for us to say that t <: T, even though that follows from D[t] <: C[T]. Note, however, that if D was a final class, we could rely on that relationship. To support typical case classes, we also assume that this relationship holds for them and their parent traits. This is enforced by checking that classes inheriting from case classes do not extend the parent traits of those case classes without also appropriately extending the relevant case class (see RefChecks#checkCaseClassInheritanceInvariant).

Attributes

Inherited from:
PatternTypeConstrainer

Attributes

Inherited from:
TypeComparer

Attributes

Inherited from:
TypeComparer

Can comparing this type on the left lead to an either? This is the case if the type is and AndType or contains embedded occurrences of AndTypes

Can comparing this type on the left lead to an either? This is the case if the type is and AndType or contains embedded occurrences of AndTypes

Attributes

Inherited from:
TypeComparer

Attributes

Inherited from:
TypeComparer
def decomposeRefinements(tp: Type, refines: List[(Name, Type)]): Type

Decompose into conjunction of types each of which has only a single refinement

Decompose into conjunction of types each of which has only a single refinement

Attributes

Inherited from:
TypeComparer
def dropTransparentTraits(tp: Type, bound: Type)(using Context): Type

If tp is an intersection such that some operands are transparent trait instances and others are not, replace as many transparent trait instances as possible with Any as long as the result is still a subtype of bound. But fall back to the original type if the resulting widened type is a supertype of all dropped types (since in this case the type was not a true intersection of transparent traits and other types to start with).

If tp is an intersection such that some operands are transparent trait instances and others are not, replace as many transparent trait instances as possible with Any as long as the result is still a subtype of bound. But fall back to the original type if the resulting widened type is a supertype of all dropped types (since in this case the type was not a true intersection of transparent traits and other types to start with).

Attributes

Inherited from:
ConstraintHandling

Attributes

Inherited from:
TypeComparer
def explained[T](op: ExplainingTypeComparer => T, header: String)(using Context): String

The trace of comparison operations when performing op

The trace of comparison operations when performing op

Attributes

Inherited from:
TypeComparer

Full bounds of param, including other lower/upper params.

Full bounds of param, including other lower/upper params.

Note that underlying operations perform subtype checks - for this reason, recursing on fullBounds of some param when comparing types might lead to infinite recursion. Consider bounds instead.

Attributes

Inherited from:
ConstraintHandling

The full lower bound of param includes both the nonParamBounds and the params in the constraint known to be <: param, except that params with a nestingLevel higher than param will be instantiated to a fresh param at a legal level. See the documentation of TypeVar for details.

The full lower bound of param includes both the nonParamBounds and the params in the constraint known to be <: param, except that params with a nestingLevel higher than param will be instantiated to a fresh param at a legal level. See the documentation of TypeVar for details.

Attributes

Inherited from:
ConstraintHandling

The full upper bound of param, see the documentation of fullLowerBounds above.

The full upper bound of param, see the documentation of fullLowerBounds above.

Attributes

Inherited from:
ConstraintHandling
def glbArgs(args1: List[Type], args2: List[Type], tparams: List[TypeParamInfo]): List[Type]

Try to produce joint arguments for a glb A[T_1, ..., T_n] & A[T_1', ..., T_n'] using the following strategies:

Try to produce joint arguments for a glb A[T_1, ..., T_n] & A[T_1', ..., T_n'] using the following strategies:

  • if arguments are the same, that argument.
  • if corresponding parameter variance is co/contra-variant, the glb/lub.
  • if at least one of the arguments if a TypeBounds, the union of the bounds.
  • if homogenizeArgs is set, and arguments can be unified by instantiating type parameters, the unified argument.
  • otherwise NoType

The unification rule is contentious because it cuts the constraint set. Therefore it is subject to Config option alignArgsInAnd.

Attributes

Inherited from:
TypeComparer
final inline def inFrozenConstraint[T](op: => T): T

Attributes

Inherited from:
ConstraintHandling
def init(c: Context): Unit

Attributes

Inherited from:
TypeComparer
def instanceType(param: TypeParamRef, fromBelow: Boolean, widenUnions: Boolean, maxLevel: Int)(using Context): Type

The instance type of param in the current constraint (which contains param). If fromBelow is true, the instance type is the lub of the parameter's lower bounds; otherwise it is the glb of its upper bounds. However, a lower bound instantiation can be a singleton type only if the upper bound is also a singleton type. The instance type is not allowed to contain references to types nested deeper than maxLevel.

The instance type of param in the current constraint (which contains param). If fromBelow is true, the instance type is the lub of the parameter's lower bounds; otherwise it is the glb of its upper bounds. However, a lower bound instantiation can be a singleton type only if the upper bound is also a singleton type. The instance type is not allowed to contain references to types nested deeper than maxLevel.

Attributes

Inherited from:
ConstraintHandling

Defer constraining type variables when compared against prototypes

Defer constraining type variables when compared against prototypes

Attributes

Inherited from:
TypeComparer
def isSameRef(tp1: Type, tp2: Type): Boolean

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

Attributes

Inherited from:
TypeComparer
def isSameType(tp1: Type, tp2: Type): Boolean

Two types are the same if they are mutual subtypes of each other. To avoid exponential blowup for deeply nested invariant applied types, we cache successes once the stack of outstanding isSameTypes reaches depth startSameTypeTrackingLevel. See pos/i15525.scala, where this matters.

Two types are the same if they are mutual subtypes of each other. To avoid exponential blowup for deeply nested invariant applied types, we cache successes once the stack of outstanding isSameTypes reaches depth startSameTypeTrackingLevel. See pos/i15525.scala, where this matters.

Attributes

Inherited from:
TypeComparer
final def isSameTypeWhenFrozen(tp1: Type, tp2: Type)(using Context): Boolean

Attributes

Inherited from:
ConstraintHandling
final protected def isSatisfiable(using Context): Boolean

Test whether the lower bounds of all parameters in this constraint are a solution to the constraint.

Test whether the lower bounds of all parameters in this constraint are a solution to the constraint.

Attributes

Inherited from:
ConstraintHandling
def isSubArgs(args1: List[Type], args2: List[Type], tp1: Type, tparams2: List[ParamInfo]): Boolean

Subtype test for corresponding arguments in args1, args2 according to variances in type parameters tparams2.

Subtype test for corresponding arguments in args1, args2 according to variances in type parameters tparams2.

Attributes

tp1

The applied type containing args1

tparams2

The type parameters of the type constructor applied to args2

Inherited from:
TypeComparer
def isSubType(tp1: Type, tp2: Type): Boolean

Attributes

Inherited from:
TypeComparer
protected def isSubType(tp1: Type, tp2: Type, whenFrozen: Boolean)(using Context): Boolean

Attributes

Inherited from:
ConstraintHandling
final def isSubTypeWhenFrozen(tp1: Type, tp2: Type)(using Context): Boolean

Attributes

Inherited from:
ConstraintHandling
protected def legalBound(param: TypeParamRef, rawBound: Type, isUpper: Boolean)(using Context): Type

Approximate rawBound if needed to make it a legal bound of param by avoiding wildcards and types with a level strictly greater than its nestingLevel.

Approximate rawBound if needed to make it a legal bound of param by avoiding wildcards and types with a level strictly greater than its nestingLevel.

Note that level-checking must be performed here and cannot be delayed until instantiation because if we allow level-incorrect bounds, then we might end up reasoning with bad bounds outside of the scope where they are defined. This can lead to level-correct but unsound instantiations as demonstrated by tests/neg/i8900.scala.

Attributes

Inherited from:
ConstraintHandling
def levelOK(level: Int, maxLevel: Int)(using Context): Boolean

Is level <= maxLevel or legal in the current context?

Is level <= maxLevel or legal in the current context?

Attributes

Inherited from:
ConstraintHandling
def liftIfHK(tp1: Type, tp2: Type, op: (Type, Type) => Type, original: (Type, Type) => Type, combineVariance: (Variance, Variance) => Variance): Type

op(tp1, tp2) unless tp1 and tp2 are type-constructors. In the latter case, combine tp1 and tp2 under a type lambda like this:

op(tp1, tp2) unless tp1 and tp2 are type-constructors. In the latter case, combine tp1 and tp2 under a type lambda like this:

[X1, ..., Xn] -> op(tp1[X1, ..., Xn], tp2[X1, ..., Xn])

Attributes

Inherited from:
TypeComparer
def location(using Context): String

Attributes

Inherited from:
ConstraintHandling
def lubArgs(args1: List[Type], args2: List[Type], tparams: List[TypeParamInfo], canConstrain: Boolean): List[Type]

Try to produce joint arguments for a lub A[T_1, ..., T_n] | A[T_1', ..., T_n'] using the following strategies:

Try to produce joint arguments for a lub A[T_1, ..., T_n] | A[T_1', ..., T_n'] using the following strategies:

  • if arguments are the same, that argument.
  • if corresponding parameter variance is co/contra-variant, the lub/glb.
  • otherwise a TypeBounds containing both arguments

Attributes

Inherited from:
TypeComparer
final def matchesType(tp1: Type, tp2: Type, relaxed: Boolean): Boolean

A function implementing tp1 matches tp2.

A function implementing tp1 matches tp2.

Attributes

Inherited from:
TypeComparer

Do the parameter types of tp1 and tp2 match in a way that allows tp1 to override tp2 ? Two modes: precise or not. If precise is set (which is the default) this is the case if they're pairwise =:=. Otherwise parameters in tp2 must be subtypes of corresponding parameters in tp1.

Do the parameter types of tp1 and tp2 match in a way that allows tp1 to override tp2 ? Two modes: precise or not. If precise is set (which is the default) this is the case if they're pairwise =:=. Otherwise parameters in tp2 must be subtypes of corresponding parameters in tp1.

Attributes

Inherited from:
TypeComparer

Do the parameter types of tp1 and tp2 match in a way that allows tp1 to override tp2 ? This is the case if they're pairwise >:>.

Do the parameter types of tp1 and tp2 match in a way that allows tp1 to override tp2 ? This is the case if they're pairwise >:>.

Attributes

Inherited from:
TypeComparer
def natValue(tp: Type): Option[Int]

Optionally, the n such that tp <:< ConstantType(Constant(n: Int))

Optionally, the n such that tp <:< ConstantType(Constant(n: Int))

Attributes

Inherited from:
TypeComparer

When collecting the constraints needed for a particular subtyping judgment to be true, we sometimes need to approximate the constraint set (see TypeComparer#either for example).

When collecting the constraints needed for a particular subtyping judgment to be true, we sometimes need to approximate the constraint set (see TypeComparer#either for example).

Normally, this means adding extra constraints which may not be necessary for the subtyping judgment to be true, but if this variable is set to true we will instead under-approximate and keep only the constraints that must always be present for the subtyping judgment to hold.

This is needed for GADT bounds inference to be sound, but it is also used when constraining a method call based on its expected type to avoid adding constraints that would later prevent us from typechecking method arguments, see or-inf.scala and and-inf.scala for examples.

Attributes

Inherited from:
ConstraintHandling

Attributes

Inherited from:
TypeComparer
def nestingLevel(param: TypeParamRef)(using Context): Int

Attributes

Inherited from:
ConstraintHandling

Attributes

Inherited from:
ConstraintHandling
final def orType(tp1: Type, tp2: Type, isSoft: Boolean, isErased: Boolean): 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, LambdaType). Also, when forming an |, instantiated TypeVars are dereferenced and annotations are stripped.

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, LambdaType). Also, when forming an |, instantiated TypeVars are dereferenced and annotations are stripped.

Attributes

isErased

Apply erasure semantics. If erased is true, instead of creating an OrType, the lub will be computed using TypeCreator#erasedLub.

isSoft

If the result is a union, this determines whether it's a soft union.

Inherited from:
TypeComparer
def provablyDisjoint(tp1: Type, tp2: Type)(using Context): Boolean

Are tp1 and tp2 provablyDisjoint types?

Are tp1 and tp2 provablyDisjoint types?

true implies that we found a proof; uncertainty defaults to false.

Proofs rely on the following properties of Scala types:

  1. Single inheritance of classes
  2. Final classes cannot be extended
  3. ConstantTypes with distinct values are non intersecting
  4. TermRefs with distinct values are non intersecting
  5. There is no value of type Nothing

Note on soundness: the correctness of match types relies on on the property that in all possible contexts, the same match type expression is either stuck or reduces to the same case.

Attributes

Inherited from:
TypeComparer

Is tp an empty type?

Is tp an empty type?

true implies that we found a proof; uncertainty defaults to false.

Attributes

Inherited from:
TypeComparer
def recordStatistics(result: Boolean, prevSuccessCount: Int): Unit

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.

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.

Attributes

Inherited from:
TypeComparer
def showGoal(tp1: Type, tp2: Type)(using Context): Unit

Show subtype goal that led to an assertion failure

Show subtype goal that led to an assertion failure

Attributes

Inherited from:
TypeComparer
final def simplifyAndTypeWithFallback(tp1: Type, tp2: Type, fallback: Type): Type

Attributes

Inherited from:
TypeComparer
def singletonInterval(tp1: Type, tp2: Type): Type

If the range tp1..tp2 consist of a single type, that type, otherwise NoType. This is the case iftp1 =:= tp2, but also iftp1 <:< tp2,tp1is a singleton type, andtp2derives fromscala.Singleton` (or vice-versa). Examples of the latter case:

If the range tp1..tp2 consist of a single type, that type, otherwise NoType. This is the case iftp1 =:= tp2, but also iftp1 <:< tp2,tp1is a singleton type, andtp2derives fromscala.Singleton` (or vice-versa). Examples of the latter case:

"name".type .. Singleton "name".type .. String & Singleton Singleton .. "name".type String & Singleton .. "name".type

All consist of the single type "name".type.

Attributes

Inherited from:
TypeComparer
final protected def subsumes(c1: Constraint, c2: Constraint, pre: Constraint)(using Context): Boolean

Constraint c1 subsumes constraint c2, if under c2 as constraint we have for all poly params p defined in c2 as p >: L2 <: U2:

Constraint c1 subsumes constraint c2, if under c2 as constraint we have for all poly params p defined in c2 as p >: L2 <: U2:

c1 defines p with bounds p >: L1 <: U1, and L2 <: L1, and U1 <: U2

Both c1 and c2 are required to derive from constraint pre, without adding any new type variables but possibly narrowing already registered ones with further bounds.

Attributes

Inherited from:
ConstraintHandling

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.

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.

Attributes

Inherited from:
TypeComparer

Attributes

Inherited from:
TypeComparer
def topLevelSubType(tp1: Type, tp2: Type): Boolean

Attributes

Inherited from:
TypeComparer
def tracked[T](op: TrackingTypeComparer => T)(using Context): T

Attributes

Inherited from:
TypeComparer

Attributes

Inherited from:
ConstraintHandling

Attributes

Inherited from:
TypeComparer
def widenInferred(inst: Type, bound: Type, widenUnions: Boolean)(using Context): Type

Widen inferred type inst with upper bound, according to the following rules:

Widen inferred type inst with upper bound, according to the following rules:

  1. If inst is a singleton type, or a union containing some singleton types, widen (all) the singleton type(s), provided the result is a subtype of bound. (i.e. inst.widenSingletons <:< bound succeeds with satisfiable constraint) 2a. If inst is a union type and widenUnions is true, approximate the union type from above by an intersection of all common base types, provided the result is a subtype of bound. 2b. If inst is a union type and widenUnions is false, turn it into a hard union type (except for unions | Null, which are kept in the state they were).
  2. Widen some irreducible applications of higher-kinded types to wildcard arguments (see @widenIrreducible).
  3. Drop transparent traits from intersections (see @dropTransparentTraits).

Don't do these widenings if bound is a subtype of scala.Singleton. Also, if the result of these widenings is a TypeRef to a module class, and this type ref is different from inst, replace by a TermRef to its source module instead.

At this point we also drop the @Repeated annotation to avoid inferring type arguments with it, as those could leak the annotation to users (see run/inferred-repeated-result).

Attributes

Inherited from:
ConstraintHandling

If tp is an applied match type alias which is also an unreducible application of a higher-kinded type to a wildcard argument, widen to the match type's bound, in order to avoid an unreducible application of higher-kinded type ... in inferred type" error in PostTyper. Fixes #11246.

If tp is an applied match type alias which is also an unreducible application of a higher-kinded type to a wildcard argument, widen to the match type's bound, in order to avoid an unreducible application of higher-kinded type ... in inferred type" error in PostTyper. Fixes #11246.

Attributes

Inherited from:
ConstraintHandling
inline def withUntrustedBounds(op: => Type): Type

Attributes

Inherited from:
ConstraintHandling

Inherited fields

protected var canWidenAbstract: Boolean

Used for match type reduction: If false, we don't recognize an abstract type to be a subtype type of any of its base classes. This is in place only at the toplevel; it is turned on again when we add parts of the scrutinee to the constraint.

Used for match type reduction: If false, we don't recognize an abstract type to be a subtype type of any of its base classes. This is in place only at the toplevel; it is turned on again when we add parts of the scrutinee to the constraint.

Attributes

Inherited from:
ConstraintHandling
protected var caseLambda: Type

Potentially a type lambda that is still instantiatable, even though the constraint is generally frozen.

Potentially a type lambda that is still instantiatable, even though the constraint is generally frozen.

Attributes

Inherited from:
ConstraintHandling

We are currently comparing type lambdas. Used as a flag for optimization: when false, no need to do an expensive pruneLambdaParams

We are currently comparing type lambdas. Used as a flag for optimization: when false, no need to do an expensive pruneLambdaParams

Attributes

Inherited from:
ConstraintHandling
protected var frozenConstraint: Boolean

If the constraint is frozen we cannot add new bounds to the constraint.

If the constraint is frozen we cannot add new bounds to the constraint.

Attributes

Inherited from:
ConstraintHandling
protected var homogenizeArgs: Boolean

If set, align arguments S1, S2when taking the glb T1 { X = S1 } & T2 { X = S2 } of a constraint upper bound for some type parameter. Aligning means computing S1 =:= S2 which may change the current constraint. See note in TypeComparer#distributeAnd.

If set, align arguments S1, S2when taking the glb T1 { X = S1 } & T2 { X = S2 } of a constraint upper bound for some type parameter. Aligning means computing S1 =:= S2 which may change the current constraint. See note in TypeComparer#distributeAnd.

Attributes

Inherited from:
ConstraintHandling

Attributes

Inherited from:
ConstraintHandling

The sameLevel nesting depth from which on we want to keep track of isSameTypes suucesses using sames

The sameLevel nesting depth from which on we want to keep track of isSameTypes suucesses using sames

Attributes

Inherited from:
TypeComparer