aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/language.scala7
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala32
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala19
-rw-r--r--tests/disabled/not-representable/pos/tryexpr.scala (renamed from tests/pending/pos/tryexpr.scala)0
-rw-r--r--tests/neg/autoTuplingTest.scala2
-rw-r--r--tests/pending/pos/t1756.scala5
-rw-r--r--tests/pending/pos/t2660.scala25
-rw-r--r--tests/pos/t2913.scala (renamed from tests/pending/pos/t2913.scala)29
9 files changed, 64 insertions, 59 deletions
diff --git a/src/dotty/language.scala b/src/dotty/language.scala
index 96250a9f2..416a4281b 100644
--- a/src/dotty/language.scala
+++ b/src/dotty/language.scala
@@ -4,13 +4,6 @@ object language {
class Feature
- /** Allow higher-kinded type syntax (not yet checked) */
- val higherKinds = new Feature
-
/** Keep union types */
val keepUnions = new Feature
-
- /** No auto tupling */
- val noAutoTupling = new Feature
-
}
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 93b1b1f02..b69ce2536 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -493,7 +493,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
*/
def featureEnabled(owner: ClassSymbol, feature: TermName): Boolean = {
def toPrefix(sym: Symbol): String =
- if (!sym.exists || (sym eq defn.LanguageModuleClass) || (sym eq defn.Scala2LanguageModuleRef)) ""
+ if (!sym.exists || (sym eq defn.LanguageModuleClass) || (sym eq defn.Scala2LanguageModuleClass)) ""
else toPrefix(sym.owner) + sym.name + "."
def featureName = toPrefix(owner) + feature
def hasImport(implicit ctx: Context): Boolean = {
@@ -512,7 +512,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
/** Is auto-tupling enabled? */
def canAutoTuple =
- !featureEnabled(defn.LanguageModuleClass, nme.noAutoTupling)
+ !featureEnabled(defn.Scala2LanguageModuleClass, nme.noAutoTupling)
def scala2Mode =
featureEnabled(defn.LanguageModuleClass, nme.Scala2)
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index c8f41b7fa..efd12cb5e 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -541,17 +541,29 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
+ /** Try same application with an implicit inserted around the qualifier of the function
+ * part. Return an optional value to indicate success.
+ */
+ def tryWithImplicitOnQualifier(fun1: Tree, proto: FunProto)(implicit ctx: Context): Option[Tree] =
+ tryInsertImplicitOnQualifier(fun1, proto) flatMap { fun2 =>
+ tryEither { implicit ctx =>
+ Some(typedApply(
+ cpy.Apply(tree)(untpd.TypedSplice(fun2), proto.typedArgs map untpd.TypedSplice),
+ pt)): Option[Tree]
+ } { (_, _) => None }
+ }
+
def realApply(implicit ctx: Context): Tree = track("realApply") {
- var proto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx(tree))
- val fun1 = typedExpr(tree.fun, proto)
+ val originalProto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx(tree))
+ val fun1 = typedExpr(tree.fun, originalProto)
- // Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as
+ // Warning: The following lines are dirty and fragile. We record that auto-tupling was demanded as
// a side effect in adapt. If it was, we assume the tupled proto-type in the rest of the application.
// This crucially relies on he fact that `proto` is used only in a single call of `adapt`,
// otherwise we would get possible cross-talk between different `adapt` calls using the same
// prototype. A cleaner alternative would be to return a modified prototype from `adapt` together with
// a modified tree but this would be more convoluted and less efficient.
- if (proto.isTupled) proto = proto.tupled
+ val proto = if (originalProto.isTupled) originalProto.tupled else originalProto
// If some of the application's arguments are function literals without explicitly declared
// parameter types, relate the normalized result type of the application with the
@@ -580,13 +592,11 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val result = app.result
convertNewGenericArray(ConstFold(result))
} { (failedVal, failedState) =>
- val fun2 = tryInsertImplicitOnQualifier(fun1, proto)
- if (fun1 eq fun2) {
- failedState.commit()
- failedVal
- } else typedApply(
- cpy.Apply(tree)(untpd.TypedSplice(fun2), proto.typedArgs map untpd.TypedSplice), pt)
- }
+ def fail = { failedState.commit(); failedVal }
+ tryWithImplicitOnQualifier(fun1, originalProto).getOrElse(
+ if (proto eq originalProto) fail
+ else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail))
+ }
case _ =>
handleUnexpectedFunType(tree, fun1)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 2b690ef51..34cd5448b 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1445,26 +1445,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val sel = typedSelect(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt)
if (sel.tpe.isError) sel else adapt(sel, pt)
} { (failedTree, failedState) =>
- val tree1 = tryInsertImplicitOnQualifier(tree, pt)
- if (tree1 eq tree) fallBack(failedTree, failedState)
- else adapt(tree1, pt)
- }
+ tryInsertImplicitOnQualifier(tree, pt) match {
+ case Some(tree1) => adapt(tree1, pt)
+ case none => fallBack(failedTree, failedState)
+ }
+ }
/** If this tree is a select node `qual.name`, try to insert an implicit conversion
* `c` around `qual` so that `c(qual).name` conforms to `pt`. If that fails
* return `tree` itself.
*/
- def tryInsertImplicitOnQualifier(tree: Tree, pt: Type)(implicit ctx: Context): Tree = ctx.traceIndented(i"try insert impl on qualifier $tree $pt") {
+ def tryInsertImplicitOnQualifier(tree: Tree, pt: Type)(implicit ctx: Context): Option[Tree] = ctx.traceIndented(i"try insert impl on qualifier $tree $pt") {
tree match {
case Select(qual, name) =>
val qualProto = SelectionProto(name, pt, NoViewsAllowed)
tryEither { implicit ctx =>
val qual1 = adaptInterpolated(qual, qualProto, EmptyTree)
- if ((qual eq qual1) || ctx.reporter.hasErrors) tree
- else typedSelect(cpy.Select(tree)(untpd.TypedSplice(qual1), name), pt)
- } { (_, _) => tree
+ if ((qual eq qual1) || ctx.reporter.hasErrors) None
+ else Some(typedSelect(cpy.Select(tree)(untpd.TypedSplice(qual1), name), pt))
+ } { (_, _) => None
}
- case _ => tree
+ case _ => None
}
}
diff --git a/tests/pending/pos/tryexpr.scala b/tests/disabled/not-representable/pos/tryexpr.scala
index c6c2febf7..c6c2febf7 100644
--- a/tests/pending/pos/tryexpr.scala
+++ b/tests/disabled/not-representable/pos/tryexpr.scala
diff --git a/tests/neg/autoTuplingTest.scala b/tests/neg/autoTuplingTest.scala
index 37136b760..92126ab5d 100644
--- a/tests/neg/autoTuplingTest.scala
+++ b/tests/neg/autoTuplingTest.scala
@@ -1,4 +1,4 @@
-import dotty.language.noAutoTupling
+import language.noAutoTupling
object autoTuplingNeg2 {
diff --git a/tests/pending/pos/t1756.scala b/tests/pending/pos/t1756.scala
index 58f56ccb9..34bf273ab 100644
--- a/tests/pending/pos/t1756.scala
+++ b/tests/pending/pos/t1756.scala
@@ -18,6 +18,11 @@ with expected type A with Poly[A]. And no solution is found.
To solve this, I added a fallback scheme similar to implicit arguments:
When an implicit view that adds a method matching given arguments and result
type fails, try again without the result type.
+
+However, troubles are not yet over. We now get an oprhan poly param C when pickling
+and, if typr printer and -Ylog:front is on, an infinite type of the form
+
+ mu x. Ring[LazyRef(x) & A]
*/
trait Ring[T <: Ring[T]] {
def +(that: T): T
diff --git a/tests/pending/pos/t2660.scala b/tests/pending/pos/t2660.scala
deleted file mode 100644
index d42dcc72b..000000000
--- a/tests/pending/pos/t2660.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package hoho
-
-class G
-
-class H extends G
-
-class A[T](x: T) {
-
- def this(y: G, z: T) = {
- this(z)
- print(1)
- }
-
- def this(z: H, h: T) = {
- this(h)
- print(2)
- }
-}
-
-object T {
- def main(args: Array[String]): Unit = {
- implicit def g2h(g: G): H = new H
- new A(new H, 23)
- }
-}
diff --git a/tests/pending/pos/t2913.scala b/tests/pos/t2913.scala
index 21700e71a..f91ed7b51 100644
--- a/tests/pending/pos/t2913.scala
+++ b/tests/pos/t2913.scala
@@ -1,4 +1,3 @@
-import language.noAutoTupling // try with on and off
class A {
def foo(a: Int) = 0
@@ -10,7 +9,8 @@ class RichA {
def foo() = 0
}
-object Test {
+object TestNoAutoTupling {
+ import language.noAutoTupling // try with on and off
implicit def AToRichA(a: A): RichA = new RichA
@@ -18,7 +18,7 @@ object Test {
a.foo()
a.foo(1)
- a.foo("") // Without implicits, a type error regarding invalid argument types is generated at `""`. This is
+ a.foo("") // Without implicits, a type error regarding invalid argument types is generated at `""`. This is
// the same position as an argument, so the 'second try' typing with an Implicit View is tried,
// and AToRichA(a).foo("") is found.
//
@@ -29,7 +29,6 @@ object Test {
a.foo("a", "b") // Without implicits, a type error regarding invalid arity is generated at `foo(<error>"", "")`.
// Typers#tryTypedApply:3274 only checks if the error is as the same position as `foo`, `"a"`, or `"b"`.
- // None of these po
}
// t0851 is essentially the same:
@@ -53,3 +52,25 @@ object Main {
()
}
}
+
+object TestWithAutoTupling {
+
+ implicit def AToRichA(a: A): RichA = new RichA
+
+ val a = new A
+ a.foo()
+ a.foo(1)
+
+ a.foo("") // Without implicits, a type error regarding invalid argument types is generated at `""`. This is
+ // the same position as an argument, so the 'second try' typing with an Implicit View is tried,
+ // and AToRichA(a).foo("") is found.
+ //
+ // My reading of the spec "7.3 Views" is that `a.foo` denotes a member of `a`, so the view should
+ // not be triggered.
+ //
+ // But perhaps the implementation was changed to solve See https://lampsvn.epfl.ch/trac/scala/ticket/1756
+
+ a.foo("a", "b") // Without implicits, a type error regarding invalid arity is generated at `foo(<error>"", "")`.
+ // Typers#tryTypedApply:3274 only checks if the error is as the same position as `foo`, `"a"`, or `"b"`.
+}
+