aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-24 18:51:26 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-24 22:32:32 +0200
commitb56a743edf1fe21ff1f9f070d17e4a23930e59bd (patch)
tree1da465c9bfaabade7017efb2c70078f4c3fc0780
parentbd8ff1720396bb61d0ef5fede8eb956df663faa5 (diff)
downloaddotty-b56a743edf1fe21ff1f9f070d17e4a23930e59bd.tar.gz
dotty-b56a743edf1fe21ff1f9f070d17e4a23930e59bd.tar.bz2
dotty-b56a743edf1fe21ff1f9f070d17e4a23930e59bd.zip
Special context for self constructor args
Arguments to this(...) calls need a special contet, similar to - but different from - the supercall context.
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala13
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala6
-rw-r--r--src/dotty/tools/dotc/typer/Mode.scala3
-rw-r--r--test/dotc/tests.scala4
-rw-r--r--tests/neg/badAuxConstr.scala11
-rw-r--r--tests/neg/t1131.scala4
6 files changed, 28 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 5f0f6ee6a..b221d4083 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -267,7 +267,6 @@ object Contexts {
* - as owner: The primary constructor of the class
* - as outer context: The context enclosing the class context
* - as scope: The parameter accessors in the class context
- * - as mode: inSuperCall
*
* The reasons for this peculiar choice of attributes are as follows:
*
@@ -283,7 +282,7 @@ object Contexts {
*/
def superCallContext: Context = {
val locals = newScopeWith(owner.decls.filter(_ is ParamAccessor).toList: _*)
- superOrThisCallContext(owner.primaryConstructor, locals)//.addMode(Mode.InSuperCall)
+ superOrThisCallContext(owner.primaryConstructor, locals)
}
/** The context for the arguments of a this(...) constructor call.
@@ -293,20 +292,18 @@ object Contexts {
* - as owner: The auxiliary constructor
* - as outer context: The context enclosing the enclosing class context
* - as scope: The parameters of the auxiliary constructor.
- * - as mode: inSuperCall
*/
- def thisCallContext: Context = {
+ def thisCallArgContext: Context = {
assert(owner.isClassConstructor)
val constrCtx = outersIterator.dropWhile(_.outer.owner == owner).next
var classCtx = outersIterator.dropWhile(!_.isClassDefContext).next
- println(i"locals for this call: ${constrCtx.scope}")
- classCtx.superOrThisCallContext(owner, constrCtx.scope)
+ classCtx.superOrThisCallContext(owner, constrCtx.scope).setTyperState(typerState)
}
/** The super= or this-call context with given owner and locals. */
- private def superOrThisCallContext(owner: Symbol, locals: Scope): Context = {
+ private def superOrThisCallContext(owner: Symbol, locals: Scope): FreshContext = {
assert(isClassDefContext)
- outer.fresh.setOwner(owner).setScope(locals)//.addMode(Mode.InSuperCall)
+ outer.fresh.setOwner(owner).setScope(locals)
}
/** The current source file; will be derived from current
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index a7c6a85cf..a126db1ad 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -445,7 +445,9 @@ trait Applications extends Compatibility { self: Typer =>
def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
def realApply(implicit ctx: Context): Tree = track("realApply") {
- var proto = new FunProto(tree.args, IgnoredProto(pt), this)
+ def argCtx(implicit ctx: Context) =
+ if (untpd.isSelfConstrCall(tree)) ctx.thisCallArgContext else ctx
+ var proto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx)
val fun1 = typedExpr(tree.fun, proto)
// Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as
@@ -461,7 +463,7 @@ trait Applications extends Compatibility { self: Typer =>
tryEither { implicit ctx =>
val app =
if (proto.argsAreTyped) new ApplyToTyped(tree, fun1, funRef, proto.typedArgs, pt)
- else new ApplyToUntyped(tree, fun1, funRef, proto, pt)
+ else new ApplyToUntyped(tree, fun1, funRef, proto, pt)(argCtx)
val result = app.result
ConstFold(result)
} { (failedVal, failedState) =>
diff --git a/src/dotty/tools/dotc/typer/Mode.scala b/src/dotty/tools/dotc/typer/Mode.scala
index 54487722a..417d461e1 100644
--- a/src/dotty/tools/dotc/typer/Mode.scala
+++ b/src/dotty/tools/dotc/typer/Mode.scala
@@ -32,8 +32,7 @@ object Mode {
val InferringReturnType = newMode(3, "InferringReturnType")
val TypevarsMissContext = newMode(4, "TypevarsMissContext")
- val InSuperCall = newMode(5, "InSuperCall")
- val CheckCyclic = newMode(6, "CheckCyclic")
+ val CheckCyclic = newMode(5, "CheckCyclic")
val PatternOrType = Pattern | Type
} \ No newline at end of file
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 183e318eb..387bab97f 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -17,7 +17,7 @@ class tests extends CompilerTest {
"-Ycheck:literalize"
)
- val twice = List("#runs", "2", "-YnoDoubleBindings")
+ val twice = List("#runs", "2", "-YnoDoubleBindings"/*, "-Ystop-before:terminal"*/)
val doErase = List("-Ystop-before:terminal")
val posDir = "./tests/pos/"
@@ -76,6 +76,7 @@ class tests extends CompilerTest {
defaultOptions = noCheckOptions)
// -Ycheck fails because there are structural types involving higher-kinded types.
// these are illegal, but are tested only later.
+ @Test def neg_t1131_structural = compileFile(negDir, "t1131", xerrors = 1)
@Test def neg_zoo = compileFile(negDir, "zoo", xerrors = 1)
@Test def neg_t1192_legalPrefix = compileFile(negDir, "t1192", xerrors = 1)
@Test def neg_tailcall_t1672b = compileFile(negDir, "tailcall/t1672b", xerrors = 6)
@@ -89,6 +90,7 @@ class tests extends CompilerTest {
@Test def neg_t1843_variances = compileFile(negDir, "t1843-variances", xerrors = 1)
@Test def neg_t2994 = compileFile(negDir, "t2994", xerrors = 2)
@Test def neg_variances = compileFile(negDir, "variances", xerrors = 2)
+ @Test def neg_badAuxConstr = compileFile(negDir, "badAuxConstr", xerrors = 2)
@Test def dotc = compileDir(dotcDir + "tools/dotc", twice)
@Test def dotc_ast = compileDir(dotcDir + "tools/dotc/ast", twice)
diff --git a/tests/neg/badAuxConstr.scala b/tests/neg/badAuxConstr.scala
new file mode 100644
index 000000000..8984f2306
--- /dev/null
+++ b/tests/neg/badAuxConstr.scala
@@ -0,0 +1,11 @@
+class A[S, T](s: S, t: T) {
+ val z: T = ???
+}
+
+class B[X](x: X) extends A[X, X](x, x) {
+ def this() = this(z) // error: not found: z
+
+ val u: X = x
+ def this(x: Int) = this(u) // error: not found: u
+}
+
diff --git a/tests/neg/t1131.scala b/tests/neg/t1131.scala
new file mode 100644
index 000000000..f4a7b377d
--- /dev/null
+++ b/tests/neg/t1131.scala
@@ -0,0 +1,4 @@
+trait A { self: Any { def p: Any } =>
+ def f(b: => Unit): Unit = {}
+ f { p } // error: cannot access member 'p' from structural type
+}