scala.tools.nsc.typechecker.Infer
[Martin] Can someone comment this please? I have no idea what it's for and the code is not exactly readable.
Retract arguments that were inferred to Nothing because inference failed.
Retract arguments that were inferred to Nothing because inference failed. Correct types for repeated params.
We detect Nothing-due-to-failure by only retracting a parameter if either:
restpe
restpe == WildcardType
Retracted parameters are mapped to None. TODO:
Rewrite for repeated param types: Map T* entries to Seq[T].
map from tparams to inferred arg, if inference was successful, tparams that map to None are considered left undetermined
type parameters that are inferred as scala.Nothing
and that are not covariant in restpe
are taken to be undetermined
Check that sym
is defined and accessible as a member of
tree site
with type pre
in current context.
Check that sym
is defined and accessible as a member of
tree site
with type pre
in current context.
Note: pre is not refchecked -- moreover, refchecking the resulting tree may not refcheck pre, since pre may not occur in its type (callers should wrap the result in a TypeTreeWithDeferredRefCheck)
error if arguments not within bounds.
TODO: much better error positions.
TODO: much better error positions. Kind of stuck right now because they just pass us the one tree. TODO: Eliminate inPattern, canRemedy, which have no place here.
Does tp
contain any types that cannot be checked at run-time (i.
Does tp
contain any types that cannot be checked at run-time (i.e., after erasure, will isInstanceOf[erased(tp)] imply conceptualIsInstanceOf[tp]?)
we should find a way to ask erasure: hey, is tp
going to make it through you with all of its isInstanceOf resolving powers intact?
TODO: at the very least, reduce duplication wrt checkCheckable
Collects type parameters referred to in a type.
Substitute free type variables undetparams
of polymorphic argument
expression tree
, given two prototypes strictPt
, and lenientPt
.
Substitute free type variables undetparams
of polymorphic argument
expression tree
, given two prototypes strictPt
, and lenientPt
.
strictPt
is the first attempt prototype where type parameters
are left unchanged. lenientPt
is the fall-back prototype where type
parameters are replaced by WildcardType
s. We try to instantiate
first to strictPt
and then, if this fails, to lenientPt
. If both
attempts fail, an error is produced.
Substitute free type variables undetparams
of type constructor
tree
in pattern, given prototype pt
.
Substitute free type variables undetparams
of type constructor
tree
in pattern, given prototype pt
.
the constuctor that needs to be instantiated
the undetermined type parameters
Assign tree
the symbol and type of the alternative which
matches prototype pt
, if it exists.
Assign tree
the symbol and type of the alternative which
matches prototype pt
, if it exists.
If several alternatives match pt
, take parameterless one.
If no alternative matches pt
, take the parameterless one anyway.
Infer type arguments targs
for tparams
of polymorphic expression in tree
, given prototype pt
.
Infer type arguments targs
for tparams
of polymorphic expression in tree
, given prototype pt
.
Substitute tparams
to targs
in tree
, after adjustment by adjustTypeArgs
, returning the type parameters that were not determined
If passed, infers against specified type treeTp
instead of tree.tp
.
Assign tree
the type of an alternative which is applicable
to argtpes
, and whose result type is compatible with pt
.
Assign tree
the type of an alternative which is applicable
to argtpes
, and whose result type is compatible with pt
.
If several applicable alternatives exist, drop the alternatives which use
default arguments, then select the most specialized one.
If no applicable alternative exists, and pt != WildcardType, try again
with pt = WildcardType.
Otherwise, if there is no best alternative, error.
contains the argument types. If an argument is named, as
"a = 3", the corresponding type is NamedType("a", Int)'. If the name
of some NamedType does not exist in an alternative's parameter names,
the type is replaces by
Unit, i.e. the argument is treated as an
assignment expression.
Substitute free type variables undetparams
of application
fn(args)
, given prototype pt
.
Substitute free type variables undetparams
of application
fn(args)
, given prototype pt
.
fn: the function that needs to be instantiated.
the parameters that need to be determined
the actual arguments supplied in the call.
The type parameters that remain uninstantiated, and that thus have not been substituted.
Assign tree
the type of all polymorphic alternatives
with nparams
as the number of type parameters, if it exists.
Assign tree
the type of all polymorphic alternatives
with nparams
as the number of type parameters, if it exists.
If no such polymorphic alternative exist, error.
...
Type intersection of simple type tp1 with general type tp2.
Type intersection of simple type tp1 with general type tp2. The result eliminates some redundancies.
Is type ftpe1
strictly more specific than type ftpe2
when both are alternatives in an overloaded function?
Is type ftpe1
strictly more specific than type ftpe2
when both are alternatives in an overloaded function?
...
...
...
SLS (sec:overloading-resolution)
This is overridden in the Typer.
This is overridden in the Typer.infer with some logic, but since that's the only place in the compiler an Inferencer is ever created, I suggest this should either be abstract or have the implementation.
Like weakly compatible but don't apply any implicit conversions yet.
Like weakly compatible but don't apply any implicit conversions yet. Used when comparing the result type of a method with its prototype.
[Martin] I think Infer is also created by Erasure, with the default implementation of isCoercible [Paulp] (Assuming the above must refer to my comment on isCoercible) Nope, I examined every occurrence of Inferencer in trunk. It appears twice as a self-type, once at its definition, and once where it is instantiated in Typers. There are no others.
% ack -A0 -B0 --no-filename '\bInferencer\b' src self: Inferencer => self: Inferencer => class Inferencer(context: Context) extends InferencerContextErrors with InferCheckable { val infer = new Inferencer(context0) {
is symbol sym1
defined in a proper subclass of symbol sym2
?
Is sym1 (or its companion class in case it is a module) a subclass of sym2 (or its companion class in case it is a module)?
don't do a () to (()) conversion for methods whose second parameter is a varargs.
don't do a () to (()) conversion for methods whose second parameter is a varargs. This is a fairly kludgey way to address #3224. We'll probably find a better way to do this by identifying tupled and n-ary methods, but thiws is something for a future major revision.
Replace any (possibly bounded) wildcard types in type tp
by existentially bound variables.
Return inferred type arguments, given type parameters, formal parameters, argument types, result type and expected result type.
Return inferred type arguments, given type parameters, formal parameters,
argument types, result type and expected result type.
If this is not possible, throw a NoInstance
exception.
Undetermined type arguments are represented by definitions.NothingClass.tpe
.
No check that inferred parameters conform to their bounds is made here.
the type parameters of the method
the value parameter types of the method
the argument types of the application
the expected return type of the application
@see adjustTypeArgs
Return inferred proto-type arguments of function, given
its type and value parameters and result type, and a
prototype pt
for the function result.
Return inferred proto-type arguments of function, given
its type and value parameters and result type, and a
prototype pt
for the function result.
Type arguments need to be either determined precisely by
the prototype, or they are maximized, if they occur only covariantly
in the value parameter list.
If instantiation of a type parameter fails,
take WildcardType for the proto-type argument.
...
...
...
...
Try inference twice, once without views and once with views, unless views are already disabled.
Try inference twice, once without views and once with views, unless views are already disabled.
...
(inferencer: StringAdd).self
(inferencer: StringFormat).self
(inferencer: ArrowAssoc[Analyzer.Inferencer]).x
(Since version 2.10.0) Use leftOfArrow
instead
(inferencer: Ensuring[Analyzer.Inferencer]).x
(Since version 2.10.0) Use resultOfEnsuring
instead
The context-dependent inferencer part