Skip to content

Commit

Permalink
Introduce untpd.syntheticUnitLiteral to allow detection of explicit…
Browse files Browse the repository at this point in the history
… unit provided by user from synthetic unit introduced by compiler

[Cherry-picked 8c52866][modified]
  • Loading branch information
WojciechMazur committed Jul 9, 2024
1 parent 902da78 commit 8b28722
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 10 deletions.
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ object desugar {
if isSetterNeeded(vdef) then
val setterParam = makeSyntheticParameter(tpt = SetterParamTree().watching(vdef))
// The rhs gets filled in later, when field is generated and getter has parameters (see Memoize miniphase)
val setterRhs = if (vdef.rhs.isEmpty) EmptyTree else unitLiteral
val setterRhs = if (vdef.rhs.isEmpty) EmptyTree else syntheticUnitLiteral
val setter = cpy.DefDef(vdef)(
name = valName.setterName,
paramss = (setterParam :: Nil) :: Nil,
Expand Down Expand Up @@ -1311,7 +1311,7 @@ object desugar {
def block(tree: Block)(using Context): Block = tree.expr match {
case EmptyTree =>
cpy.Block(tree)(tree.stats,
unitLiteral.withSpan(if (tree.stats.isEmpty) tree.span else tree.span.endPos))
syntheticUnitLiteral.withSpan(if (tree.stats.isEmpty) tree.span else tree.span.endPos))
case _ =>
tree
}
Expand Down Expand Up @@ -1811,7 +1811,7 @@ object desugar {
case ts: Thicket => ts.trees.tail
case t => Nil
} map {
case Block(Nil, EmptyTree) => unitLiteral // for s"... ${} ..."
case Block(Nil, EmptyTree) => syntheticUnitLiteral // for s"... ${} ..."
case Block(Nil, expr) => expr // important for interpolated string as patterns, see i1773.scala
case t => t
}
Expand Down Expand Up @@ -1839,7 +1839,7 @@ object desugar {
val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
flatTree(pats1 map (makePatDef(tree, mods, _, rhs)))
case ext: ExtMethods =>
Block(List(ext), unitLiteral.withSpan(ext.span))
Block(List(ext), syntheticUnitLiteral.withSpan(ext.span))
case f: FunctionWithMods if f.hasErasedParams => makeFunctionWithValDefs(f, pt)
}
desugared.withSpan(tree.span)
Expand Down
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def InferredTypeTree(tpe: Type)(using Context): TypedSplice =
TypedSplice(new InferredTypeTree().withTypeUnchecked(tpe))

def unitLiteral(implicit src: SourceFile): Literal = Literal(Constant(())).withAttachment(SyntheticUnit, ())
def unitLiteral(implicit src: SourceFile): Literal =
Literal(Constant(()))

def syntheticUnitLiteral(implicit src: SourceFile): Literal =
unitLiteral.withAttachment(SyntheticUnit, ())

def ref(tp: NamedType)(using Context): Tree =
TypedSplice(tpd.ref(tp))
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2284,7 +2284,7 @@ object Parsers {
in.nextToken();
val expr = subExpr()
if expr.span.exists then expr
else unitLiteral // finally without an expression
else syntheticUnitLiteral // finally without an expression
}
else {
if handler.isEmpty then
Expand Down Expand Up @@ -3768,10 +3768,10 @@ object Parsers {
val stats = selfInvocation() :: (
if (isStatSep) { in.nextToken(); blockStatSeq() }
else Nil)
Block(stats, unitLiteral)
Block(stats, syntheticUnitLiteral)
}
}
else Block(selfInvocation() :: Nil, unitLiteral)
else Block(selfInvocation() :: Nil, syntheticUnitLiteral)

/** SelfInvocation ::= this ArgumentExprs {ArgumentExprs}
*/
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2009,7 +2009,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
// because we do not know the internal type params and method params.
// Hence no adaptation is possible, and we assume WildcardType as prototype.
(from, proto)
val expr1 = typedExpr(tree.expr orElse untpd.unitLiteral.withSpan(tree.span), proto)
val expr1 = typedExpr(tree.expr orElse untpd.syntheticUnitLiteral.withSpan(tree.span), proto)
assignType(cpy.Return(tree)(expr1, from))
end typedReturn

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/repl/ReplCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class ReplCompiler extends Compiler:
def wrap(trees: List[untpd.Tree]): untpd.PackageDef = {
import untpd.*

val valdef = ValDef("expr".toTermName, TypeTree(), Block(trees, unitLiteral).withSpan(Span(0, expr.length)))
val valdef = ValDef("expr".toTermName, TypeTree(), Block(trees, syntheticUnitLiteral).withSpan(Span(0, expr.length)))
val tmpl = Template(emptyConstructor, Nil, Nil, EmptyValDef, List(valdef))
val wrapper = TypeDef("$wrapper".toTypeName, tmpl)
.withMods(Modifiers(Final))
Expand Down

0 comments on commit 8b28722

Please sign in to comment.