trait ConstraintHandling

Methods for adding constraints and solving them.

What goes into a Constraint as opposed to a ConstrainHandler?

Constraint code is purely functional: Operations get constraints and produce new ones. Constraint code does not have access to a type-comparer. Anything regarding lubs and glbs has to be done elsewhere.

By comparison: Constraint handlers are parts of type comparers and can use their functionality. Constraint handlers update the current constraint as a side effect.

Constructors

Members

[+] private var addConstraintInvocations : Int
[+] protected var alwaysFluid : Boolean
[+] protected var comparedPolyTypes : Set [ PolyType ]

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

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

[+] implicit val ctx : Context
[+] 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.

[+] val state : TyperState
[+] protected def addConstraint ( param: PolyParam , bound: Type , fromBelow: Boolean ) : 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 s...

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.

[+] private def addConstraintInvocations_= ( x$1: Int ) : Unit
[+] protected def addLess ( p1: PolyParam , p2: PolyParam ) : Boolean
[+] protected def addLowerBound ( param: PolyParam , bound: Type ) : Boolean
[+] private def addOneBound ( param: PolyParam , bound: Type , isUpper: Boolean ) : Boolean
[+] def addToConstraint ( pt: PolyType , tvars: List [ TypeVar ] ) : Unit

Add polytype pt, possibly with type variables tvars, to current constraint and propagate all bounds.

Add polytype pt, possibly with type variables tvars, to current constraint and propagate all bounds.

[+] protected def addUpperBound ( param: PolyParam , bound: Type ) : Boolean
[+] protected def alwaysFluid_= ( x$1: Boolean ) : Unit
[+] final def approximation ( param: PolyParam , fromBelow: Boolean ) : 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...

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. However, any occurrences of the parameter in a refinement somewhere in the bound are removed. Also wildcard types in bounds are approximated by their upper or lower bounds. (Such occurrences can arise for F-bounded types). The constraint is left unchanged.

[+] final def bounds ( param: PolyParam ) : TypeBounds

The current bounds of type parameter param

The current bounds of type parameter param

[+] final def canConstrain ( param: PolyParam ) : Boolean

Can param be constrained with new bounds?

Can param be constrained with new bounds?

[+] def checkPropagated ( msg: => String ) ( result: Boolean ) : Boolean

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

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

[+] protected def comparedPolyTypes_= ( x$1: Set [ PolyType ] ) : Unit

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

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

[+] def fluidly ( op: => T ) : T

Perform op in a mode where all attempts to set frozen to true are ignored

Perform op in a mode where all attempts to set frozen to true are ignored

[+] protected def frozenConstraint_= ( x$1: Boolean ) : Unit

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.

[+] def instanceType ( param: PolyParam , fromBelow: Boolean ) : 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...

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.

[+] protected def isSameType ( tp1: Type , tp2: Type ) : Boolean
[+] final def isSameTypeWhenFrozen ( tp1: Type , tp2: Type ) : Boolean
[+] protected final def isSatisfiable : 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.

[+] protected def isSubType ( tp1: Type , tp2: Type ) : Boolean
[+] final def isSubTypeWhenFrozen ( tp1: Type , tp2: Type ) : Boolean
[+] protected final def subsumes ( c1: Constraint , c2: Constraint , pre: Constraint ) : 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:

c1 defines p with bounds p...

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, possibly narrowing it with further bounds.

[+] protected def tryInstantiate ( param: PolyParam , tp: Type ) : Boolean

Instantiate param to tp if the constraint stays satisfiable

Instantiate param to tp if the constraint stays satisfiable

[+] private def unify ( p1: PolyParam , p2: PolyParam ) : Boolean

Make p2 = p1, transfer all bounds of p2 to p1

Make p2 = p1, transfer all bounds of p2 to p1