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/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) 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 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