Skip to content

Commit 573b664

Browse files
committed
Ignore all kinds of ProtoTypes instead of just AppliedProtos
In blocks, conditionals and matches we mapped applied prototypes to WildcardTypes in order to force eta expansions. With extension methods the same problem arises for SelectionProtos as well. Furthermore, it makes to sense to propagate a ViewProto into a local context. So the consistent thing to do is to map all kinds of ProtoTypes to WildcardTypes in these situations. This fails one line in run/implicitsFuns.scala, which, however is of dubious value. (The line requires a manually inserted `apply` to propagate a `given` argument into an if-then-else, circumvening the previous "no applies propagated" strategy.
1 parent fae6009 commit 573b664

File tree

5 files changed

+16
-13
lines changed

5 files changed

+16
-13
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,9 +1249,6 @@ object Types {
12491249
case _ => if (isRepeatedParam) this.argTypesHi.head else this
12501250
}
12511251

1252-
/** If this is a FunProto or PolyProto, WildcardType, otherwise this. */
1253-
def notApplied: Type = this
1254-
12551252
// ----- Normalizing typerefs over refined types ----------------------------
12561253

12571254
/** If this normalizes* to a refinement type that has a refinement for `name` (which might be followed
@@ -1433,6 +1430,9 @@ object Types {
14331430
/** If this is an ignored proto type, its underlying type, otherwise the type itself */
14341431
def revealIgnored: Type = this
14351432

1433+
/** If this is a proto type, the ignored version, otherwise the type itself */
1434+
def dropIfProto: Type = this
1435+
14361436
// ----- Substitutions -----------------------------------------------------
14371437

14381438
/** Substitute all types that refer in their symbol attribute to
@@ -1733,6 +1733,8 @@ object Types {
17331733
* captures the given context `ctx`.
17341734
*/
17351735
def withContext(ctx: Context): ProtoType = this
1736+
1737+
override def dropIfProto = WildcardType
17361738
}
17371739

17381740
/** Implementations of this trait cache the results of `narrow`. */

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ object ProtoTypes {
260260
if ((args eq this.args) && (resultType eq this.resultType) && (typer eq this.typer)) this
261261
else new FunProto(args, resultType)(typer, isGivenApply)
262262

263-
override def notApplied: Type = WildcardType
264-
265263
/** @return True if all arguments have types.
266264
*/
267265
def allArgTypesAreCurrent()(implicit ctx: Context): Boolean =
@@ -453,8 +451,6 @@ object ProtoTypes {
453451
if ((targs eq this.targs) && (resType eq this.resType)) this
454452
else PolyProto(targs, resType)
455453

456-
override def notApplied: Type = WildcardType
457-
458454
def map(tm: TypeMap)(implicit ctx: Context): PolyProto =
459455
derivedPolyProto(targs, tm(resultType))
460456

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ class Typer extends Namer
712712

713713
def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context): Tree = track("typedBlock") {
714714
val (exprCtx, stats1) = typedBlockStats(tree.stats)
715-
val expr1 = typedExpr(tree.expr, pt.notApplied)(exprCtx)
715+
val expr1 = typedExpr(tree.expr, pt.dropIfProto)(exprCtx)
716716
ensureNoLocalRefs(
717717
cpy.Block(tree)(stats1, expr1).withType(expr1.tpe), pt, localSyms(stats1))
718718
}
@@ -766,7 +766,7 @@ class Typer extends Namer
766766
}
767767
else {
768768
val thenp1 :: elsep1 :: Nil = harmonic(harmonize, pt)(
769-
(tree.thenp :: tree.elsep :: Nil).map(typed(_, pt.notApplied)))
769+
(tree.thenp :: tree.elsep :: Nil).map(typed(_, pt.dropIfProto)))
770770
assignType(cpy.If(tree)(cond1, thenp1, elsep1), thenp1, elsep1)
771771
}
772772
}
@@ -1068,7 +1068,7 @@ class Typer extends Namer
10681068

10691069
// Overridden in InlineTyper for inline matches
10701070
def typedMatchFinish(tree: untpd.Match, sel: Tree, wideSelType: Type, cases: List[untpd.CaseDef], pt: Type)(implicit ctx: Context): Tree = {
1071-
val cases1 = harmonic(harmonize, pt)(typedCases(cases, wideSelType, pt.notApplied))
1071+
val cases1 = harmonic(harmonize, pt)(typedCases(cases, wideSelType, pt.dropIfProto))
10721072
.asInstanceOf[List[CaseDef]]
10731073
assignType(cpy.Match(tree)(sel, cases1), sel, cases1)
10741074
}
@@ -1193,8 +1193,8 @@ class Typer extends Namer
11931193

11941194
def typedTry(tree: untpd.Try, pt: Type)(implicit ctx: Context): Try = track("typedTry") {
11951195
val expr2 :: cases2x = harmonic(harmonize, pt) {
1196-
val expr1 = typed(tree.expr, pt.notApplied)
1197-
val cases1 = typedCases(tree.cases, defn.ThrowableType, pt.notApplied)
1196+
val expr1 = typed(tree.expr, pt.dropIfProto)
1197+
val cases1 = typedCases(tree.cases, defn.ThrowableType, pt.dropIfProto)
11981198
expr1 :: cases1
11991199
}
12001200
val finalizer1 = typed(tree.finalizer, defn.UnitType)

tests/pos/implicit-scope.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ object A {
1111

1212
delegate FlagOps {
1313
def (xs: FlagSet) bits: Long = opaques.toBits(xs)
14+
def (xs: FlagSet) | (ys: FlagSet): FlagSet = FlagSet(xs.bits | ys.bits)
1415
}
1516
}
1617

@@ -22,4 +23,8 @@ object B {
2223

2324
val v: Variance = A.someFlag
2425
v.bits // OK, used to fail with: value bits is not a member of B.Variance
26+
27+
A.someFlag.bits // OK
28+
var x = 0
29+
(if (x > 0) A.someFlag else A.someFlag).bits // OK, used to fail with: value bits is not a member of ?
2530
}

tests/run/implicitFuns.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ object Test {
5656

5757
def foo(s: String): Stringly[Int] = 42
5858

59-
(if ("".isEmpty) foo("") else foo("")).apply given ""
59+
//(if ("".isEmpty) foo("") else foo("")).apply given "" // does not typecheck
6060
}
6161
}
6262

0 commit comments

Comments
 (0)