diff options
Diffstat (limited to 'src/compiler')
5 files changed, 52 insertions, 34 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 96ecf51e44..04f95455a5 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -455,28 +455,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def inheritanceDiagram = makeInheritanceDiagram(this) def contentDiagram = makeContentDiagram(this) - def groupSearch[T](extractor: Comment => T, default: T): T = { - // query this template - if (comment.isDefined) { - val entity = extractor(comment.get) - if (entity != default) return entity + def groupSearch[T](extractor: Comment => Option[T]): Option[T] = { + val comments = comment +: linearizationTemplates.collect { case dtpl: DocTemplateImpl => dtpl.comment } + comments.flatten.map(extractor).flatten.headOption orElse { + Option(inTpl) flatMap (_.groupSearch(extractor)) } - // query linearization - if (!sym.isPackage) - for (tpl <- linearizationTemplates.collect{ case dtpl: DocTemplateImpl if dtpl!=this => dtpl}) { - val entity = tpl.groupSearch(extractor, default) - if (entity != default) return entity - } - // query inTpl, going up the ownerChain - if (inTpl != null) - inTpl.groupSearch(extractor, default) - else - default } - def groupDescription(group: String): Option[Body] = groupSearch(_.groupDesc.get(group), if (group == defaultGroup) defaultGroupDesc else None) - def groupPriority(group: String): Int = groupSearch(_.groupPrio.get(group) match { case Some(prio) => prio; case _ => 0 }, if (group == defaultGroup) defaultGroupPriority else 0) - def groupName(group: String): String = groupSearch(_.groupNames.get(group) match { case Some(name) => name; case _ => group }, if (group == defaultGroup) defaultGroupName else group) + def groupDescription(group: String): Option[Body] = groupSearch(_.groupDesc.get(group)) orElse { if (group == defaultGroup) defaultGroupDesc else None } + def groupPriority(group: String): Int = groupSearch(_.groupPrio.get(group)) getOrElse { if (group == defaultGroup) defaultGroupPriority else 0 } + def groupName(group: String): String = groupSearch(_.groupNames.get(group)) getOrElse { if (group == defaultGroup) defaultGroupName else group } } abstract class PackageImpl(sym: Symbol, inTpl: PackageImpl) extends DocTemplateImpl(sym, inTpl) with Package { diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala index cddbd62994..817ec47ab3 100644 --- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala @@ -19,9 +19,15 @@ abstract class Reporter { class Severity(val id: Int) extends severity.Value { var count: Int = 0 } - val INFO = new Severity(0) - val WARNING = new Severity(1) - val ERROR = new Severity(2) + val INFO = new Severity(0) { + override def toString: String = "INFO" + } + val WARNING = new Severity(1) { + override def toString: String = "WARNING" + } + val ERROR = new Severity(2) { + override def toString: String = "ERROR" + } /** Whether very long lines can be truncated. This exists so important * debugging information (like printing the classpath) is not rendered diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index e67d6814f1..3ac5d388d3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -373,6 +373,7 @@ trait MethodSynthesis { // spot that brand of them. In other words it's an artifact of the implementation. val tpt = derivedSym.tpe.finalResultType match { case ExistentialType(_, _) => TypeTree() + case _ if mods.isDeferred => TypeTree() case tp => TypeTree(tp) } tpt setPos derivedSym.pos.focus diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 76ff341d3f..c5245c4e9e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -414,7 +414,17 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // (the prefix of the argument passed to the unapply must equal the prefix of the type of the binder) val treeMaker = TypeTestTreeMaker(patBinder, patBinder, extractor.paramType, extractor.paramType)(pos, extractorArgTypeTest = true) (List(treeMaker), treeMaker.nextBinder) - } else (Nil, patBinder) + } else { + // no type test needed, but the tree maker relies on `patBinderOrCasted` having type `extractor.paramType` (and not just some type compatible with it) + // SI-6624 shows this is necessary because apparently patBinder may have an unfortunate type (.decls don't have the case field accessors) + // TODO: get to the bottom of this -- I assume it happens when type checking infers a weird type for an unapply call + // by going back to the parameterType for the extractor call we get a saner type, so let's just do that for now + /* TODO: uncomment when `settings.developer` and `devWarning` become available + if (settings.developer.value && !(patBinder.info =:= extractor.paramType)) + devWarning(s"resetting info of $patBinder: ${patBinder.info} to ${extractor.paramType}") + */ + (Nil, patBinder setInfo extractor.paramType) + } withSubPats(typeTestTreeMaker :+ extractor.treeMaker(patBinderOrCasted, pos), extractor.subBindersAndPatterns: _*) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1cfc8c909b..42c7d4a6b8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1058,6 +1058,10 @@ trait Typers extends Modes with Adaptations with Tags { instantiateToMethodType(mt) case _ => + def shouldInsertApply(tree: Tree) = inAllModes(mode, EXPRmode | FUNmode) && (tree.tpe match { + case _: MethodType | _: OverloadedType | _: PolyType => false + case _ => applyPossible + }) def applyPossible = { def applyMeth = member(adaptToName(tree, nme.apply), nme.apply) dyna.acceptsApplyDynamic(tree.tpe) || ( @@ -1071,14 +1075,12 @@ trait Typers extends Modes with Adaptations with Tags { adaptType() else if ( inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application - tree.symbol != null && tree.symbol.isTermMacro) // of a macro + tree.symbol != null && tree.symbol.isTermMacro && // of a macro + !tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined) macroExpand(this, tree, mode, pt) else if (inAllModes(mode, PATTERNmode | FUNmode)) adaptConstrPattern() - else if (inAllModes(mode, EXPRmode | FUNmode) && - !tree.tpe.isInstanceOf[MethodType] && - !tree.tpe.isInstanceOf[OverloadedType] && - applyPossible) + else if (shouldInsertApply(tree)) insertApply() else if (!context.undetparams.isEmpty && !inPolyMode(mode)) { // (9) assert(!inHKMode(mode), modeString(mode)) //@M @@ -3772,9 +3774,14 @@ trait Typers extends Modes with Adaptations with Tags { case t: ValOrDefDef => t.rhs case t => t } - val (outer, explicitTargs) = cxTree1 match { + val cxTree2 = cxTree1 match { + case Typed(t, tpe) => t // ignore outer type annotation + case t => t + } + val (outer, explicitTargs) = cxTree2 match { case TypeApply(fun, targs) => (fun, targs) case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs) + case Select(TypeApply(fun, targs), nme) => (Select(fun, nme), targs) case t => (t, Nil) } def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty @@ -4855,9 +4862,9 @@ trait Typers extends Modes with Adaptations with Tags { // find out whether the programmer is trying to eta-expand a macro def // to do that we need to typecheck the tree first (we need a symbol of the eta-expandee) // that typecheck must not trigger macro expansions, so we explicitly prohibit them - // Q: "but, " - you may ask - ", `typed1` doesn't call adapt, which does macro expansion, so why explicit check?" - // A: solely for robustness reasons. this mechanism might change in the future, which might break unprotected code - val exprTyped = context.withMacrosDisabled(typed1(expr, mode, pt)) + // however we cannot do `context.withMacrosDisabled` + // because `expr` might contain nested macro calls (see SI-6673) + val exprTyped = typed1(expr updateAttachment SuppressMacroExpansionAttachment, mode, pt) exprTyped match { case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous => MacroEtaError(exprTyped) @@ -5001,8 +5008,14 @@ trait Typers extends Modes with Adaptations with Tags { } def typedTypeTree(tree: TypeTree) = { - if (tree.original != null) - tree setType typedType(tree.original, mode).tpe + if (tree.original != null) { + val newTpt = typedType(tree.original, mode) + tree setType newTpt.tpe + newTpt match { + case tt @ TypeTree() => tree setOriginal tt.original + case _ => tree + } + } else // we should get here only when something before failed // and we try again (@see tryTypedApply). In that case we can assign |