Skip to content

Commit 4c44e64

Browse files
committed
Simplifications
1 parent 4523a6f commit 4c44e64

File tree

2 files changed

+23
-34
lines changed

2 files changed

+23
-34
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,17 +1197,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
11971197
)
11981198
end typedIf
11991199

1200-
/** Decompose function prototype into a list of parameter prototypes, an optional list
1201-
* describing whether the parameter prototypes come from WildcardTypes, and a result prototype
1202-
* tree, using WildcardTypes where a type is not known.
1200+
/** Decompose function prototype into a list of parameter prototypes and a result
1201+
* prototype tree, using WildcardTypes where a type is not known.
12031202
* For the result type we do this even if the expected type is not fully
12041203
* defined, which is a bit of a hack. But it's needed to make the following work
12051204
* (see typers.scala and printers/PlainPrinter.scala for examples).
12061205
*
12071206
* def double(x: Char): String = s"$x$x"
12081207
* "abc" flatMap double
12091208
*/
1210-
private def decomposeProtoFunction(pt: Type, defaultArity: Int, pos: SrcPos)(using Context): (List[Type], Option[List[Boolean]], untpd.Tree) = {
1209+
private def decomposeProtoFunction(pt: Type, defaultArity: Int, pos: SrcPos)(using Context): (List[Type], untpd.Tree) = {
12111210
def typeTree(tp: Type) = tp match {
12121211
case _: WildcardType => new untpd.InferredTypeTree()
12131212
case _ => untpd.InferredTypeTree(tp)
@@ -1235,26 +1234,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
12351234
// if expected parameter type(s) are wildcards, approximate from below.
12361235
// if expected result type is a wildcard, approximate from above.
12371236
// this can type the greatest set of admissible closures.
1238-
// However, we still keep the information on whether expected parameter types were
1239-
// wildcards, in case of types inferred from target being more specific
1240-
1241-
val fromWildcards = pt1.argInfos.init.map{
1242-
case bounds @ TypeBounds(nt, at) if nt == defn.NothingType && at == defn.AnyType => true
1243-
case bounds => false
1244-
}
1245-
1246-
(pt1.argTypesLo.init, Some(fromWildcards), typeTree(interpolateWildcards(pt1.argTypesHi.last)))
1237+
(pt1.argTypesLo.init, typeTree(interpolateWildcards(pt1.argTypesHi.last)))
12471238
case RefinedType(parent, nme.apply, mt @ MethodTpe(_, formals, restpe))
12481239
if defn.isNonRefinedFunction(parent) && formals.length == defaultArity =>
1249-
(formals, None, untpd.DependentTypeTree(syms => restpe.substParams(mt, syms.map(_.termRef))))
1240+
(formals, untpd.DependentTypeTree(syms => restpe.substParams(mt, syms.map(_.termRef))))
12501241
case SAMType(mt @ MethodTpe(_, formals, restpe)) =>
1251-
(formals, None,
1242+
(formals,
12521243
if (mt.isResultDependent)
12531244
untpd.DependentTypeTree(syms => restpe.substParams(mt, syms.map(_.termRef)))
12541245
else
12551246
typeTree(restpe))
12561247
case _ =>
1257-
(List.tabulate(defaultArity)(alwaysWildcardType), None, untpd.TypeTree())
1248+
(List.tabulate(defaultArity)(alwaysWildcardType), untpd.TypeTree())
12581249
}
12591250
}
12601251
}
@@ -1276,7 +1267,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
12761267
* If both attempts fail, return `NoType`.
12771268
*/
12781269
def inferredFromTarget(
1279-
param: untpd.ValDef, formal: Type, calleeType: Type, paramIndex: Name => Int, isWildcardParam: Boolean)(using Context): Type =
1270+
param: untpd.ValDef, formal: Type, calleeType: Type, paramIndex: Name => Int)(using Context): Type =
12801271
val target = calleeType.widen match
12811272
case mtpe: MethodType =>
12821273
val pos = paramIndex(param.name)
@@ -1289,7 +1280,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
12891280
else NoType
12901281
case _ => NoType
12911282
if target.exists then formal <:< target
1292-
if !isWildcardParam && isFullyDefined(formal, ForceDegree.flipBottom) then formal
1283+
if !formal.isExactlyNothing && isFullyDefined(formal, ForceDegree.flipBottom) then formal
12931284
else if target.exists && isFullyDefined(target, ForceDegree.flipBottom) then target
12941285
else NoType
12951286

@@ -1466,7 +1457,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
14661457
case _ =>
14671458
}
14681459

1469-
val (protoFormals, areWildcardParams, resultTpt) = decomposeProtoFunction(pt, params.length, tree.srcPos)
1460+
val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length, tree.srcPos)
14701461

14711462
def protoFormal(i: Int): Type =
14721463
if (protoFormals.length == params.length) protoFormals(i)
@@ -1509,21 +1500,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
15091500
if (!param.tpt.isEmpty) param
15101501
else
15111502
val formal = protoFormal(i)
1512-
val isWildcardParam = areWildcardParams.map(list => if i < list.length then list(i) else false).getOrElse(false)
15131503
val knownFormal = isFullyDefined(formal, ForceDegree.failBottom)
1514-
// Since decomposeProtoFunction eagerly approximates function arguments
1515-
// from below, then in the case that the argument was also identified as
1516-
// a wildcard type we try to prioritize inferring from target, if possible.
1517-
// See issue 16405 (tests/run/16405.scala)
1518-
val (usingFormal, paramType) =
1519-
if !isWildcardParam && knownFormal then (true, formal)
1520-
else
1521-
val fromTarget = inferredFromTarget(param, formal, calleeType, paramIndex, isWildcardParam)
1522-
if fromTarget.exists then (false, fromTarget)
1523-
else if knownFormal then (true, formal)
1524-
else (false, errorType(AnonymousFunctionMissingParamType(param, tree, formal), param.srcPos))
1504+
// If the expected formal is Nothin, try to prioritize inferring from target,
1505+
// if possible. See issue 16405 (tests/run/16405.scala)
1506+
val paramType =
1507+
if knownFormal && !formal.isExactlyNothing then
1508+
formal
1509+
else
1510+
inferredFromTarget(param, formal, calleeType, paramIndex).orElse(
1511+
if knownFormal then formal
1512+
else errorType(AnonymousFunctionMissingParamType(param, tree, formal), param.srcPos)
1513+
)
15251514
val paramTpt = untpd.TypedSplice(
1526-
(if usingFormal then InferredTypeTree() else untpd.TypeTree())
1515+
(if knownFormal then InferredTypeTree() else untpd.TypeTree())
15271516
.withType(paramType.translateFromRepeated(toArray = false))
15281517
.withSpan(param.span.endPos)
15291518
)
@@ -1594,7 +1583,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
15941583
typedMatchFinish(tree, tpd.EmptyTree, defn.ImplicitScrutineeTypeRef, cases1, pt)
15951584
}
15961585
else {
1597-
val (protoFormals, _, _) = decomposeProtoFunction(pt, 1, tree.srcPos)
1586+
val (protoFormals, _) = decomposeProtoFunction(pt, 1, tree.srcPos)
15981587
val checkMode =
15991588
if (pt.isRef(defn.PartialFunctionClass)) desugar.MatchCheck.None
16001589
else desugar.MatchCheck.Exhaustive

tests/neg/i8012.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ class C extends Q[?] // error: Type argument must be fully defined
99

1010
object O {
1111
def m(i: Int): Int = i
12-
val x: Q[_] = m // error: result type of lambda is an underspecified SAM type Q[?]
12+
val x: Q[_] = m
1313
}

0 commit comments

Comments
 (0)