From 8acb41bd0a4dc1a6a6e6c20f48cb1c508470551a Mon Sep 17 00:00:00 2001 From: Lex Spoon Date: Tue, 23 Jan 2007 15:34:40 +0000 Subject: - Added default constructors for Settings and G... - Added default constructors for Settings and Global - Added attributed types, if -Xplugtypes is available. This enables non-LAMP people to experiment with type attributes. (This is a merge from the plugtypes branch, revision 9679) The attributes are ignored for now, even with -Xplugtypes, but do get propagated. --- src/compiler/scala/tools/nsc/Global.scala | 10 ++ src/compiler/scala/tools/nsc/Settings.scala | 2 + .../scala/tools/nsc/ast/TreeBrowsers.scala | 13 +++ .../scala/tools/nsc/ast/TreePrinters.scala | 10 ++ src/compiler/scala/tools/nsc/ast/Trees.scala | 33 ++++++- .../scala/tools/nsc/ast/parser/Parsers.scala | 36 +++++-- .../scala/tools/nsc/backend/icode/TypeKinds.scala | 3 + .../scala/tools/nsc/models/SemanticTokens.scala | 2 + .../tools/nsc/reporters/AbstractReporter.scala | 1 - src/compiler/scala/tools/nsc/symtab/Types.scala | 105 ++++++++++++++++++++- .../scala/tools/nsc/symtab/classfile/Pickler.scala | 9 +- .../scala/tools/nsc/transform/LiftCode.scala | 2 + .../scala/tools/nsc/typechecker/RefChecks.scala | 2 + .../scala/tools/nsc/typechecker/Typers.scala | 9 +- .../scala/tools/nsc/typechecker/Variances.scala | 2 + 15 files changed, 223 insertions(+), 16 deletions(-) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 6466a02d8d..03848e7439 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -35,6 +35,16 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable with Trees with CompilationUnits { + // alternate constructors ------------------------------------------ + def this(reporter: Reporter) = + this(new Settings(err => reporter.error(null,err)), + reporter) + + def this(settings: Settings) = + this(settings, new ConsoleReporter) + + def this() = this(new Settings, new ConsoleReporter) + // sub-components -------------------------------------------------- object treePrinters extends TreePrinters { val global: Global.this.type = Global.this diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 16f7acfe45..bde12d3be0 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -10,6 +10,7 @@ import java.lang.System import java.io.File class Settings(error: String => unit) { + def this() = this(Console.println) private var allsettings: List[Setting] = List() @@ -131,6 +132,7 @@ class Settings(error: String => unit) { val Xunapply = BooleanSetting("-Xunapply", "enable unapply pattern matching") Xunapply.value = true val Xplugtypes = BooleanSetting("-Xplugtypes", "parse but ignore annotations in more locations") + //Xplugtypes.value = true // just while experimenting val Xkilloption = BooleanSetting("-Xkilloption", "optimizes option types") val XprintOuterMatches = BooleanSetting("-XprintOuterMatches", "prints outer-checks caused by pattern matching") diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala index ccbc9dd764..ce17c7f1ee 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala @@ -353,6 +353,9 @@ abstract class TreeBrowsers { case TypeTree() => Pair("TypeTree", EMPTY) + case AttributedTypeTree(attribs, tpt) => + Pair("AttributedTypeTree", EMPTY) + case SingletonTypeTree(ref) => Pair("SingletonType", EMPTY) @@ -494,6 +497,9 @@ abstract class TreeBrowsers { case TypeTree() => Nil + case AttributedTypeTree(attribs, tpt) => + attribs ::: List(tpt) + case SingletonTypeTree(ref) => List(ref) @@ -645,6 +651,13 @@ abstract class TreeBrowsers { toDocument(result) :: ")") ) + case AttributedType(attribs, tp) => + Document.group( + Document.nest(4, "AttributedType(" :/: + attribs.mkString("[", ",", "]") :/: + "," :/: toDocument(tp) :: ")") + ) + case _ => abort("Unknown case: " + t.toString()) } diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 0ba2519e0d..3b3fca377c 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -304,6 +304,16 @@ abstract class TreePrinters { tree.tpe.toString() ) + case AttributedTypeTree(attribs, tree) => + for(val attrib <- attribs) { + print("[") + print(attrib) + print("]") + } + if(!attribs.isEmpty) + print(" ") + print(tree) + case SingletonTypeTree(ref) => print(ref); print(".type") diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 8f21650b13..8df742bd59 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -137,6 +137,9 @@ trait Trees requires Global { if (hasSymbol) symbol = tree.symbol this } + + def withAttributes(attribs: List[Tree]) = + AttributedTypeTree(attribs, this) } trait SymTree extends Tree { @@ -153,6 +156,8 @@ trait Trees requires Global { override def isTerm = true } + /** A tree for a type. Note that not all type trees implement + * this trait; in particular, Ident's are an exception. */ trait TypTree extends Tree { override def isType = true } @@ -622,7 +627,11 @@ trait Trees requires Global { def Literal(value: Any): Literal = Literal(Constant(value)) - /** General type term, introduced by the phase RefCheck. */ + /** A synthetic term holding an arbitrary type. Not to be confused with + * with TypTree, the trait for trees that are only used for type trees. + * TypeTree's are inserted in several places, but most notably in + * RefCheck, where the arbitrary type trees are all replaced by + * TypeTree's. */ case class TypeTree() extends TypTree { var original: Tree = _ @@ -630,12 +639,19 @@ trait Trees requires Global { original = tree setPos(tree.pos) } + override def isEmpty = (tpe eq null) || tpe == NoType } def TypeTree(tp: Type): TypeTree = TypeTree() setType tp // def TypeTree(tp: Type, tree : Tree): TypeTree = TypeTree(tree) setType tp + /** A type tree that has attributes attached to it */ + case class AttributedTypeTree(attribs: List[Tree], tpt: Tree) + extends TypTree { + override def withAttributes(attribs: List[Tree]) = + AttributedTypeTree(attribs:::this.attribs, this) + } /** Singleton type, eliminated by RefCheck */ case class SingletonTypeTree(ref: Tree) @@ -697,7 +713,8 @@ trait Trees requires Global { case Select(qualifier, selector) => case Ident(name) => case Literal(value) => - case TypeTree() => + case TypeTree() => (introduced by refcheck) + case AttributedTypeTree(attribs, tpt) => (eliminated by uncurry) case SingletonTypeTree(ref) => (eliminated by uncurry) case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry) case CompoundTypeTree(templ: Template) => (eliminated by uncurry) @@ -743,6 +760,7 @@ trait Trees requires Global { def Ident(tree: Tree, name: Name): Ident def Literal(tree: Tree, value: Constant): Literal def TypeTree(tree: Tree): TypeTree + def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree): AttributedTypeTree def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree @@ -825,6 +843,8 @@ trait Trees requires Global { new Literal(value).copyAttrs(tree) def TypeTree(tree: Tree) = new TypeTree().copyAttrs(tree) + def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree) = + new AttributedTypeTree(attribs, tpt) def SingletonTypeTree(tree: Tree, ref: Tree) = new SingletonTypeTree(ref).copyAttrs(tree) def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = @@ -1024,6 +1044,11 @@ trait Trees requires Global { case t @ TypeTree() => t case _ => copy.TypeTree(tree) } + def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree) = tree match { + case t @ AttributedTypeTree(attribs0, tpt0) + if (attribs0==attribs) && (tpt0==tpt) => t + case _ => copy.AttributedTypeTree(tree, attribs, tpt) + } def SingletonTypeTree(tree: Tree, ref: Tree) = tree match { case t @ SingletonTypeTree(ref0) if ref0 == ref => t @@ -1152,6 +1177,8 @@ trait Trees requires Global { copy.Literal(tree, value) case TypeTree() => copy.TypeTree(tree) + case AttributedTypeTree(attribs, tpt) => + copy.AttributedTypeTree(tree, transformTrees(attribs), transform(tpt)) case SingletonTypeTree(ref) => copy.SingletonTypeTree(tree, transform(ref)) case SelectFromTypeTree(qualifier, selector) => @@ -1288,6 +1315,8 @@ trait Trees requires Global { ; case TypeTree() => ; + case AttributedTypeTree(attribs, tpt) => + traverseTrees(attribs); traverse(tpt) case SingletonTypeTree(ref) => traverse(ref) case SelectFromTypeTree(qualifier, selector) => diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index f0a3808c01..53314b4581 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -648,7 +648,7 @@ trait Parsers requires SyntaxAnalyzer { * | Path `.' type * | `(' Type `)' * | `{' [Type `,' [Types [`,']]] `}' - * | AttributeClauses SimpleType // if Xplugtypes enabled + * | TypeAttributes SimpleType (if -Xplugtypes) * SimpleTypePattern ::= SimpleTypePattern1 [TypePatternArgs] * SimpleTypePattern1 ::= SimpleTypePattern1 "#" Id * | StableId @@ -656,8 +656,11 @@ trait Parsers requires SyntaxAnalyzer { * | `{' [ArgTypePattern `,' [ArgTypePatterns [`,']]] `}' */ def simpleType(isPattern: boolean): Tree = { - if(settings.Xplugtypes.value) - attributeClauses + val attribs = + if(settings.Xplugtypes.value) + typeAttributes + else + Nil val pos = in.currentPos var t: Tree = @@ -686,18 +689,22 @@ trait Parsers requires SyntaxAnalyzer { // System.err.println("SIMPLE_TYPE: " + r.pos + " " + r + " => " + x.pos + " " + x) x } - while (true) { + + // scan for # and [] + var done = false + while (!done) { if (in.token == HASH) { t = atPos(in.skipToken()) { SelectFromTypeTree(t, ident().toTypeName) } } else if (in.token == LBRACKET) { t = atPos(pos) { AppliedTypeTree(t, typeArgs(isPattern)) } - if (isPattern) return t + if (isPattern) done=true } else - return t + done=true } - null; //dummy + + t.withAttributes(attribs) } /** TypeArgs ::= `[' ArgTypes `]' @@ -2147,6 +2154,21 @@ trait Parsers requires SyntaxAnalyzer { defs } + /** TypeAttributes ::= (`[' Exprs `]') * + * + * Type attributes may be arbitrary expressions. + */ + def typeAttributes: List[Tree] = { + val exps = new ListBuffer[Tree] + while(in.token == LBRACKET) { + accept(LBRACKET) + exps ++= argExprs + accept(RBRACKET) + } + exps.toList + } + + /** RefineStatSeq ::= RefineStat {StatementSeparator RefineStat} * RefineStat ::= Dcl * | type TypeDef diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index dcf98c2493..20c1c190ed 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -401,6 +401,9 @@ trait TypeKinds requires ICodes { REFERENCE(sym) } + case AttributedType(attribs, tp) => + toTypeKind(tp) + case _ => abort("Unknown type: " + t) } diff --git a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala index 3d4b199304..efe79e2baf 100644 --- a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala +++ b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala @@ -354,6 +354,7 @@ class SemanticTokens(val compiler: Global) { case tpe0 : ThisType => tree match { case stt : SingletonTypeTree => stt.ref match { case ths : This => build(ths); + case _ => Console.err.println("UNKNOWN TPE11: " + tpe0 + " " + stt + " " + stt.ref + " " + stt.ref.getClass() + " " + unit.source.dbg(tree.pos)); } case tt : This => @@ -476,6 +477,7 @@ class SemanticTokens(val compiler: Global) { case tree : DocDef => build(tree.definition); case tree: Import => build(tree.expr) case tree: AppliedTypeTree => ; + case tree: AttributedTypeTree => ; case tree: SingletonTypeTree => ; case tree: Super => ; case tree: Literal => ; diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala index b899c04999..3e3d07cb92 100644 --- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala @@ -22,7 +22,6 @@ abstract class AbstractReporter extends Reporter { var nowarn : Boolean = false; def displayPrompt : Unit; - // XXX: while is pos ignored? protected def info0(pos : Position, msg : String, severity : Severity, force : Boolean) : Unit = severity match { case INFO => if (force || verbose) display(pos, msg, severity); case WARNING => { diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index ebef3e87b5..24acb66646 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -29,6 +29,7 @@ import Flags._ case OverloadedType(pre, tparams, alts) => case AntiPolyType(pre: Type, targs) => case TypeVar(_, _) => + case AttributedType(attribs, tp) => */ trait Types requires SymbolTable { @@ -47,7 +48,7 @@ trait Types requires SymbolTable { private var explainSwitch = false private var checkMalformedSwitch = true - private var globalVariance = 1//only necessary of healTypes = true? + private var globalVariance = 1//only necessary if healTypes = true? private final val healTypes = false private final val LubGlbMargin = 0 @@ -55,6 +56,18 @@ trait Types requires SymbolTable { /** The base class for all types */ abstract class Type { + /** Add an attribute to this type */ + def withAttribute(attrib: Any) = withAttributes(List(attrib)) + + /** Add a number of attributes to this type */ + def withAttributes(attribs: List[Any]): Type = + attribs match { + case Nil => this + case _ => AttributedType(attribs, this) + } + + /** Remove any attributes from this type */ + def withoutAttributes = this /** Types for which asSeenFrom always is the identity, no matter what * prefix or owner. @@ -1069,7 +1082,79 @@ trait Types requires SymbolTable { override def toString(): String = if (constr.inst eq null) "" else if (constr.inst eq NoType) "?" + origin - else constr.inst.toString(); + else constr.inst.toString; + } + + /** A type carrying some attributes. The attributes have no significance + * to the core compiler, but can be observed by type-system plugins. The + * core compiler does take care to propagate attributes and to save them + * in the symbol tables of object files. */ + case class AttributedType(attributes: List[Any], tp: Type) extends Type { + override def toString(): String = { + val attString = + if(attributes.isEmpty) + "" + else + attributes.mkString("[", "] [", "] ") + + attString + tp + } + + + /** Add a number of attributes to this type */ + override def withAttributes(attribs: List[Any]): Type = + AttributedType(attribs:::this.attributes, this) + + /** Remove any attributes from this type */ + override def withoutAttributes = tp.withoutAttributes + + override def isTrivial: boolean = tp.isTrivial + + /** Return the argument, unless it is eq to tp, in which case return the + * receiver. This method is used for methods like singleDeref and widen, + * so that the attributes are remembered more frequently. */ + private def maybeRewrap(newtp: Type) = + if(newtp eq tp) this else newtp + + // ---------------- methods forwarded to tp ------------------ \\ + + override def symbol: Symbol = tp.symbol + override def singleDeref: Type = maybeRewrap(tp.singleDeref) + override def widen: Type = maybeRewrap(tp.widen) + override def deconst: Type = maybeRewrap(tp.deconst) + override def bounds: TypeBounds = { + val oftp = tp.bounds + oftp match { + case TypeBounds(lo, hi) if((lo eq this) && (hi eq this)) => TypeBounds(this,this) + case _ => oftp + } + } + override def parents: List[Type] = tp.parents + override def prefix: Type = tp.prefix + override def typeArgs: List[Type] = tp.typeArgs + override def resultType: Type = maybeRewrap(tp.resultType) + override def finalResultType: Type = maybeRewrap(tp.finalResultType) + override def paramSectionCount: int = tp.paramSectionCount + override def paramTypes: List[Type] = tp.paramTypes + override def typeParams: List[Symbol] = tp.typeParams + override def isStable: boolean = tp.isStable + override def nonPrivateDecl(name: Name): Symbol = tp.nonPrivateDecl(name) + override def baseType(clazz: Symbol): Type = tp.baseType(clazz) + override def closure: Array[Type] = { + val oftp = tp.closure + if((oftp.length == 1 &&) (oftp(0) eq this)) + Array(this) + else + oftp + } + override def closureDepth: int = tp.closureDepth + override def baseClasses: List[Symbol] = tp.baseClasses + override def cloneInfo(owner: Symbol) = maybeRewrap(cloneInfo(owner)) + override def isComplete: boolean = tp.isComplete + override def complete(sym: Symbol) = tp.complete(sym) + override def load(sym: Symbol): unit = tp.load(sym) + override def findMember(name: Name, excludedFlags: int, requiredFlags: long, stableOnly: boolean): Symbol = + tp.findMember(name, excludedFlags, requiredFlags, stableOnly) } /** A class representing an as-yet unevaluated type. @@ -1077,6 +1162,7 @@ trait Types requires SymbolTable { abstract class LazyType extends Type { override def isComplete: boolean = false override def complete(sym: Symbol): unit + override def toString = "LazyType" } /** A class representing a lazy type with known type parameters. @@ -1412,6 +1498,12 @@ trait Types requires SymbolTable { case TypeVar(_, constr) => if (constr.inst != NoType) this(constr.inst) else tp + case AttributedType(attribs, atp) => + val atp1 = this(atp) + if(atp1 eq atp) + tp + else + AttributedType(attribs, atp1) case _ => tp // throw new Error("mapOver inapplicable for " + tp); @@ -1720,6 +1812,7 @@ trait Types requires SymbolTable { case TypeBounds(_, _) => mapOver(tp) case MethodType(_, _) => mapOver(tp) case TypeVar(_, _) => mapOver(tp) + case AttributedType(_,_) => mapOver(tp) case _ => tp } } @@ -1849,6 +1942,10 @@ trait Types requires SymbolTable { case Pair(_, TypeVar(_, constr2)) => if (constr2.inst != NoType) tp1 =:= constr2.inst else constr2 instantiate (wildcardToTypeVarMap(tp1)) + case Pair(AttributedType(_,atp), _) => + isSameType(atp, tp2) + case Pair(_, AttributedType(_,atp)) => + isSameType(tp1, atp) case _ => if (tp1.isStable && tp2.isStable) { var origin1 = tp1 @@ -1951,6 +2048,10 @@ trait Types requires SymbolTable { case Pair(TypeVar(_, constr1), _) => if (constr1.inst != NoType) constr1.inst <:< tp2 else { constr1.hibounds = tp2 :: constr1.hibounds; true } + case Pair(AttributedType(_,atp1), _) => + atp1 <:< tp2 + case Pair(_, AttributedType(_,atp2)) => + tp1 <:< atp2 case Pair(_, TypeRef(pre2, sym2, args2)) if sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo) => true diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 7a9f044064..857f9b9db2 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -144,6 +144,9 @@ abstract class Pickler extends SubComponent { putType(restpe); putTypes(formals) case PolyType(tparams, restpe) => putType(restpe); putSymbols(tparams) + case AttributedType(attribs, tp) => + putType(tp) // the attributes should be stored, but it is not yet + // decided how to handle that. case _ => throw new FatalError("bad type: " + tp + "(" + tp.getClass() + ")") } @@ -204,7 +207,7 @@ abstract class Pickler extends SubComponent { /** Write an entry */ private def writeEntry(entry: AnyRef): unit = { - def writeBody: int = entry match { + def writeBody(entry: AnyRef): int = entry match { case name: Name => writeName(name) if (name.isTermName) TERMname else TYPEname @@ -268,12 +271,14 @@ abstract class Pickler extends SubComponent { for (val c <- cs) writeRef(cs); ATTRIBUTE */ + case AttributedType(attribs, tp) + => writeBody(tp) // obviously, this should be improved case _ => throw new FatalError("bad entry: " + entry + " " + entry.getClass())//debug } val startpos = writeIndex writeByte(0); writeByte(0) - patchNat(startpos, writeBody) + patchNat(startpos, writeBody(entry)) patchNat(startpos + 1, writeIndex - (startpos + 2)) } diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index bd6050f99a..9e87b4fee4 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -213,6 +213,8 @@ abstract class LiftCode extends Transform { if (_log_reify_type_) Console.println("cannot handle MethodType "+tp); null case PolyType(tparams, result) => if (_log_reify_type_) Console.println("cannot handle PolyType "+tp); null; + case AttributedType(attribs, tp) => + reify(tp) case _ => null } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 62d2185600..407068299b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -366,6 +366,8 @@ abstract class RefChecks extends InfoTransform { validateVariance(result, variance) case PolyType(tparams, result) => validateVariance(result, variance) + case AttributedType(attribs, tp) => + validateVariance(tp, variance) } def validateVariances(tps: List[Type], variance: int): unit = diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 9faffe5466..aa81ba6de3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2150,6 +2150,11 @@ trait Typers requires Analyzer { if (value.tag == UnitTag) UnitClass.tpe else ConstantType(value)) + case AttributedTypeTree(attribs, tpt) => + attribs.foreach(t => typed(t, EXPRmode, WildcardType)) + val tptTyped = typed1(tpt, mode, pt) + tptTyped setType (tptTyped.tpe.withAttributes(attribs)) + case SingletonTypeTree(ref) => val ref1 = checkStable(typed(ref, EXPRmode | QUALmode, AnyRefClass.tpe)) tree setType ref1.tpe.resultType @@ -2159,7 +2164,7 @@ trait Typers requires Analyzer { tree setSymbol sel.symbol setType typedSelect(typedType(qual), selector).tpe case tree @ CompoundTypeTree(templ: Template) => - tree setType { + (tree setType { val parents1 = List.mapConserve(templ.parents)(typedType) if (parents1 exists (.tpe.isError)) ErrorType else { @@ -2168,7 +2173,7 @@ trait Typers requires Analyzer { newTyper(context.make(templ, self.symbol, decls)).typedRefinement(templ.body) self } - } + }) : CompoundTypeTree case AppliedTypeTree(tpt, args) => val tpt1 = typed1(tpt, mode | FUNmode | TAPPmode, WildcardType) diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/compiler/scala/tools/nsc/typechecker/Variances.scala index 30b89200bb..43e394cd91 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Variances.scala @@ -79,5 +79,7 @@ trait Variances { flip(varianceInTypes(formals)(tparam)) & varianceInType(restpe)(tparam) case PolyType(tparams, restpe) => flip(varianceInSyms(tparams)(tparam)) & varianceInType(restpe)(tparam) + case AttributedType(attribs, tp) => + varianceInType(tp)(tparam) } } -- cgit v1.2.3