Dotty Documentation


object Inferencing

[-] Constructors

[-] Members

[+] private class IsFullyDefinedAccumulator

The accumulator which forces type variables using the policy encoded in force and returns whether the type is fully defined. The direction in which a type variable is instantiated is determined as follows: 1. T is minimized if the constraint over T is only from below (i.e. constrained lower bound != given lower bound and constrained upper bound == given upper bound). 2. T is maximized if the constraint over T is only from above (i.e. constrained upper bound != given upper bound and constrained lower bound == given lower bound). If (1) and (2) do not apply: 3. T is maximized if it appears only contravariantly in the given type. 4. T is minimized in all other cases.

The instantiation is done in two phases: 1st Phase: Try to instantiate minimizable type variables to their lower bound. Record whether successful. 2nd Phase: If first phase was successful, instantiate all remaining type variables to their upper bound.

[+] type VarianceMap = SimpleMap [ TypeVar, Integer ]
[+] def companionRef ( tp: Type ) ( implicit ctx: Context ) : Type

Following type aliases and stripping refinements and annotations, if one arrives at a class type reference where the class has a companion module, a reference to that companion module. Otherwise NoType

[+] def fullyDefinedType ( tp: Type , what: String , pos: Position ) ( implicit ctx: Context ) : Type

The fully defined type, where all type variables are forced. Throws an error if type contains wildcards.

[+] def inferTypeParams ( tree: Tree , pt: Type ) ( implicit ctx: Context ) : Tree

If tree has a type lambda type, infer its type parameters by comparing with expected type pt

[+] private def instDirection ( param: TypeParamRef ) ( implicit ctx: Context ) : Int

The instantiation direction for given poly param computed from the constraint:

[+] def instantiateSelected ( tp: Type , tvars: List [ Type ] ) ( implicit ctx: Context ) : Unit

Instantiate selected type variables tvars in type tp

[+] def interpolateUndetVars ( tree: Tree , ownedBy: Symbol ) ( implicit ctx: Context ) : Unit

Interpolate those undetermined type variables in the widened type of this tree which are introduced by type application contained in the tree. If such a variable appears covariantly in type tp or does not appear at all, approximate it by its lower bound. Otherwise, if it appears contravariantly in type tp approximate it by its upper bound.

[+] def isFullyDefined ( tp: Type , force: Value ) ( implicit ctx: Context ) : Boolean

Is type fully defined, meaning the type does not contain wildcard types or uninstantiated type variables. As a side effect, this will minimize any uninstantiated type variables, according to the given force degree, but only if the overall result of isFullyDefined is true. Variables that are successfully minimized do not count as uninstantiated.

[+] def maximizeType ( tp: Type ) ( implicit ctx: Context ) : Option [ TypeVar ]

Instantiate undetermined type variables to that type tp is maximized and return None. If this is not possible, because a non-variant typevar is not uniquely determined, return that typevar in a Some.

[+] def tvarsInParams ( tree: Tree ) ( implicit ctx: Context ) : List [ TypeVar ]

The list of uninstantiated type variables bound by some prefix of type T which occur in at least one formal parameter type of a prefix application. Considered prefixes are: - The function f of an application node f(e1, .., en) - The function f of a type application node f[T1, ..., Tn] - The prefix p of a selection p.f. - The result expression e of a block {s1; .. sn; e}.

[+] private def variances ( tp: Type , include: TypeVar => Boolean ) ( implicit ctx: Context ) : VarianceMap

All occurrences of type vars in this type that satisfy predicate include mapped to their variances (-1/0/1) in this type, where -1 means: only covariant occurrences +1 means: only covariant occurrences 0 means: mixed or non-variant occurrences

Note: We intentionally use a relaxed version of variance here, where the variance does not change under a prefix of a named type (the strict version makes prefixes invariant). This turns out to be better for type inference. In a nutshell, if a type variable occurs like this:

(U? >: x.type) # T

we want to instantiate U to x.type right away. No need to wait further.