Skip to content

Commit e33e20a

Browse files
committed
Fixup for 80f977d
1 parent 80f977d commit e33e20a

File tree

4 files changed

+38
-38
lines changed

4 files changed

+38
-38
lines changed

src/dotty/tools/dotc/core/Mode.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,5 @@ object Mode {
8484
/** Use Scala2 scheme for overloading and implicit resolution */
8585
val OldOverloadingResolution = newMode(14, "OldOverloadingResolution")
8686

87-
/* Currently inside a potential scala.Dynamic rewrite. */
88-
val IgnoreNextDynamic = newMode(15, "IgnoreNextDynamic")
89-
9087
val PatternOrType = Pattern | Type
9188
}

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -542,22 +542,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
542542

543543
def realApply(implicit ctx: Context): Tree = track("realApply") {
544544
var proto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx(tree))
545-
546-
/* In the default case we type using Mode.IgnoreNextDynamic because fun1 might be a Select(foo, bar) where foo is of
547-
* type scala.Dynamic and bar is not one of its members. In which case the following transformation will be tried:
548-
* foo.bar(baz0, baz1, ...) ~~> foo.applyDynamic(bar)(baz0, baz1, ...)
549-
* Mode.IgnoreNextDynamic will ensure that Apply(Select(foo, bar), baz) is not transformed
550-
* into foo.selectDynamic(bar).apply(args).
551-
* We remove Mode.IgnoreNextDynamic if the name of the called method if is one of the scala.Dynamic methods or
552-
* if this node was generated by an assign (see typedAssign).
553-
* See: Dynamic.scala
554-
*/
555-
def generatedByTypedAssign(name: Name) = name == nme.update && ctx.mode.is(Mode.IgnoreNextDynamic)
556-
val ctx1 = tree.fun match {
557-
case Select(_, name) if isDynamicMethod(name) || generatedByTypedAssign(name) => ctx.retractMode(Mode.IgnoreNextDynamic)
558-
case _ => ctx.addMode(Mode.IgnoreNextDynamic)
559-
}
560-
val fun1 = typedExpr(tree.fun, proto)(ctx1)
545+
val fun1 = typedExpr(tree.fun, proto)
561546

562547
// Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as
563548
// a side effect in adapt. If it was, we assume the tupled proto-type in the rest of the application.

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,31 @@ object ProtoTypes {
430430
(if (theMap != null) theMap else new WildApproxMap).mapOver(tp)
431431
}
432432

433+
trait AssigningProto extends ProtoType
434+
435+
/** A prototype for expressions that appear in the lhs position of an assign
436+
*
437+
* lhs = (rhs: resType)
438+
*/
439+
case class AssignProto(lhs: untpd.Tree, rhsType: Type, typer: Typer)(implicit ctx: Context)
440+
extends UncachedGroundType with AssigningProto {
441+
override def resultType(implicit ctx: Context) = rhsType
442+
443+
def isMatchedBy(tp: Type)(implicit ctx: Context) = ???
444+
445+
def fold[T](x: T, ta: TypeAccumulator[T])(implicit ctx: Context): T = ta(x, rhsType)
446+
447+
def map(tm: TypeMap)(implicit ctx: Context): ProtoType = derivedAssignProto(lhs, tm(rhsType), typer)
448+
449+
def derivedAssignProto(lhs: untpd.Tree, rhsType: Type, typer: Typer) =
450+
if ((lhs eq this.lhs) && (rhsType eq this.resultType) && (typer eq this.typer)) this
451+
else new AssignProto(lhs, rhsType, typer)
452+
453+
override def toString = s"AssignProto($lhs = (rhs: $resultType))"
454+
455+
override def deepenProto(implicit ctx: Context) = derivedAssignProto(lhs, resultType.deepenProto, typer)
456+
}
457+
433458
private[ProtoTypes] class WildApproxMap(implicit ctx: Context) extends TypeMap {
434459
def apply(tp: Type) = wildApprox(tp, this)
435460
}

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

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,17 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
315315

316316
def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = track("typedSelect") {
317317
def asSelect(implicit ctx: Context): Tree = {
318-
val qual1 = typedExpr(tree.qualifier, selectionProto(tree.name, pt, this))(ctx.retractMode(Mode.IgnoreNextDynamic))
318+
val qual1 = typedExpr(tree.qualifier, selectionProto(tree.name, pt, this))
319319
if (tree.name.isTypeName) checkStable(qual1.tpe, qual1.pos)
320320
val select = typedSelect(tree, pt, qual1)
321-
if (select.tpe == TryDynamicCallType && !ctx.mode.is(Mode.IgnoreNextDynamic)) {
322-
typedDynamicSelect(tree, pt)
323-
} else select
321+
if (select.tpe != TryDynamicCallType) {
322+
select
323+
} else {
324+
pt match {
325+
case _: FunProto | _: AssignProto => select
326+
case _ => typedDynamicSelect(tree, pt)
327+
}
328+
}
324329
}
325330

326331
def asJavaSelectFromTypeTree(implicit ctx: Context): Tree = {
@@ -475,14 +480,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
475480
def typedAssign(tree: untpd.Assign, pt: Type)(implicit ctx: Context) = track("typedAssign") {
476481
tree.lhs match {
477482
case lhs @ Apply(fn, args) =>
478-
/* We type using Mode.IgnoreNextDynamic because fn might be a Select(foo, bar) where foo is of type
479-
* scala.Dynamic and bar is not one of its members. In which case the following transformation will be tried:
480-
* foo.bar(baz) = quux ~~> foo.selectDynamic("bar").update(baz, quux)
481-
* Mode.IgnoreNextDynamic will ensure that Apply(Select(fn, update), args) is not transformed
482-
* into fn.applyDynamic(update)(args) and will only transform the contents of fn if needed.
483-
* See: Dynamic.scala
484-
*/
485-
typed(cpy.Apply(lhs)(untpd.Select(fn, nme.update), args :+ tree.rhs), pt)(ctx.addMode(Mode.IgnoreNextDynamic))
483+
typed(cpy.Apply(lhs)(untpd.Select(fn, nme.update), args :+ tree.rhs), pt)
486484
case untpd.TypedSplice(Apply(MaybePoly(Select(fn, app), targs), args)) if app == nme.apply =>
487485
val rawUpdate: untpd.Tree = untpd.Select(untpd.TypedSplice(fn), nme.update)
488486
val wrappedUpdate =
@@ -491,13 +489,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
491489
val appliedUpdate = cpy.Apply(fn)(wrappedUpdate, (args map untpd.TypedSplice) :+ tree.rhs)
492490
typed(appliedUpdate, pt)
493491
case lhs =>
494-
/* We type using Mode.IgnoreNextDynamic because this tree might be transformed with:
495-
* foo.bar = baz ~~> foo.updateDynamic("bar")(baz)
496-
* Mode.IgnoreNextDynamic will ensure that Assign(Select(foo, bar), baz) will not be transformed
497-
* into foo.selectDynamic(bar) = baz during the typing of the lhs.
498-
* See: Dynamic.scala
499-
*/
500-
val lhsCore = typedUnadapted(lhs)(ctx.addMode(Mode.IgnoreNextDynamic))
492+
val proto = new AssignProto(tree.lhs, pt, this)(argCtx(tree))
493+
val lhsCore = typedUnadapted(lhs, proto)
501494
def lhs1 = typed(untpd.TypedSplice(lhsCore))
502495
def canAssign(sym: Symbol) = // allow assignments from the primary constructor to class fields
503496
sym.is(Mutable, butNot = Accessor) ||

0 commit comments

Comments
 (0)