Skip to content

Commit

Permalink
Make error message appear at first invalid argument
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanfrawley authored and adriaanm committed Jun 14, 2018
1 parent dcefe2c commit aad4c28
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/compiler/scala/reflect/quasiquotes/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ trait Parsers { self: Quasiquotes =>
override implicit lazy val fresh: FreshNameCreator = new FreshNameCreator(nme.QUASIQUOTE_PREFIX)

// Do not check for tuple arity. The placeholders can support arbitrary tuple sizes.
override def makeSafeTupleTerm(trees: List[Tree], offset: Offset): Tree = treeBuilder.makeTupleTerm(trees)
override def makeSafeTupleType(trees: List[Tree], offset: Offset): Tree = treeBuilder.makeTupleType(trees)
override def makeSafeTupleTerm(trees: List[Tree]): Tree = treeBuilder.makeTupleTerm(trees)
override def makeSafeTupleType(trees: List[Tree]): Tree = treeBuilder.makeTupleType(trees)

override val treeBuilder = new ParserTreeBuilder {
override implicit def fresh: FreshNameCreator = parser.fresh
Expand Down
30 changes: 16 additions & 14 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -799,40 +799,42 @@ self =>
def readAnnots(part: => Tree): List[Tree] = tokenSeparated(AT, sepFirst = true, part)

/** Create a tuple type Tree. If the arity is not supported, a syntax error is emitted. */
def makeSafeTupleType(elems: List[Tree], offset: Offset) = {
if (checkTupleSize(elems, offset)) makeTupleType(elems)
def makeSafeTupleType(elems: List[Tree]) = {
if (checkTupleSize(elems)) makeTupleType(elems)
else makeTupleType(Nil) // create a dummy node; makeTupleType(elems) would fail
}

/** Create a tuple term Tree. If the arity is not supported, a syntax error is emitted. */
def makeSafeTupleTerm(elems: List[Tree], offset: Offset) = {
checkTupleSize(elems, offset)
def makeSafeTupleTerm(elems: List[Tree]) = {
checkTupleSize(elems)
makeTupleTerm(elems)
}

/** Create a function Tree. If the arity is not supported, a syntax error is emitted. */
def makeSafeFunctionType(argtpes: List[Tree], offset: Offset, restpe: Tree) = {
if (checkFunctionArity(argtpes, offset)) makeFunctionTypeTree(argtpes, restpe)
def makeSafeFunctionType(argtpes: List[Tree], restpe: Tree) = {
if (checkFunctionArity(argtpes)) makeFunctionTypeTree(argtpes, restpe)
else makeFunctionTypeTree(Nil, restpe) // create a dummy node
}

private[this] def checkTupleSize(elems: List[Tree], offset: Offset): Boolean =
private[this] def checkTupleSize(elems: List[Tree]): Boolean =
elems.lengthCompare(definitions.MaxTupleArity) <= 0 || {
val firstInvalidElem = elems(definitions.MaxTupleArity)
val msg = s"tuples may not have more than ${definitions.MaxFunctionArity} elements, but ${elems.length} given"
syntaxError(offset, msg, skipIt = false)
syntaxError(firstInvalidElem.pos, msg, skipIt = false)
false
}

private[this] def checkFunctionArity(argtpes: List[Tree], offset: Offset): Boolean =
private[this] def checkFunctionArity(argtpes: List[Tree]): Boolean =
argtpes.lengthCompare(definitions.MaxFunctionArity) <= 0 || {
val firstInvalidArg = argtpes(definitions.MaxFunctionArity)
val msg = s"function values may not have more than ${definitions.MaxFunctionArity} parameters, but ${argtpes.length} given"
syntaxError(offset, msg, skipIt = false)
syntaxError(firstInvalidArg.pos, msg, skipIt = false)
false
}

/** Strip the artificial `Parens` node to create a tuple term Tree. */
def stripParens(t: Tree) = t match {
case Parens(ts) => atPos(t.pos) { makeSafeTupleTerm(ts, t.pos.point) }
case Parens(ts) => atPos(t.pos) { makeSafeTupleTerm(ts) }
case _ => t
}

Expand Down Expand Up @@ -978,10 +980,10 @@ self =>
val ts = functionTypes()
accept(RPAREN)
if (in.token == ARROW)
atPos(start, in.skipToken()) { makeSafeFunctionType(ts, start, typ()) }
atPos(start, in.skipToken()) { makeSafeFunctionType(ts, typ()) }
else {
ts foreach checkNotByNameOrVarargs
val tuple = atPos(start) { makeSafeTupleType(ts, start) }
val tuple = atPos(start) { makeSafeTupleType(ts) }
infixTypeRest(
compoundTypeRest(
annotTypeRest(
Expand Down Expand Up @@ -1056,7 +1058,7 @@ self =>
} else {
val start = in.offset
simpleTypeRest(in.token match {
case LPAREN => atPos(start)(makeSafeTupleType(inParens(types()), start))
case LPAREN => atPos(start)(makeSafeTupleType(inParens(types())))
case USCORE => wildcardType(in.skipToken())
case _ =>
path(thisOK = false, typeOK = true) match {
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/func-max-args.check
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
func-max-args.scala:3: error: function values may not have more than 22 parameters, but 23 given
val func23: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) => Int
^
^
one error found
4 changes: 2 additions & 2 deletions test/files/neg/t9572.check
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
t9572.scala:3: error: tuples may not have more than 22 elements, but 23 given
val term23 = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
^
^
t9572.scala:5: error: tuples may not have more than 22 elements, but 23 given
val type23: (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int) = null
^
^
two errors found

0 comments on commit aad4c28

Please sign in to comment.