From ca7bbcfb178c5a0c697a3cdd543e38f37b79f737 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 8 Dec 2016 14:03:05 -0800 Subject: SI-8704 Error on bad implicit sections Instead of aborting when a class def has extra parameter section, take all parameter sections and sanity check the use of leading implicit to indicate an implicit parameter section. --- .../scala/tools/nsc/ast/parser/Parsers.scala | 32 +++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'src/compiler/scala/tools/nsc/ast/parser/Parsers.scala') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index a511d753c1..45c177f5b9 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2236,22 +2236,24 @@ self => * }}} */ def paramClauses(owner: Name, contextBounds: List[Tree], ofCaseClass: Boolean): List[List[ValDef]] = { - var implicitmod = 0 - var caseParam = ofCaseClass - val vds = new ListBuffer[List[ValDef]] + var implicitSection = -1 + var implicitOffset = -1 + var warnAt = -1 + var caseParam = ofCaseClass + val vds = new ListBuffer[List[ValDef]] val start = in.offset - def paramClause(): List[ValDef] = { - if (in.token == RPAREN) - return Nil - - if (in.token == IMPLICIT) { - in.nextToken() - implicitmod = Flags.IMPLICIT - } - commaSeparated(param(owner, implicitmod, caseParam )) + def paramClause(): List[ValDef] = if (in.token == RPAREN) Nil else { + val implicitmod = + if (in.token == IMPLICIT) { + if (implicitOffset == -1) { implicitOffset = in.offset ; implicitSection = vds.length } + else if (warnAt == -1) warnAt = in.offset + in.nextToken() + Flags.IMPLICIT + } else 0 + commaSeparated(param(owner, implicitmod, caseParam)) } newLineOptWhenFollowedBy(LPAREN) - while (implicitmod == 0 && in.token == LPAREN) { + while (in.token == LPAREN) { in.nextToken() vds += paramClause() accept(RPAREN) @@ -2266,6 +2268,10 @@ self => syntaxError(in.lastOffset, s"case classes must have a non-implicit parameter list; try 'case class ${ owner.encoded}()${ vds.map(vs => "(...)").mkString }'") } + if (implicitSection != -1 && implicitSection != vds.length - 1) + syntaxError(implicitOffset, "an implicit parameter section must be last") + if (warnAt != -1) + syntaxError(warnAt, "multiple implicit parameter sections are not allowed") val result = vds.toList if (owner == nme.CONSTRUCTOR && (result.isEmpty || (result.head take 1 exists (_.mods.isImplicit)))) { in.token match { -- cgit v1.2.3