@@ -452,7 +452,7 @@ object Parsers {
452452 if (isLeftAssoc(op1) != op2LeftAssoc)
453453 syntaxError(MixedLeftAndRightAssociativeOps (op1, op2, op2LeftAssoc), offset)
454454
455- def reduceStack (base : List [OpInfo ], top : Tree , prec : Int , leftAssoc : Boolean , op2 : Name ): Tree = {
455+ def reduceStack (base : List [OpInfo ], top : Tree , prec : Int , leftAssoc : Boolean , op2 : Name , isType : Boolean ): Tree = {
456456 if (opStack != base && precedence(opStack.head.operator.name) == prec)
457457 checkAssoc(opStack.head.offset, opStack.head.operator.name, op2, leftAssoc)
458458 def recur (top : Tree ): Tree = {
@@ -464,7 +464,15 @@ object Parsers {
464464 opStack = opStack.tail
465465 recur {
466466 atPos(opInfo.operator.pos union opInfo.operand.pos union top.pos) {
467- InfixOp (opInfo.operand, opInfo.operator, top)
467+ val op = opInfo.operator
468+ val l = opInfo.operand
469+ val r = top
470+ if (isType && ! op.isBackquoted && op.name == tpnme.raw.BAR ) {
471+ OrTypeTree (checkAndOrArgument(l), checkAndOrArgument(r))
472+ } else if (isType && ! op.isBackquoted && op.name == tpnme.raw.AMP ) {
473+ AndTypeTree (checkAndOrArgument(l), checkAndOrArgument(r))
474+ } else
475+ InfixOp (l, op, r)
468476 }
469477 }
470478 }
@@ -488,20 +496,20 @@ object Parsers {
488496 var top = first
489497 while (isIdent && isOperator) {
490498 val op = if (isType) typeIdent() else termIdent()
491- top = reduceStack(base, top, precedence(op.name), isLeftAssoc(op.name), op.name)
499+ top = reduceStack(base, top, precedence(op.name), isLeftAssoc(op.name), op.name, isType )
492500 opStack = OpInfo (top, op, in.offset) :: opStack
493501 newLineOptWhenFollowing(canStartOperand)
494502 if (maybePostfix && ! canStartOperand(in.token)) {
495503 val topInfo = opStack.head
496504 opStack = opStack.tail
497- val od = reduceStack(base, topInfo.operand, 0 , true , in.name)
505+ val od = reduceStack(base, topInfo.operand, 0 , true , in.name, isType )
498506 return atPos(startOffset(od), topInfo.offset) {
499507 PostfixOp (od, topInfo.operator)
500508 }
501509 }
502510 top = operand()
503511 }
504- reduceStack(base, top, 0 , true , in.name)
512+ reduceStack(base, top, 0 , true , in.name, isType )
505513 }
506514
507515/* -------- IDENTIFIERS AND LITERALS ------------------------------------------- */
@@ -709,15 +717,7 @@ object Parsers {
709717 /** Same as [[typ ]], but if this results in a wildcard it emits a syntax error and
710718 * returns a tree for type `Any` instead.
711719 */
712- def toplevelTyp (): Tree = {
713- val t = typ()
714- findWildcardType(t) match {
715- case Some (wildcardPos) =>
716- syntaxError(UnboundWildcardType (), wildcardPos)
717- scalaAny
718- case None => t
719- }
720- }
720+ def toplevelTyp (): Tree = checkWildcard(typ())
721721
722722 /** Type ::= [FunArgMods] FunArgTypes `=>' Type
723723 * | HkTypeParamClause `->' Type
@@ -768,9 +768,16 @@ object Parsers {
768768 accept(RPAREN )
769769 if (imods.is(Implicit ) || isValParamList || in.token == ARROW ) functionRest(ts)
770770 else {
771- for (t <- ts)
772- if (t.isInstanceOf [ByNameTypeTree ])
773- syntaxError(ByNameParameterNotSupported ())
771+ val ts1 =
772+ for (t <- ts) yield {
773+ t match {
774+ case t@ ByNameTypeTree (t1) =>
775+ syntaxError(ByNameParameterNotSupported (t), t.pos)
776+ t1
777+ case _ =>
778+ t
779+ }
780+ }
774781 val tuple = atPos(start) { makeTupleOrParens(ts) }
775782 infixTypeRest(
776783 refinedTypeRest(
@@ -784,7 +791,7 @@ object Parsers {
784791 val start = in.offset
785792 val tparams = typeParamClause(ParamOwner .TypeParam )
786793 if (in.token == ARROW )
787- atPos(start, in.skipToken())(LambdaTypeTree (tparams, typ ()))
794+ atPos(start, in.skipToken())(LambdaTypeTree (tparams, toplevelTyp ()))
788795 else { accept(ARROW ); typ() }
789796 }
790797 else infixType()
@@ -822,7 +829,7 @@ object Parsers {
822829
823830 def refinedTypeRest (t : Tree ): Tree = {
824831 newLineOptWhenFollowedBy(LBRACE )
825- if (in.token == LBRACE ) refinedTypeRest(atPos(startOffset(t)) { RefinedTypeTree (t , refinement()) })
832+ if (in.token == LBRACE ) refinedTypeRest(atPos(startOffset(t)) { RefinedTypeTree (checkWildcard(t) , refinement()) })
826833 else t
827834 }
828835
@@ -835,7 +842,7 @@ object Parsers {
835842 if (ctx.settings.strict.value)
836843 deprecationWarning(DeprecatedWithOperator ())
837844 in.nextToken()
838- AndTypeTree (t, withType())
845+ AndTypeTree (checkAndOrArgument(t), checkAndOrArgument( withType() ))
839846 }
840847 else t
841848
@@ -886,7 +893,7 @@ object Parsers {
886893 private def simpleTypeRest (t : Tree ): Tree = in.token match {
887894 case HASH => simpleTypeRest(typeProjection(t))
888895 case LBRACKET => simpleTypeRest(atPos(startOffset(t)) {
889- AppliedTypeTree (t , typeArgs(namedOK = false , wildOK = true )) })
896+ AppliedTypeTree (checkWildcard(t) , typeArgs(namedOK = false , wildOK = true )) })
890897 case _ => t
891898 }
892899
@@ -917,7 +924,7 @@ object Parsers {
917924 else Nil
918925 first :: rest
919926 }
920- def typParser () = if (wildOK) typ() else toplevelTyp( )
927+ def typParser () = checkWildcard( typ(), wildOK )
921928 if (namedOK && in.token == IDENTIFIER )
922929 typParser() match {
923930 case Ident (name) if in.token == EQUALS =>
@@ -1001,17 +1008,46 @@ object Parsers {
10011008 else if (location == Location .InPattern ) refinedType()
10021009 else infixType()
10031010
1004- /** Checks whether `t` is a wildcard type.
1005- * If it is, returns the [[Position ]] where the wildcard occurs .
1011+ /** Checks whether `t` represents a non-value type (wildcard types, or ByNameTypeTree) .
1012+ * If it is, returns the [[Tree ]] which immediately represents the non-value type .
10061013 */
10071014 @ tailrec
1008- private final def findWildcardType (t : Tree ): Option [Position ] = t match {
1009- case TypeBoundsTree (_, _) => Some (t.pos)
1010- case Parens (t1) => findWildcardType(t1)
1011- case Annotated (t1, _) => findWildcardType(t1)
1015+ private final def findNonValueTypeTree (t : Tree , alsoNonValue : Boolean ): Option [Tree ] = t match {
1016+ case TypeBoundsTree (_, _) => Some (t)
1017+ case ByNameTypeTree (_) if alsoNonValue => Some (t)
1018+ case Parens (t1) => findNonValueTypeTree(t1, alsoNonValue)
1019+ case Annotated (t1, _) => findNonValueTypeTree(t1, alsoNonValue)
10121020 case _ => None
10131021 }
10141022
1023+ def rejectWildcard (t : Tree , fallbackTree : Tree ): Tree =
1024+ findNonValueTypeTree(t, false ) match {
1025+ case Some (wildcardTree) =>
1026+ syntaxError(UnboundWildcardType (), wildcardTree.pos)
1027+ fallbackTree
1028+ case None => t
1029+ }
1030+
1031+
1032+ def checkWildcard (t : Tree , wildOK : Boolean = false , fallbackTree : Tree = scalaAny): Tree =
1033+ if (wildOK)
1034+ t
1035+ else
1036+ rejectWildcard(t, fallbackTree)
1037+
1038+ def checkAndOrArgument (t : Tree ): Tree =
1039+ findNonValueTypeTree(t, true ) match {
1040+ case Some (typTree) =>
1041+ typTree match {
1042+ case typTree : TypeBoundsTree =>
1043+ syntaxError(UnboundWildcardType (), typTree.pos)
1044+ case typTree : ByNameTypeTree =>
1045+ syntaxError(ByNameParameterNotSupported (typTree), typTree.pos)
1046+ }
1047+ scalaAny
1048+ case None => t
1049+ }
1050+
10151051/* ----------- EXPRESSIONS ------------------------------------------------ */
10161052
10171053 /** EqualsExpr ::= `=' Expr
@@ -2148,7 +2184,7 @@ object Parsers {
21482184 in.token match {
21492185 case EQUALS =>
21502186 in.nextToken()
2151- TypeDef (name, lambdaAbstract(tparams, typ ())).withMods(mods).setComment(in.getDocComment(start))
2187+ TypeDef (name, lambdaAbstract(tparams, toplevelTyp ())).withMods(mods).setComment(in.getDocComment(start))
21522188 case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF =>
21532189 TypeDef (name, lambdaAbstract(tparams, typeBounds())).withMods(mods).setComment(in.getDocComment(start))
21542190 case _ =>
@@ -2276,7 +2312,8 @@ object Parsers {
22762312 /** ConstrApp ::= SimpleType {ParArgumentExprs}
22772313 */
22782314 val constrApp = () => {
2279- val t = annotType()
2315+ // Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code
2316+ val t = checkWildcard(annotType(), fallbackTree = Ident (nme.ERROR ))
22802317 if (in.token == LPAREN ) parArgumentExprss(wrapNew(t))
22812318 else t
22822319 }
0 commit comments