@@ -19,7 +19,7 @@ import StdNames._
19
19
import util .Positions ._
20
20
import Constants ._
21
21
import ScriptParsers ._
22
- import annotation .switch
22
+ import scala . annotation .{ tailrec , switch }
23
23
import util .DotClass
24
24
import rewrite .Rewrites .patch
25
25
@@ -648,12 +648,19 @@ object Parsers {
648
648
}
649
649
650
650
/* ------------- TYPES ------------------------------------------------------ */
651
+ /** Same as [[typ ]], but emits a syntax error if it returns a wildcard.
652
+ */
653
+ def toplevelTyp (): Tree = {
654
+ val t = typ()
655
+ for (wildcardPos <- findWildcardType(t)) syntaxError(" unbound wildcard type" , wildcardPos)
656
+ t
657
+ }
651
658
652
- /** Type ::= FunArgTypes `=>' Type
659
+ /** Type ::= FunArgTypes `=>' Type
653
660
* | HkTypeParamClause `->' Type
654
- * | InfixType
661
+ * | InfixType
655
662
* FunArgTypes ::= InfixType
656
- * | `(' [ FunArgType {`,' FunArgType } ] `)'
663
+ * | `(' [ FunArgType {`,' FunArgType } ] `)'
657
664
*/
658
665
def typ (): Tree = {
659
666
val start = in.offset
@@ -823,7 +830,7 @@ object Parsers {
823
830
/** ParamValueType ::= Type [`*']
824
831
*/
825
832
def paramValueType (): Tree = {
826
- val t = typ ()
833
+ val t = toplevelTyp ()
827
834
if (isIdent(nme.raw.STAR )) {
828
835
in.nextToken()
829
836
atPos(t.pos.start) { PostfixOp (t, nme.raw.STAR ) }
@@ -845,7 +852,7 @@ object Parsers {
845
852
atPos(in.offset) { TypeBoundsTree (bound(SUPERTYPE ), bound(SUBTYPE )) }
846
853
847
854
private def bound (tok : Int ): Tree =
848
- if (in.token == tok) { in.nextToken(); typ () }
855
+ if (in.token == tok) { in.nextToken(); toplevelTyp () }
849
856
else EmptyTree
850
857
851
858
/** TypeParamBounds ::= TypeBounds {`<%' Type} {`:' Type}
@@ -859,26 +866,37 @@ object Parsers {
859
866
def contextBounds (pname : TypeName ): List [Tree ] = in.token match {
860
867
case COLON =>
861
868
atPos(in.skipToken) {
862
- AppliedTypeTree (typ (), Ident (pname))
869
+ AppliedTypeTree (toplevelTyp (), Ident (pname))
863
870
} :: contextBounds(pname)
864
871
case VIEWBOUND =>
865
872
deprecationWarning(" view bounds `<%' are deprecated, use a context bound `:' instead" )
866
873
atPos(in.skipToken) {
867
- Function (Ident (pname) :: Nil , typ ())
874
+ Function (Ident (pname) :: Nil , toplevelTyp ())
868
875
} :: contextBounds(pname)
869
876
case _ =>
870
877
Nil
871
878
}
872
879
873
880
def typedOpt (): Tree =
874
- if (in.token == COLON ) { in.nextToken(); typ () }
881
+ if (in.token == COLON ) { in.nextToken(); toplevelTyp () }
875
882
else TypeTree ()
876
883
877
884
def typeDependingOn (location : Location .Value ): Tree =
878
885
if (location == Location .InParens ) typ()
879
886
else if (location == Location .InPattern ) refinedType()
880
887
else infixType()
881
888
889
+ /** Checks whether `t` is a wildcard type.
890
+ * If it is, returns the [[Position ]] where the wildcard occurs.
891
+ */
892
+ @ tailrec
893
+ private final def findWildcardType (t : Tree ): Option [Position ] = t match {
894
+ case TypeBoundsTree (_, _) => Some (t.pos)
895
+ case Parens (t1) => findWildcardType(t1)
896
+ case Annotated (_, t1) => findWildcardType(t1)
897
+ case _ => None
898
+ }
899
+
882
900
/* ----------- EXPRESSIONS ------------------------------------------------ */
883
901
884
902
/** EqualsExpr ::= `=' Expr
0 commit comments