diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-06-23 17:49:59 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-07-04 15:49:07 +0200 |
commit | 59db57f5ac26609186d6338d2d7cfaf1281b78ab (patch) | |
tree | d599b985b5ac5b9f4cb23ef44c60b9bce0d1fcd5 | |
parent | e08735380e8cba8f4b7230f5615e528782a0111a (diff) | |
download | scala-59db57f5ac26609186d6338d2d7cfaf1281b78ab.tar.gz scala-59db57f5ac26609186d6338d2d7cfaf1281b78ab.tar.bz2 scala-59db57f5ac26609186d6338d2d7cfaf1281b78ab.zip |
Route type checker reporting through context
Continue the work started in SI-8450
(no "implicit numeric widening" warning in silent mode),
which was caused by going straight to the reporter instead of
using the context for type error reporting (which buffers in silent mode).
Ideally, this mistake should not be possible: typer should change
the current reporter to buffer where appropriate.
4 files changed, 36 insertions, 28 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala index 6e99b9bd4c..37c39c07be 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala @@ -77,7 +77,7 @@ trait Adaptations { val msg = "Adaptation of argument list by inserting () has been deprecated: " + ( if (isLeakyTarget) "leaky (Object-receiving) target makes this especially dangerous." else "this is unlikely to be what you want.") - context.unit.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(msg)) + context.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(msg)) } } else if (settings.warnAdaptedArgs) context.warning(t.pos, adaptWarningMessage(s"Adapting argument list by creating a ${args.size}-tuple: this may not be what you want.")) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 8e1ceffecd..03890f30f6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -593,6 +593,14 @@ trait Contexts { self: Analyzer => else if (bufferErrors) reportBuffer += (pos -> msg) } + def deprecationWarning(pos: Position, sym: Symbol, msg: String): Unit = + currentRun.reporting.deprecationWarning(pos, sym, msg) + + def featureWarning(pos: Position, featureName: String, featureDesc: String, featureTrait: Symbol, construct: => String = "", required: Boolean): Unit = + currentRun.reporting.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required) + + def echo(pos: Position, msg: String): Unit = reporter.echo(pos, msg) + // nextOuter determines which context is searched next for implicits // (after `this`, which contributes `newImplicits` below.) In // most cases, it is simply the outer context: if we're owned by diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 65f33952d3..43902d1c65 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -536,7 +536,7 @@ trait NamesDefaults { self: Analyzer => def matchesName(param: Symbol) = !param.isSynthetic && ( (param.name == name) || (param.deprecatedParamName match { case Some(`name`) => - context0.unit.deprecationWarning(arg.pos, param, + context0.deprecationWarning(arg.pos, param, s"the parameter name $name has been deprecated. Use ${param.name} instead.") true case _ => false diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 3c215ea10b..349bad555a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -746,7 +746,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (!OK) { val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) = featureTrait getAnnotation LanguageFeatureAnnot - unit.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required) + context.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required) } OK } @@ -942,7 +942,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def adaptConstant(value: Constant): Tree = { val sym = tree.symbol if (sym != null && sym.isDeprecated) - unit.deprecationWarning(tree.pos, sym, s"${sym.toString}${sym.locationString} is deprecated: ${sym.deprecationMessage.getOrElse("")}") + context.deprecationWarning(tree.pos, sym, s"${sym.toString}${sym.locationString} is deprecated: ${sym.deprecationMessage.getOrElse("")}") treeCopy.Literal(tree, value) } @@ -1051,7 +1051,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case coercion => def msg = "inferred view from " + tree.tpe + " to " + pt + " = " + coercion + ":" + coercion.tpe if (settings.logImplicitConv) - unit.echo(tree.pos, msg) + context.echo(tree.pos, msg) debuglog(msg) val silentContext = context.makeImplicit(context.ambiguousErrors) @@ -1211,7 +1211,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case EmptyTree => qual case coercion => if (settings.logImplicitConv) - unit.echo(qual.pos, + context.echo(qual.pos, "applied implicit conversion from %s to %s = %s".format( qual.tpe, searchTemplate, coercion.symbol.defString)) @@ -1276,7 +1276,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper private def validateNoCaseAncestor(clazz: Symbol) = { if (!phase.erasedTypes) { for (ancestor <- clazz.ancestors find (_.isCase)) { - unit.error(clazz.pos, ( + context.error(clazz.pos, ( "case %s has case ancestor %s, but case-to-case inheritance is prohibited."+ " To overcome this limitation, use extractors to pattern match on non-leaf nodes." ).format(clazz, ancestor.fullName)) @@ -1293,7 +1293,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val isValueClass = !clazz.isTrait def where = if (isValueClass) "value class" else "universal trait extending from class Any" def implRestriction(tree: Tree, what: String) = - unit.error(tree.pos, s"implementation restriction: $what is not allowed in $where" + + context.error(tree.pos, s"implementation restriction: $what is not allowed in $where" + "\nThis restriction is planned to be removed in subsequent releases.") /** * Deeply traverses the tree in search of constructs that are not allowed @@ -1322,7 +1322,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } } for (stat <- body) { - def notAllowed(what: String) = unit.error(stat.pos, s"$what is not allowed in $where") + def notAllowed(what: String) = context.error(stat.pos, s"$what is not allowed in $where") stat match { // see https://issues.scala-lang.org/browse/SI-6444 // see https://issues.scala-lang.org/browse/SI-6463 @@ -1350,9 +1350,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper private def validateDerivedValueClass(clazz: Symbol, body: List[Tree]) = { if (clazz.isTrait) - unit.error(clazz.pos, "only classes (not traits) are allowed to extend AnyVal") + context.error(clazz.pos, "only classes (not traits) are allowed to extend AnyVal") if (!clazz.isStatic) - unit.error(clazz.pos, "value class may not be a "+ + context.error(clazz.pos, "value class may not be a "+ (if (clazz.owner.isTerm) "local class" else "member of another class")) if (!clazz.isPrimitiveValueClass) { clazz.primaryConstructor.paramss match { @@ -1360,26 +1360,26 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val decls = clazz.info.decls val paramAccessor = clazz.constrParamAccessors.head if (paramAccessor.isMutable) - unit.error(paramAccessor.pos, "value class parameter must not be a var") + context.error(paramAccessor.pos, "value class parameter must not be a var") val accessor = decls.toList.find(x => x.isMethod && x.accessedOrSelf == paramAccessor) accessor match { case None => - unit.error(paramAccessor.pos, "value class parameter must be a val and not be private[this]") + context.error(paramAccessor.pos, "value class parameter must be a val and not be private[this]") case Some(acc) if acc.isProtectedLocal => - unit.error(paramAccessor.pos, "value class parameter must not be protected[this]") + context.error(paramAccessor.pos, "value class parameter must not be protected[this]") case Some(acc) => if (acc.tpe.typeSymbol.isDerivedValueClass) - unit.error(acc.pos, "value class may not wrap another user-defined value class") + context.error(acc.pos, "value class may not wrap another user-defined value class") checkEphemeral(clazz, body filterNot (stat => stat.symbol != null && stat.symbol.accessedOrSelf == paramAccessor)) } case _ => - unit.error(clazz.pos, "value class needs to have exactly one val parameter") + context.error(clazz.pos, "value class needs to have exactly one val parameter") } } for (tparam <- clazz.typeParams) if (tparam hasAnnotation definitions.SpecializedClass) - unit.error(tparam.pos, "type parameter of value class may not be specialized") + context.error(tparam.pos, "type parameter of value class may not be specialized") } /** Typechecks a parent type reference. @@ -1675,7 +1675,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (!isPastTyper && psym.hasDeprecatedInheritanceAnnotation && !sameSourceFile) { val suffix = psym.deprecatedInheritanceMessage map (": " + _) getOrElse "" val msg = s"inheritance from ${psym.fullLocationString} is deprecated$suffix" - unit.deprecationWarning(parent.pos, psym, msg) + context.deprecationWarning(parent.pos, psym, msg) } if (psym.isSealed && !phase.erasedTypes) @@ -1742,7 +1742,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if ((clazz isNonBottomSubClass ClassfileAnnotationClass) && (clazz != ClassfileAnnotationClass)) { if (!clazz.owner.isPackageClass) - unit.error(clazz.pos, "inner classes cannot be classfile annotations") + context.error(clazz.pos, "inner classes cannot be classfile annotations") else restrictionWarning(cdef.pos, unit, """|subclassing Classfile does not |make your annotation visible at runtime. If that is what @@ -1797,7 +1797,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper private def ensurePredefParentsAreInSameSourceFile(template: Template) = { val parentSyms = template.parents map (_.symbol) filterNot (_ == AnyRefClass) if (parentSyms exists (_.associatedFile != PredefModule.associatedFile)) - unit.error(template.pos, s"All parents of Predef must be defined in ${PredefModule.associatedFile}.") + context.error(template.pos, s"All parents of Predef must be defined in ${PredefModule.associatedFile}.") } /** In order to override this in the TreeCheckers Typer so synthetics aren't re-added * all the time, it is exposed here the module/class typing methods go through it. @@ -1868,7 +1868,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper ConstrArgsInParentOfTraitError(parents1.head, clazz) if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.isTopLevel) - unit.error(clazz.pos, "inner classes cannot be classfile annotations") + context.error(clazz.pos, "inner classes cannot be classfile annotations") if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType]) @@ -1896,7 +1896,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (clazz.isTrait) { for (decl <- clazz.info.decls if decl.isTerm && decl.isEarlyInitialized) { - unit.warning(decl.pos, "Implementation restriction: early definitions in traits are not initialized before the super class is initialized.") + context.warning(decl.pos, "Implementation restriction: early definitions in traits are not initialized before the super class is initialized.") } } @@ -2084,7 +2084,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case xs => xs.map(_.nameString).mkString(" (of ", " with ", ")") } def fail(pos: Position, msg: String): Boolean = { - unit.error(pos, msg) + context.error(pos, msg) false } /* Have to examine all parameters in all lists. @@ -3665,7 +3665,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } if (annType.typeSymbol == DeprecatedAttr && argss.flatten.size < 2) - unit.deprecationWarning(ann.pos, DeprecatedAttr, "@deprecated now takes two arguments; see the scaladoc.") + context.deprecationWarning(ann.pos, DeprecatedAttr, "@deprecated now takes two arguments; see the scaladoc.") if ((typedAnn.tpe == null) || typedAnn.tpe.isErroneous) ErroneousAnnotation else annInfo(typedAnn) @@ -4239,7 +4239,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // it is non-Unit) so we have to retype it. Fortunately it won't come up much // unless the warning is legitimate. if (typed(expr).tpe.typeSymbol != UnitClass) - unit.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded") + context.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded") } val res = treeCopy.Return(tree, checkDead(expr1)).setSymbol(enclMethod.owner) val tp = pluginsTypedReturn(NothingTpe, this, res, restpt.tpe) @@ -4697,7 +4697,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // temporarily use `filter` as an alternative for `withFilter` def tryWithFilterAndFilter(tree: Select, qual: Tree): Tree = { - def warn(sym: Symbol) = unit.deprecationWarning(tree.pos, sym, s"`withFilter' method does not yet exist on ${qual.tpe.widen}, using `filter' method instead") + def warn(sym: Symbol) = context.deprecationWarning(tree.pos, sym, s"`withFilter' method does not yet exist on ${qual.tpe.widen}, using `filter' method instead") silent(_ => typedSelect(tree, qual, nme.withFilter)) orElse { _ => silent(_ => typed1(Select(qual, nme.filter) setPos tree.pos, mode, pt)) match { case SilentResultValue(res) => warn(res.symbol) ; res @@ -5477,11 +5477,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val commonMessage = "macro defs must have explicitly specified return types" def reportFailure() = { ddef.symbol.setFlag(IS_ERROR) - unit.error(ddef.pos, commonMessage) + context.error(ddef.pos, commonMessage) } def reportWarning(inferredType: Type) = { val explanation = s"inference of $inferredType from macro impl's c.Expr[$inferredType] is deprecated and is going to stop working in 2.12" - unit.deprecationWarning(ddef.pos, ddef.symbol, s"$commonMessage ($explanation)") + context.deprecationWarning(ddef.pos, ddef.symbol, s"$commonMessage ($explanation)") } computeMacroDefTypeFromMacroImplRef(ddef, rhs1) match { case ErrorType => ErrorType |