diff options
author | Som Snytt <som.snytt@gmail.com> | 2016-05-04 12:44:40 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2016-05-04 16:00:11 -0700 |
commit | 6379b70d952cf0eea96d205e14a291b441f9cd45 (patch) | |
tree | 5f26e590ef4a8dbd30519b8cf368b277a3c2bff8 /src | |
parent | f952a812340db7bc11f45b45f46e4b8ce7d6fb49 (diff) | |
download | scala-6379b70d952cf0eea96d205e14a291b441f9cd45.tar.gz scala-6379b70d952cf0eea96d205e14a291b441f9cd45.tar.bz2 scala-6379b70d952cf0eea96d205e14a291b441f9cd45.zip |
SI-9045 Error on recursive ctor
If the constructor invokes itself, say so.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 17 |
2 files changed, 14 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index ccdff5c9a1..e190b57017 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -469,6 +469,11 @@ trait ContextErrors { setError(tree) } + def ConstructorRecursesError(tree: Tree) = { + issueNormalTypeError(tree, "constructor invokes itself") + setError(tree) + } + def OnlyDeclarationsError(tree: Tree) = { issueNormalTypeError(tree, "only declarations allowed here") setError(tree) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 65c6e09fd3..329ce8c23b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3003,22 +3003,23 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // skip typechecking of statements in a sequence where some other statement includes the targetposition case s if localTarget && !includesTargetPos(s) => s case _ => - val localTyper = if (inBlock || (stat.isDef && !stat.isInstanceOf[LabelDef])) { - this - } else newTyper(context.make(stat, exprOwner)) + val localTyper = if (inBlock || (stat.isDef && !stat.isInstanceOf[LabelDef])) this + else newTyper(context.make(stat, exprOwner)) // XXX this creates a spurious dead code warning if an exception is thrown // in a constructor, even if it is the only thing in the constructor. val result = checkDead(localTyper.typedByValueExpr(stat)) if (treeInfo.isSelfOrSuperConstrCall(result)) { context.inConstructorSuffix = true - if (treeInfo.isSelfConstrCall(result) && result.symbol.pos.pointOrElse(0) >= exprOwner.enclMethod.pos.pointOrElse(0)) - ConstructorsOrderError(stat) + if (treeInfo.isSelfConstrCall(result)) { + if (result.symbol == exprOwner.enclMethod) + ConstructorRecursesError(stat) + else if (result.symbol.pos.pointOrElse(0) >= exprOwner.enclMethod.pos.pointOrElse(0)) + ConstructorsOrderError(stat) + } } - if (!isPastTyper && treeInfo.isPureExprForWarningPurposes(result)) context.warning(stat.pos, - "a pure expression does nothing in statement position; " + - "you may be omitting necessary parentheses" + "a pure expression does nothing in statement position; you may be omitting necessary parentheses" ) result } |