From 4ce42eb231a72d3f3599288cab0e08c8c54ce495 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 3 Jan 2021 14:25:05 +0100 Subject: [PATCH 1/3] Move ExpandSAMs to miniphase group before HoistSuperArgs There are interactions for treating partial functions that require a split into different groups. This move uncovered two follow-on errors which were previously not detected. --- compiler/src/dotty/tools/dotc/Compiler.scala | 2 +- compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala | 4 ++++ tests/pos/i9391.scala | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i9391.scala diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index 2d48c7a98d94..f24df22d673d 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -61,9 +61,9 @@ class Compiler { new CookComments, // Cook the comments: expand variables, doc, etc. new CheckStatic, // Check restrictions that apply to @static members new BetaReduce, // Reduce closure applications + new ExpandSAMs, // Expand single abstract method closures to anonymous classes new init.Checker) :: // Check initialization of objects List(new ElimRepeated, // Rewrite vararg parameters and arguments - new ExpandSAMs, // Expand single abstract method closures to anonymous classes new ProtectedAccessors, // Add accessors for protected members new ExtensionMethods, // Expand methods of value classes with extension methods new UncacheGivenAliases, // Avoid caching RHS of simple parameterless given aliases diff --git a/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala b/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala index 2547b6f24a38..00bcd1e5076a 100644 --- a/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala +++ b/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala @@ -26,6 +26,10 @@ class ByNameClosures extends TransformByNameApply with IdentityDenotTransformer override def phaseName: String = ByNameClosures.name + override def runsAfterGroupsOf: Set[String] = Set(ExpandSAMs.name) + // ExpanSAMs applied to partial functions creates methods that need + // to be fully defined before converting. Test case is pos/i9391.scala. + override def mkByNameClosure(arg: Tree, argType: Type)(using Context): Tree = { val meth = newSymbol( ctx.owner, nme.ANON_FUN, Synthetic | Method, MethodType(Nil, Nil, argType)) diff --git a/tests/pos/i9391.scala b/tests/pos/i9391.scala new file mode 100644 index 000000000000..b6bacbd2819a --- /dev/null +++ b/tests/pos/i9391.scala @@ -0,0 +1,3 @@ +def g(x: => Any): Any = x + +val a: PartialFunction[Any => Any, Any] = (f => g(f(0)) match { case v => v }) // was an error, now OK From 41aa184cbbb61690992bfc7053829eff6838704d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 3 Jan 2021 14:27:25 +0100 Subject: [PATCH 2/3] Maintain Extension flags for forwarders when creating an anonymous class. This causes an error in RefChecks for run/fragables-extension.scala otherwise. Previously the error was not detected since methods created in the same group as RefChecks are not checked. --- compiler/src/dotty/tools/dotc/ast/tpd.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 5fc78d80196c..c14238b06c06 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -350,7 +350,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { val constr = newConstructor(cls, Synthetic, Nil, Nil).entered def forwarder(fn: TermSymbol, name: TermName) = { val fwdMeth = fn.copy(cls, name, Synthetic | Method | Final).entered.asTerm - if (fwdMeth.allOverriddenSymbols.exists(!_.is(Deferred))) fwdMeth.setFlag(Override) + for overridden <- fwdMeth.allOverriddenSymbols do + if overridden.is(Extension) then fwdMeth.setFlag(Extension) + if !overridden.is(Deferred) then fwdMeth.setFlag(Override) polyDefDef(fwdMeth, tprefs => prefss => ref(fn).appliedToTypes(tprefs).appliedToArgss(prefss)) } val forwarders = fns.lazyZip(methNames).map(forwarder) From 57b5311fd77fd912d90029fe050f10d608df4d3a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 3 Jan 2021 14:27:53 +0100 Subject: [PATCH 3/3] SAMtype extractor should not use avoidance in same class When extracting a SAMtype we use avoidance of the class parameters since these are not visible outside the class. But we should not do that when the SAMType is extracted with an owner within the class. Fixes a problem with sammy_scope.scala that was left dormant until now since RefChecks did not check methods generated by ExpandSAMs. --- compiler/src/dotty/tools/dotc/core/Types.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index c05c4231dc24..a83628c65cf4 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -5006,7 +5006,9 @@ object Types { mapOver(tp) } } - val approx = approxParams(mt).asInstanceOf[MethodType] + val approx = + if ctx.owner.isContainedIn(cls) then mt + else approxParams(mt).asInstanceOf[MethodType] Some(approx) case _ => None