From aad4c28a6bdb866abede03e9850c16ce858db9ba Mon Sep 17 00:00:00 2001 From: Jonathan Frawley Date: Wed, 14 Mar 2018 11:14:09 +0000 Subject: [PATCH] Make error message appear at first invalid argument --- .../scala/reflect/quasiquotes/Parsers.scala | 4 +-- .../scala/tools/nsc/ast/parser/Parsers.scala | 30 ++++++++++--------- test/files/neg/func-max-args.check | 2 +- test/files/neg/t9572.check | 4 +-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/compiler/scala/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/reflect/quasiquotes/Parsers.scala index d1af1fab3f5c..94601a0297f8 100644 --- a/src/compiler/scala/reflect/quasiquotes/Parsers.scala +++ b/src/compiler/scala/reflect/quasiquotes/Parsers.scala @@ -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 diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 2414b5994961..9ca139873191 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -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 } @@ -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( @@ -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 { diff --git a/test/files/neg/func-max-args.check b/test/files/neg/func-max-args.check index 37335f0a5b84..fde5c184f604 100644 --- a/test/files/neg/func-max-args.check +++ b/test/files/neg/func-max-args.check @@ -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 diff --git a/test/files/neg/t9572.check b/test/files/neg/t9572.check index b0eeeb14488e..c0ee18199ada 100644 --- a/test/files/neg/t9572.check +++ b/test/files/neg/t9572.check @@ -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