Skip to content

Commit 80e1920

Browse files
Merge pull request #11609 from dotty-staging/fix-11571
Change order of evaluation for default parameters
2 parents 0e9b84c + 1f27a25 commit 80e1920

File tree

9 files changed

+41
-24
lines changed

9 files changed

+41
-24
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -825,8 +825,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
825825
val ownerAcc = new TreeAccumulator[immutable.Set[Symbol]] {
826826
def apply(ss: immutable.Set[Symbol], tree: Tree)(using Context) = tree match {
827827
case tree: DefTree =>
828-
if (tree.symbol.exists) ss + tree.symbol.owner
829-
else ss
828+
val sym = tree.symbol
829+
if sym.exists && !sym.owner.is(Package) then ss + sym.owner else ss
830830
case _ =>
831831
foldOver(ss, tree)
832832
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,13 +750,23 @@ trait Applications extends Compatibility {
750750
}
751751
private def sameSeq[T <: Trees.Tree[?]](xs: List[T], ys: List[T]): Boolean = firstDiff(xs, ys) < 0
752752

753+
/** An argument is safe if it is a pure expression or a default getter call
754+
* If all arguments are safe, no reordering is necessary
755+
*/
756+
def isSafeArg(arg: Tree) =
757+
isPureExpr(arg)
758+
|| arg.isInstanceOf[RefTree | Apply | TypeApply] && arg.symbol.name.is(DefaultGetterName)
759+
753760
val result: Tree = {
754761
var typedArgs = typedArgBuf.toList
755762
def app0 = cpy.Apply(app)(normalizedFun, typedArgs) // needs to be a `def` because typedArgs can change later
756763
val app1 =
757764
if (!success) app0.withType(UnspecifiedErrorType)
758765
else {
759-
if (!sameSeq(args, orderedArgs.dropWhile(_ eq EmptyTree)) && !isJavaAnnotConstr(methRef.symbol)) {
766+
if !sameSeq(args, orderedArgs)
767+
&& !isJavaAnnotConstr(methRef.symbol)
768+
&& !typedArgs.forall(isSafeArg)
769+
then
760770
// need to lift arguments to maintain evaluation order in the
761771
// presence of argument reorderings.
762772

@@ -787,7 +797,7 @@ trait Applications extends Compatibility {
787797
argDefBuf.zip(impureArgIndices), (arg, idx) => originalIndex(idx)).map(_._1)
788798
}
789799
liftedDefs ++= orderedArgDefs
790-
}
800+
end if
791801
if (sameSeq(typedArgs, args)) // trick to cut down on tree copying
792802
typedArgs = args.asInstanceOf[List[Tree]]
793803
assignType(app0, normalizedFun, typedArgs)

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
459459
val denot = qualifier.tpe.member(name.toTermName)
460460
assert(!denot.isOverloaded, s"The symbol `$name` is overloaded. The method Select.unique can only be used for non-overloaded symbols.")
461461
withDefaultPos(tpd.Select(qualifier, name.toTermName))
462-
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term]): Apply =
463-
withDefaultPos(tpd.applyOverloaded(qualifier, name.toTermName, args, targs, Types.WildcardType).asInstanceOf[Apply])
462+
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term]): Term =
463+
withDefaultPos(tpd.applyOverloaded(qualifier, name.toTermName, args, targs, Types.WildcardType))
464464

465-
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term], returnType: TypeRepr): Apply =
466-
withDefaultPos(tpd.applyOverloaded(qualifier, name.toTermName, args, targs, returnType).asInstanceOf[Apply])
465+
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term], returnType: TypeRepr): Term =
466+
withDefaultPos(tpd.applyOverloaded(qualifier, name.toTermName, args, targs, returnType))
467467
def copy(original: Tree)(qualifier: Term, name: String): Select =
468468
tpd.cpy.Select(original)(qualifier, name.toTermName)
469469
def unapply(x: Select): (Term, String) =

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,6 @@ i9793.scala
6060

6161
# lazy_implicit symbol has different position after pickling
6262
i8182.scala
63+
64+
# local lifted value in annotation argument has different position after pickling
65+
i2797a

library/src/scala/quoted/Quotes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -783,10 +783,10 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
783783
def unique(qualifier: Term, name: String): Select
784784

785785
/** Call an overloaded method with the given type and term parameters */
786-
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term]): Apply
786+
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term]): Term
787787

788788
/** Call an overloaded method with the given type and term parameters */
789-
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term], returnType: TypeRepr): Apply
789+
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term], returnType: TypeRepr): Term
790790

791791
def copy(original: Tree)(qualifier: Term, name: String): Select
792792

tests/run/i11571.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
17
2+
42

tests/run/i11571.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import util.chaining.scalaUtilChainingOps
2+
object Test extends App {
3+
def x = 42.tap(println(_))
4+
def y = 27.tap(println(_))
5+
def z = 17.tap(println(_))
6+
def f(i: Int = x, j: Int = y) = i + j
7+
f(j = z)
8+
}

tests/semanticdb/expect/NamedApplyBlock.expect.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ package example
33
object NamedApplyBlockMethods/*<-example::NamedApplyBlockMethods.*/ {
44
val local/*<-example::NamedApplyBlockMethods.local.*/ = 1
55
def foo/*<-example::NamedApplyBlockMethods.foo().*/(a/*<-example::NamedApplyBlockMethods.foo().(a)*/: Int/*->scala::Int#*/ = 1, b/*<-example::NamedApplyBlockMethods.foo().(b)*/: Int/*->scala::Int#*/ = 2, c/*<-example::NamedApplyBlockMethods.foo().(c)*/: Int/*->scala::Int#*/ = 3): Int/*->scala::Int#*/ = a/*->example::NamedApplyBlockMethods.foo().(a)*/ +/*->scala::Int#`+`(+4).*/ b/*->example::NamedApplyBlockMethods.foo().(b)*/ +/*->scala::Int#`+`(+4).*/ c/*->example::NamedApplyBlockMethods.foo().(c)*/
6-
def baseCase/*<-example::NamedApplyBlockMethods.baseCase().*/ = foo/*->example::NamedApplyBlockMethods.foo().*//*->local0*/(local/*->example::NamedApplyBlockMethods.local.*/, c/*->example::NamedApplyBlockMethods.foo().(c)*/ = 3)
7-
def recursive/*<-example::NamedApplyBlockMethods.recursive().*/ = foo/*->example::NamedApplyBlockMethods.foo().*//*->local2*/(local/*->example::NamedApplyBlockMethods.local.*/, c/*->example::NamedApplyBlockMethods.foo().(c)*/ = foo/*->example::NamedApplyBlockMethods.foo().*//*->local3*/(local/*->example::NamedApplyBlockMethods.local.*/, c/*->example::NamedApplyBlockMethods.foo().(c)*/ = 3))
6+
def baseCase/*<-example::NamedApplyBlockMethods.baseCase().*/ = foo/*->example::NamedApplyBlockMethods.foo().*/(local/*->example::NamedApplyBlockMethods.local.*/, c/*->example::NamedApplyBlockMethods.foo().(c)*/ = 3)
7+
def recursive/*<-example::NamedApplyBlockMethods.recursive().*/ = foo/*->example::NamedApplyBlockMethods.foo().*//*->local1*/(local/*->example::NamedApplyBlockMethods.local.*/, c/*->example::NamedApplyBlockMethods.foo().(c)*/ = foo/*->example::NamedApplyBlockMethods.foo().*/(local/*->example::NamedApplyBlockMethods.local.*/, c/*->example::NamedApplyBlockMethods.foo().(c)*/ = 3))
88
}
99

1010
object NamedApplyBlockCaseClassConstruction/*<-example::NamedApplyBlockCaseClassConstruction.*/ {
1111
case class Msg/*<-example::NamedApplyBlockCaseClassConstruction.Msg#*/(body/*<-example::NamedApplyBlockCaseClassConstruction.Msg#body.*/: String/*->scala::Predef.String#*/, head/*<-example::NamedApplyBlockCaseClassConstruction.Msg#head.*/: String/*->scala::Predef.String#*/ = "default", tail/*<-example::NamedApplyBlockCaseClassConstruction.Msg#tail.*/: String/*->scala::Predef.String#*/)
1212
val bodyText/*<-example::NamedApplyBlockCaseClassConstruction.bodyText.*/ = "body"
13-
val msg/*<-example::NamedApplyBlockCaseClassConstruction.msg.*/ = Msg/*->example::NamedApplyBlockCaseClassConstruction.Msg.*//*->local4*//*->example::NamedApplyBlockCaseClassConstruction.Msg.apply().*/(bodyText/*->example::NamedApplyBlockCaseClassConstruction.bodyText.*/, tail/*->example::NamedApplyBlockCaseClassConstruction.Msg.apply().(tail)*/ = "tail")
13+
val msg/*<-example::NamedApplyBlockCaseClassConstruction.msg.*/ = Msg/*->example::NamedApplyBlockCaseClassConstruction.Msg.*//*->example::NamedApplyBlockCaseClassConstruction.Msg.apply().*/(bodyText/*->example::NamedApplyBlockCaseClassConstruction.bodyText.*/, tail/*->example::NamedApplyBlockCaseClassConstruction.Msg.apply().(tail)*/ = "tail")
1414
}

tests/semanticdb/metac.expect

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,8 +2157,8 @@ Schema => SemanticDB v4
21572157
Uri => NamedApplyBlock.scala
21582158
Text => empty
21592159
Language => Scala
2160-
Symbols => 46 entries
2161-
Occurrences => 46 entries
2160+
Symbols => 43 entries
2161+
Occurrences => 43 entries
21622162

21632163
Symbols:
21642164
example/NamedApplyBlockCaseClassConstruction. => final object NamedApplyBlockCaseClassConstruction
@@ -2202,11 +2202,8 @@ example/NamedApplyBlockMethods.foo().(b) => param b
22022202
example/NamedApplyBlockMethods.foo().(c) => param c
22032203
example/NamedApplyBlockMethods.local. => val method local
22042204
example/NamedApplyBlockMethods.recursive(). => method recursive
2205-
local0 => val local b$1
2206-
local1 => val local c$1
2207-
local2 => val local b$3
2208-
local3 => val local b$2
2209-
local4 => val local head$1
2205+
local0 => val local c$1
2206+
local1 => val local b$1
22102207

22112208
Occurrences:
22122209
[0:8..0:15): example <- example/
@@ -2227,16 +2224,14 @@ Occurrences:
22272224
[4:61..4:62): c -> example/NamedApplyBlockMethods.foo().(c)
22282225
[5:6..5:14): baseCase <- example/NamedApplyBlockMethods.baseCase().
22292226
[5:17..5:20): foo -> example/NamedApplyBlockMethods.foo().
2230-
[5:17..5:17): -> local0
22312227
[5:21..5:26): local -> example/NamedApplyBlockMethods.local.
22322228
[5:28..5:29): c -> example/NamedApplyBlockMethods.foo().(c)
22332229
[6:6..6:15): recursive <- example/NamedApplyBlockMethods.recursive().
22342230
[6:18..6:21): foo -> example/NamedApplyBlockMethods.foo().
2235-
[6:18..6:18): -> local2
2231+
[6:18..6:18): -> local1
22362232
[6:22..6:27): local -> example/NamedApplyBlockMethods.local.
22372233
[6:29..6:30): c -> example/NamedApplyBlockMethods.foo().(c)
22382234
[6:33..6:36): foo -> example/NamedApplyBlockMethods.foo().
2239-
[6:33..6:33): -> local3
22402235
[6:37..6:42): local -> example/NamedApplyBlockMethods.local.
22412236
[6:44..6:45): c -> example/NamedApplyBlockMethods.foo().(c)
22422237
[9:7..9:43): NamedApplyBlockCaseClassConstruction <- example/NamedApplyBlockCaseClassConstruction.
@@ -2251,7 +2246,6 @@ Occurrences:
22512246
[11:6..11:14): bodyText <- example/NamedApplyBlockCaseClassConstruction.bodyText.
22522247
[12:6..12:9): msg <- example/NamedApplyBlockCaseClassConstruction.msg.
22532248
[12:12..12:15): Msg -> example/NamedApplyBlockCaseClassConstruction.Msg.
2254-
[12:12..12:12): -> local4
22552249
[12:15..12:15): -> example/NamedApplyBlockCaseClassConstruction.Msg.apply().
22562250
[12:16..12:24): bodyText -> example/NamedApplyBlockCaseClassConstruction.bodyText.
22572251
[12:26..12:30): tail -> example/NamedApplyBlockCaseClassConstruction.Msg.apply().(tail)

0 commit comments

Comments
 (0)