diff --git a/docs/SyntaxSummary.txt b/docs/SyntaxSummary.txt index e40b3fd6c594..1bbdc84d7635 100644 --- a/docs/SyntaxSummary.txt +++ b/docs/SyntaxSummary.txt @@ -99,8 +99,9 @@ grammar. FunArgTypes ::= InfixType | `(' [ FunArgType {`,' FunArgType } ] `)' InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2) - RefinedType ::= WithType {Annotation | [nl] Refinement} Annotated(t, annot), RefinedTypeTree(t, ds) - WithType ::= SimpleType {`with' SimpleType} (deprecated) + RefinedType ::= WithType {[nl] Refinement} RefinedTypeTree(t, ds) + WithType ::= AnnotType {`with' AnnotType} (deprecated) + AnnotType ::= SimpleType {Annotation} Annotated(t, annot) SimpleType ::= SimpleType TypeArgs AppliedTypeTree(t, args) | SimpleType `#' id SelectFromTypeTree(t, name) | StableId @@ -121,9 +122,9 @@ grammar. Expr ::= FunParams `=>' Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr) | Expr1 - FunParams ::= Bindings - | [`implicit'] id - | `_' + FunParams ::= Bindings + | [`implicit'] id + | `_' ExprInParens ::= PostfixExpr `:' Type | Expr BlockResult ::= (FunParams | [`implicit'] id `:' InfixType) => Block @@ -248,7 +249,7 @@ grammar. AccessModifier ::= (`private' | `protected') [AccessQualifier] AccessQualifier ::= `[' (id | `this') `]' - Annotation ::= `@' SimpleType {ArgumentExprs} Apply(tpe, args) + Annotation ::= `@' SimpleType {ParArgumentExprs} Apply(tpe, args) TemplateBody ::= [nl] `{' [SelfType] TemplateStat {semi TemplateStat} `} (self, stats) TemplateStat ::= Import @@ -301,7 +302,7 @@ grammar. TemplateOpt ::= [`extends' Template | [nl] TemplateBody] Template ::= ConstrApps [TemplateBody] | TemplateBody Template(constr, parents, self, stats) ConstrApps ::= ConstrApp {`with' ConstrApp} - ConstrApp ::= SimpleType {ArgumentExprs} Apply(tp, args) + ConstrApp ::= AnnotType {ArgumentExprs} Apply(tp, args) ConstrExpr ::= SelfInvocation | ConstrBlock diff --git a/src/dotty/tools/backend/jvm/GenBCode.scala b/src/dotty/tools/backend/jvm/GenBCode.scala index d7557acecb10..eabf1b660ec9 100644 --- a/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/src/dotty/tools/backend/jvm/GenBCode.scala @@ -38,7 +38,7 @@ class GenBCode extends Phase { def run(implicit ctx: Context): Unit = { - new GenBCodePipeline(entryPoints.toList, new DottyBackendInterface()(ctx))(ctx).run(ctx.compilationUnit.tpdTree) + new GenBCodePipeline(entryPoints.toList, new DottyBackendInterface()(ctx))(ctx).run(ctx.compilationUnit.tpdTree) entryPoints.clear() } } diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 1adabbd2d54e..acbd5b6f0b19 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -302,18 +302,19 @@ trait TypeOps { this: Context => // TODO: Make standalone object. // println(s"normalizing $parents of $cls in ${cls.owner}") // !!! DEBUG var refinements: SimpleMap[TypeName, Type] = SimpleMap.Empty var formals: SimpleMap[TypeName, Symbol] = SimpleMap.Empty - def normalizeToRef(tp: Type): TypeRef = tp match { + def normalizeToRef(tp: Type): TypeRef = tp.dealias match { + case tp: TypeRef => + tp case tp @ RefinedType(tp1, name: TypeName) => val prevInfo = refinements(name) refinements = refinements.updated(name, if (prevInfo == null) tp.refinedInfo else prevInfo & tp.refinedInfo) formals = formals.updated(name, tp1.typeParamNamed(name)) normalizeToRef(tp1) - case tp: TypeRef => - if (tp.symbol.info.isAlias) normalizeToRef(tp.info.bounds.hi) - else tp case ErrorType => defn.AnyClass.typeRef + case AnnotatedType(_, tpe) => + normalizeToRef(tpe) case _ => throw new TypeError(s"unexpected parent type: $tp") } diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index dd2c9bcaa43b..b790772455a6 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -679,25 +679,29 @@ object Parsers { def refinedTypeRest(t: Tree): Tree = { newLineOptWhenFollowedBy(LBRACE) - in.token match { - case AT => refinedTypeRest(atPos(t.pos.start) { Annotated(annot(), t) }) - case LBRACE => refinedTypeRest(atPos(t.pos.start) { RefinedTypeTree(t, refinement()) }) - case _ => t - } + if (in.token == LBRACE) refinedTypeRest(atPos(t.pos.start) { RefinedTypeTree(t, refinement()) }) + else t } - /** WithType ::= SimpleType {`with' SimpleType} (deprecated) + /** WithType ::= AnnotType {`with' AnnotType} (deprecated) */ - def withType(): Tree = withTypeRest(simpleType()) + def withType(): Tree = withTypeRest(annotType()) - def withTypeRest(t: Tree): Tree = { + def withTypeRest(t: Tree): Tree = if (in.token == WITH) { deprecationWarning("`with' as a type operator has been deprecated; use `&' instead") in.nextToken() AndTypeTree(t, withType()) } else t - } + + /** AnnotType ::= SimpleType {Annotation} + */ + def annotType(): Tree = annotTypeRest(simpleType()) + + def annotTypeRest(t: Tree): Tree = + if (in.token == AT) annotTypeRest(atPos(t.pos.start) { Annotated(annot(), t) }) + else t /** SimpleType ::= SimpleType TypeArgs * | SimpleType `#' Id @@ -1425,10 +1429,10 @@ object Parsers { else tree1 } - /** Annotation ::= `@' SimpleType {ArgumentExprs} + /** Annotation ::= `@' SimpleType {ParArgumentExprs} */ def annot() = - adjustStart(accept(AT)) { ensureApplied(argumentExprss(wrapNew(simpleType()))) } + adjustStart(accept(AT)) { ensureApplied(parArgumentExprss(wrapNew(simpleType()))) } def annotations(skipNewLines: Boolean = false): List[Tree] = { if (skipNewLines) newLineOptWhenFollowedBy(AT) @@ -1834,7 +1838,7 @@ object Parsers { /** ConstrApp ::= SimpleType {ParArgumentExprs} */ val constrApp = () => { - val t = simpleType() + val t = annotType() if (in.token == LPAREN) parArgumentExprss(wrapNew(t)) else t } diff --git a/tests/pos/annot.scala b/tests/pos/annot.scala index c3a17ff1dc6f..e6e4f8051ba9 100644 --- a/tests/pos/annot.scala +++ b/tests/pos/annot.scala @@ -1,7 +1,10 @@ import java.beans.Transient +import annotation.unchecked.uncheckedVariance class Test { +// testing combinations of annotation syntax + @SuppressWarnings(Array("hi")) def foo() = ??? // evalutation of annotation on type cannot be deferred as requires implicit resolution(only generic Array$.apply applies here) @SuppressWarnings(Array("hi", "foo")) def foo2() = ??? //can be deferred as there is a non-generic method @@ -11,5 +14,15 @@ class Test { @Transient(false) def bar = ??? @Transient() def baz = ??? + +// testing annotations in types + + class A + trait B + + val x: A @uncheckedVariance with B @uncheckedVariance = ??? + + class C extends A @uncheckedVariance () with B @uncheckedVariance { val x = 10 } + }