Skip to content

Commit 85bdee8

Browse files
committed
Improve choice of words in comments
1 parent a33e3b0 commit 85bdee8

File tree

2 files changed

+87
-73
lines changed

2 files changed

+87
-73
lines changed

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

Lines changed: 73 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ package typer
55
import dotty.tools.dotc.ast.Trees.ApplyKind
66
import dotty.tools.dotc.ast.tpd
77
import dotty.tools.dotc.ast.untpd
8+
import dotty.tools.dotc.ast.TreeInfo
89
import dotty.tools.dotc.core.Contexts.Context
910
import dotty.tools.dotc.core.Names.Name
11+
import dotty.tools.dotc.core.NameKinds.TempResultName
12+
1013
import core.Symbols.defn
1114

1215
/** A function computing the assignment of a lvalue.
@@ -25,6 +28,39 @@ private[typer] final class PartialAssignment[+T <: LValue](val lhs: T)(
2528

2629
end PartialAssignment
2730

31+
/** The expression of a pure value or a synthetic val definition binding a value whose evaluation
32+
* must be hoisted.
33+
*
34+
* Use this type to represent a part of a lvalue that must be evaluated before the lvalue gets
35+
* used for updating a value.
36+
*/
37+
private[typer] opaque type PossiblyHoistedValue = tpd.Tree
38+
39+
extension (self: PossiblyHoistedValue)
40+
41+
/** Returns a tree representing the value of `self`. */
42+
def value(using Context): tpd.Tree =
43+
self.definition.map((d) => tpd.Ident(d.namedType)).getOrElse(self)
44+
45+
/** Returns the synthetic val defining `self` if it is hoisted. */
46+
def definition: Option[tpd.ValDef] =
47+
self match
48+
case d: tpd.ValDef => Some(d)
49+
case _ => None
50+
51+
/** Returns a tree representing the value of `self` along with its hoisted definition, if any. */
52+
def valueAndDefinition(using Context): (tpd.Tree, Option[tpd.ValDef]) =
53+
self.definition
54+
.map((d) => (tpd.Ident(d.namedType), Some(d)))
55+
.getOrElse((self, None))
56+
57+
object PossiblyHoistedValue:
58+
59+
/** Creates a value representing the `e`'s evaluation. */
60+
def apply(e: tpd.Tree)(using Context): PossiblyHoistedValue =
61+
if tpd.exprPurity(e) >= TreeInfo.Pure then e else
62+
tpd.SyntheticValDef(TempResultName.fresh(), e)
63+
2864
/** The left-hand side of an assignment. */
2965
private[typer] sealed abstract class LValue:
3066

@@ -34,23 +70,8 @@ private[typer] sealed abstract class LValue:
3470
/** Returns a tree computing the assignment of `rhs` to this lvalue. */
3571
def formAssignment(rhs: untpd.Tree)(using Context): untpd.Tree
3672

37-
/** Returns the value of `t`, which may be an expression or a local `val` definition. */
38-
protected final def read(t: tpd.Tree)(using Context): tpd.Tree =
39-
t match
40-
case d: tpd.ValDef => tpd.Ident(d.namedType)
41-
case e => e
42-
4373
end LValue
4474

45-
private[typer] final case class UnappliedSetter(
46-
expression: untpd.Tree, locals: List[tpd.ValDef]
47-
) extends LValue:
48-
49-
def formAssignment(rhs: untpd.Tree)(using Context): untpd.Tree =
50-
untpd.Apply(expression, List(rhs))
51-
52-
end UnappliedSetter
53-
5475
/** A simple expression, typically valid on left-hand side of an `Assign` tree.
5576
*
5677
* Use this class to represent an assignment that translates to an `Assign` tree or to wrap an
@@ -75,43 +96,52 @@ end SimpleLValue
7596
* @param arguments The arguments of the partial application.
7697
*/
7798
private[typer] final case class ApplyLValue(
78-
function: tpd.Tree,
79-
arguments: List[tpd.Tree]
99+
function: ApplyLValue.Callee,
100+
arguments: List[PossiblyHoistedValue]
80101
) extends LValue:
81102

82103
val locals: List[tpd.ValDef] =
83-
(function +: arguments).collect { case d: tpd.ValDef => d }
104+
function.locals ++ (arguments.collect { case d: tpd.ValDef => d })
84105

85106
def formAssignment(rhs: untpd.Tree)(using Context): untpd.Tree =
86-
val s = untpd.TypedSplice(read(function))
87-
val t = arguments.map((a) => untpd.TypedSplice(read(a))) :+ rhs
107+
val s = function.expanded
108+
val t = arguments.map((a) => untpd.TypedSplice(a.value)) :+ rhs
88109
untpd.Apply(s, t)
89110

90-
end ApplyLValue
111+
object ApplyLValue:
91112

92-
/** A lvalue represeted by the application of a partially applied method.
93-
*
94-
* @param receiver The receiver of the partially applied method.
95-
* @param member The name of the partially applied method.
96-
* @param arguments The arguments of the partial application.
97-
*/
98-
private[typer] final case class SelectLValue(
99-
receiver: tpd.Tree,
100-
member: Name,
101-
arguments: List[tpd.Tree] = List()
102-
) extends LValue:
113+
/** The callee of a lvalue represented by a partial application. */
114+
sealed abstract class Callee:
103115

104-
def expandReceiver()(using Context): tpd.Tree =
105-
receiver match
106-
case d: tpd.ValDef => d.rhs
107-
case r => r
116+
def expanded(using Context): untpd.Tree
108117

109-
val locals: List[tpd.ValDef] =
110-
(receiver +: arguments).collect { case d: tpd.ValDef => d }
118+
/** Returns the local `val` definitions composing this lvalue. */
119+
def locals: List[tpd.ValDef]
111120

112-
def formAssignment(rhs: untpd.Tree)(using Context): untpd.Tree =
113-
val s = untpd.Select(untpd.TypedSplice(read(receiver)), member)
114-
val t = arguments.map((a) => untpd.TypedSplice(read(a))) :+ rhs
115-
untpd.Apply(s, t)
121+
object Callee:
122+
123+
def apply(receiver: tpd.Tree)(using Context): Typed =
124+
Typed(PossiblyHoistedValue(receiver), None)
125+
126+
def apply(receiver: tpd.Tree, member: Name)(using Context): Typed =
127+
Typed(PossiblyHoistedValue(receiver), Some(member))
116128

117-
end SelectLValue
129+
/** A function representing a lvalue. */
130+
final case class Typed(receiver: PossiblyHoistedValue, member: Option[Name]) extends Callee:
131+
132+
def expanded(using Context): untpd.Tree =
133+
val s = untpd.TypedSplice(receiver.value)
134+
member.map((m) => untpd.Select(s, m)).getOrElse(s)
135+
136+
def locals: List[tpd.ValDef] =
137+
receiver.definition.toList
138+
139+
/** The untyped expression of a function representing a lvalue along with its captures. */
140+
final case class Untyped(value: untpd.Tree, locals: List[tpd.ValDef]) extends Callee:
141+
142+
def expanded(using Context): untpd.Tree =
143+
value
144+
145+
end Callee
146+
147+
end ApplyLValue

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

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,50 +1297,34 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
12971297
assignType(cpy.NamedArg(tree)(tree.name, arg1), arg1)
12981298
}
12991299

1300-
/** Returns `e` if evaluating `e` doesn't cause any side effect. Otherwise, returns a synthethic
1301-
* val definition binding the result of `e`.
1302-
*/
1303-
def temporary(e: tpd.Tree)(using Context): tpd.Tree =
1304-
if exprPurity(e) >= TreeInfo.Pure then
1305-
e
1306-
else
1307-
tpd.SyntheticValDef(TempResultName.fresh(), e)
1308-
1309-
/** Returns `(n, Some(d))` where `n` is the name of a synthetic val `d` that binds the result of
1310-
* `e` if evaluating `e` is impure. Otherwise, returns `(e, None)`.
1311-
*/
1312-
def hoisted(e: tpd.Tree)(using Context): (tpd.Tree, Option[tpd.ValDef]) =
1313-
if exprPurity(e) >= TreeInfo.Pure then
1314-
(e, None)
1315-
else
1316-
val d = tpd.SyntheticValDef(TempResultName.fresh(), e)
1317-
(tpd.Ident(d.namedType), Some(d))
1318-
1319-
/** Returns a builder for computing trees representing assignments to `lhs`. */
1300+
/** Returns a builder for making trees representing assignments to `lhs`. */
13201301
def formPartialAssignmentTo(lhs: untpd.Tree)(using Context): PartialAssignment[LValue] =
13211302
lhs match
13221303
case lhs @ Apply(f, as) =>
13231304
// LHS is an application `f(a1, ..., an)` that desugars to `f.update(a1, ..., an, rhs)`.
1324-
val v = SelectLValue(temporary(typed(f)), nme.update, as.map((a) => temporary(typed(a))))
1325-
PartialAssignment(v) { (l, r) => l.formAssignment(r) }
1305+
val arguments = as.map((a) => PossiblyHoistedValue(typed(a)))
1306+
val lvalue = ApplyLValue(ApplyLValue.Callee(typed(f), nme.update), arguments)
1307+
PartialAssignment(lvalue) { (l, r) => l.formAssignment(r) }
13261308

13271309
case untpd.TypedSplice(Apply(MaybePoly(Select(fn, app), tas), as)) if app == nme.apply =>
13281310
if tas.isEmpty then
13291311
// No type arguments: fall back to a regular update.
1330-
val v = SelectLValue(temporary(fn), nme.update, as.map((a) => temporary(typed(a))))
1331-
PartialAssignment(v) { (l, r) => l.formAssignment(r) }
1312+
val arguments = as.map(PossiblyHoistedValue.apply)
1313+
val lvalue = ApplyLValue(ApplyLValue.Callee(fn, nme.update), arguments)
1314+
PartialAssignment(lvalue) { (l, r) => l.formAssignment(r) }
13321315
else
13331316
// Type arguments are present; the LHS requires a type application.
13341317
val s: untpd.Tree = untpd.Select(untpd.TypedSplice(fn), nme.update)
13351318
val t = untpd.TypeApply(s, tas.map((ta) => untpd.TypedSplice(ta)))
1336-
val v = ApplyLValue(temporary(typed(t)), as.map((a) => temporary(typed(a))))
1337-
PartialAssignment(v) { (l, r) => l.formAssignment(r) }
1319+
val arguments = as.map(PossiblyHoistedValue.apply)
1320+
val lvalue = ApplyLValue(ApplyLValue.Callee(typed(t)), arguments)
1321+
PartialAssignment(lvalue) { (l, r) => l.formAssignment(r) }
13381322

13391323
case _ =>
13401324
formPartialAssignmentToNonApply(lhs)
13411325

1342-
/** Returns a builder for computing trees representing assignments to `lhs`, which isn't a term
1343-
* or type application.
1326+
/** Returns a builder for making trees representing assignments to `lhs`, which isn't a term or
1327+
* type application.
13441328
*/
13451329
def formPartialAssignmentToNonApply(lhs: untpd.Tree)(using Context): PartialAssignment[LValue] =
13461330
val locked = ctx.typerState.ownedVars
@@ -1431,7 +1415,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
14311415
(untpd.cpy.Ident(f)(name.setterName), captures)
14321416

14331417
case f @ Select(q, name: TermName) =>
1434-
val (v, d) = hoisted(q)
1418+
val (v, d) = PossiblyHoistedValue(q).valueAndDefinition
14351419
(untpd.cpy.Select(f)(untpd.TypedSplice(v), name.setterName), captures ++ d)
14361420

14371421
case f @ TypeApply(g, ts) =>
@@ -1442,7 +1426,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
14421426
var (s, newCaptures) = formSetter(g, captures)
14431427
var arguments = List[untpd.Tree]()
14441428
for a <- as do
1445-
val (v, d) = hoisted(a)
1429+
val (v, d) = PossiblyHoistedValue(a).valueAndDefinition
14461430
arguments = untpd.TypedSplice(v, isExtensionReceiver = true) +: arguments
14471431
newCaptures = newCaptures ++ d
14481432

0 commit comments

Comments
 (0)