diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 30f89c5c44d1..c215f382bcbe 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -1121,15 +1121,19 @@ class Definitions { /** Is `tp` (an alias) of either a scala.FunctionN or a scala.ImplicitFunctionN * instance? */ - def isNonDepFunctionType(tp: Type)(implicit ctx: Context): Boolean = { + def isNonRefinedFunction(tp: Type)(implicit ctx: Context): Boolean = { val arity = functionArity(tp) val sym = tp.dealias.typeSymbol - arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType(arity, sym.name.isImplicitFunction, sym.name.isErasedFunction).typeSymbol) + + arity >= 0 && + isFunctionClass(sym) && + tp.isRef(FunctionType(arity, sym.name.isImplicitFunction, sym.name.isErasedFunction).typeSymbol) && + !tp.isInstanceOf[RefinedType] } /** Is `tp` a representation of a (possibly depenent) function type or an alias of such? */ def isFunctionType(tp: Type)(implicit ctx: Context): Boolean = - isNonDepFunctionType(tp.dropDependentRefinement) + isNonRefinedFunction(tp.dropDependentRefinement) // Specialized type parameters defined for scala.Function{0,1,2}. lazy val Function1SpecializedParamTypes: collection.Set[TypeRef] = @@ -1169,7 +1173,7 @@ class Definitions { false }) - def functionArity(tp: Type)(implicit ctx: Context): Int = tp.dealias.argInfos.length - 1 + def functionArity(tp: Type)(implicit ctx: Context): Int = tp.dropDependentRefinement.dealias.argInfos.length - 1 /** Return underlying immplicit function type (i.e. instance of an ImplicitFunctionN class) * or NoType if none exists. The following types are considered as underlying types: diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 4fbeb406351d..6c371b629321 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -756,7 +756,7 @@ class Typer extends Namer case _ => untpd.TypeTree(tp) } pt.stripTypeVar.dealias.followSyntheticOpaque match { - case pt1 if defn.isNonDepFunctionType(pt1) => + case pt1 if defn.isNonRefinedFunction(pt1) => // if expected parameter type(s) are wildcards, approximate from below. // if expected result type is a wildcard, approximate from above. // this can type the greatest set of admissible closures. @@ -2528,7 +2528,7 @@ class Typer extends Namer ctx.warning(ex"${tree.symbol} is eta-expanded even though $pt does not have the @FunctionalInterface annotation.", tree.sourcePos) case _ => } - simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked) + simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked) } else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol)) readaptSimplified(tpd.Apply(tree, Nil)) else if (wtp.isImplicitMethod) diff --git a/tests/pos/i5794.scala b/tests/pos/i5794.scala new file mode 100644 index 000000000000..24862c92b324 --- /dev/null +++ b/tests/pos/i5794.scala @@ -0,0 +1,5 @@ +object Test { + trait Entry { type Key; val key: Key } + def extractKey(e: Entry): e.Key = e.key + val extractor: (e: Entry) => e.Key = extractKey +}