Skip to content

Fix #7879: Turn test case into neg test #7904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 32 additions & 31 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -955,35 +955,19 @@ class Typer extends Namer
case _ => false
}

pt match {
case pt: TypeVar if untpd.isFunctionWithUnknownParamType(tree) =>
// try to instantiate `pt` if this is possible. If it does not
// work the error will be reported later in `inferredParam`,
// when we try to infer the parameter type.
isFullyDefined(pt, ForceDegree.noBottom)
case _ =>
}

val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length)
/** The function body to be returned in the closure. Can become a TypedSplice
* of a typed expression if this is necessary to infer a parameter type.
*/
var fnBody = tree.body

def refersTo(arg: untpd.Tree, param: untpd.ValDef): Boolean = arg match {
case Ident(name) => name == param.name
case _ => false
}

/** The function body to be returned in the closure. Can become a TypedSplice
* of a typed expression if this is necessary to infer a parameter type.
*/
var fnBody = tree.body

/** A map from parameter names to unique positions where the parameter
* appears in the argument list of an application.
*/
var paramIndex = Map[Name, Int]()

/** If parameter `param` appears exactly once as an argument in `args`,
* the singleton list consisting of its position in `args`, otherwise `Nil`.
*/
* the singleton list consisting of its position in `args`, otherwise `Nil`.
*/
def paramIndices(param: untpd.ValDef, args: List[untpd.Tree]): List[Int] = {
def loop(args: List[untpd.Tree], start: Int): List[Int] = args match {
case arg :: args1 =>
Expand All @@ -995,15 +979,20 @@ class Typer extends Namer
if (allIndices.length == 1) allIndices else Nil
}

/** If function is of the form
* (x1, ..., xN) => f(... x1, ..., XN, ...)
* where each `xi` occurs exactly once in the argument list of `f` (in
* any order), the type of `f`, otherwise NoType.
* Updates `fnBody` and `paramIndex` as a side effect.
* @post: If result exists, `paramIndex` is defined for the name of
* every parameter in `params`.
*/
def calleeType: Type = fnBody match {
/** A map from parameter names to unique positions where the parameter
* appears in the argument list of an application.
*/
var paramIndex = Map[Name, Int]()

/** If function is of the form
* (x1, ..., xN) => f(... x1, ..., XN, ...)
* where each `xi` occurs exactly once in the argument list of `f` (in
* any order), the type of `f`, otherwise NoType.
* Updates `fnBody` and `paramIndex` as a side effect.
* @post: If result exists, `paramIndex` is defined for the name of
* every parameter in `params`.
*/
lazy val calleeType: Type = fnBody match {
case app @ Apply(expr, args) =>
paramIndex = {
for (param <- params; idx <- paramIndices(param, args))
Expand All @@ -1025,6 +1014,18 @@ class Typer extends Namer
NoType
}

pt match {
case pt: TypeVar
if untpd.isFunctionWithUnknownParamType(tree) && !calleeType.exists =>
// try to instantiate `pt` if this is possible. If it does not
// work the error will be reported later in `inferredParam`,
// when we try to infer the parameter type.
isFullyDefined(pt, ForceDegree.noBottom)
case _ =>
}

val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length)

/** Two attempts: First, if expected type is fully defined pick this one.
* Second, if function is of the form
* (x1, ..., xN) => f(... x1, ..., XN, ...)
Expand Down
4 changes: 4 additions & 0 deletions tests/neg/i7879.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
object Test {
val head1 +: _ = List(1).view
val _: Int = head1 // error
}
7 changes: 7 additions & 0 deletions tests/pos/i7893.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object Test {
val l1 = List(Predef.identity[Int](_))
val lc1: List[Int => Int] = l1

val l2 = List(Predef.identity[Int])
val lc2: List[Int => Int] = l2
}