Skip to content

Commit 54655b3

Browse files
committed
Merge pull request scala#1640 from paulp/xdev
Added -Xdev setting... you know, for devs
2 parents df576c8 + 7936ce5 commit 54655b3

23 files changed

+59
-42
lines changed

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
253253
if (settings.debug.value)
254254
body
255255
}
256-
// Warnings issued only under -Ydebug. For messages which should reach
257-
// developer ears, but are not adequately actionable by users.
258-
@inline final override def debugwarn(msg: => String) {
259-
if (settings.debug.value)
260-
warning(msg)
256+
/** This is for WARNINGS which should reach the ears of scala developers
257+
* whenever they occur, but are not useful for normal users. They should
258+
* be precise, explanatory, and infrequent. Please don't use this as a
259+
* logging mechanism. !!! is prefixed to all messages issued via this route
260+
* to make them visually distinct.
261+
*/
262+
@inline final override def devWarning(msg: => String) {
263+
if (settings.developer.value || settings.debug.value)
264+
warning("!!! " + msg)
261265
}
262266

263267
private def elapsedMessage(msg: String, start: Long) =

src/compiler/scala/tools/nsc/backend/icode/GenICode.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,8 +1251,11 @@ abstract class GenICode extends SubComponent {
12511251
val sym = (
12521252
if (!tree.symbol.isPackageClass) tree.symbol
12531253
else tree.symbol.info.member(nme.PACKAGE) match {
1254-
case NoSymbol => assert(false, "Cannot use package as value: " + tree) ; NoSymbol
1255-
case s => debugwarn("Bug: found package class where package object expected. Converting.") ; s.moduleClass
1254+
case NoSymbol =>
1255+
abort("Cannot use package as value: " + tree)
1256+
case s =>
1257+
devWarning(s"Found ${tree.symbol} where a package object is required. Converting to ${s.moduleClass}")
1258+
s.moduleClass
12561259
}
12571260
)
12581261
debuglog("LOAD_MODULE from %s: %s".format(tree.shortClass, sym))

src/compiler/scala/tools/nsc/backend/icode/ICodes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ abstract class ICodes extends AnyRef
2828
with Repository
2929
{
3030
val global: Global
31-
import global.{ log, definitions, settings, perRunCaches }
31+
import global.{ log, definitions, settings, perRunCaches, devWarning }
3232

3333
/** The ICode representation of classes */
3434
val classes = perRunCaches.newMap[global.Symbol, IClass]()
@@ -82,7 +82,7 @@ abstract class ICodes extends AnyRef
8282
// Something is leaving open/empty blocks around (see SI-4840) so
8383
// let's not kill the deal unless it's nonempty.
8484
if (b.isEmpty) {
85-
log("!!! Found open but empty block while inlining " + m + ": removing from block list.")
85+
devWarning(s"Found open but empty block while inlining $m: removing from block list.")
8686
m.code removeBlock b
8787
}
8888
else dumpMethodAndAbort(m, b)

src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ abstract class ReachingDefinitions {
5252
// it makes it harder to spot the real problems.
5353
val result = (a.stack, b.stack).zipped map (_ ++ _)
5454
if (settings.debug.value && (a.stack.length != b.stack.length))
55-
debugwarn("Mismatched stacks in ReachingDefinitions#lub2: " + a.stack + ", " + b.stack + ", returning " + result)
55+
devWarning(s"Mismatched stacks in ReachingDefinitions#lub2: ${a.stack}, ${b.stack}, returning $result")
5656
result
5757
}
5858
)

src/compiler/scala/tools/nsc/settings/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ trait ScalaSettings extends AbsScalaSettings
7474
val assemextdirs = StringSetting ("-Xassem-extdirs", "dirs", "(Requires -target:msil) List of directories containing assemblies. default:lib", Defaults.scalaLibDir.path).dependsOn(target, "msil")
7575
val sourcedir = StringSetting ("-Xsourcedir", "directory", "(Requires -target:msil) Mirror source folder structure in output directory.", ".").dependsOn(target, "msil")
7676
val checkInit = BooleanSetting ("-Xcheckinit", "Wrap field accessors to throw an exception on uninitialized access.")
77+
val developer = BooleanSetting ("-Xdev", "Indicates user is a developer - issue warnings about anything which seems amiss")
7778
val noassertions = BooleanSetting ("-Xdisable-assertions", "Generate no assertions or assumptions.")
7879
val elidebelow = IntSetting ("-Xelide-below", "Calls to @elidable methods are omitted if method priority is lower than argument",
7980
elidable.MINIMUM, None, elidable.byName get _)

src/compiler/scala/tools/nsc/transform/Mixin.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
289289
for (mixinMember <- mixinClass.info.decls) {
290290
if (isConcreteAccessor(mixinMember)) {
291291
if (isOverriddenAccessor(mixinMember, clazz.info.baseClasses))
292-
debugwarn("!!! is overridden val: "+mixinMember.fullLocationString)
292+
devWarning(s"Overridden concrete accessor: ${mixinMember.fullLocationString}")
293293
else {
294294
// mixin field accessors
295295
val mixedInAccessor = cloneAndAddMixinMember(mixinClass, mixinMember)

src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1482,7 +1482,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
14821482
}
14831483
// See SI-5583. Don't know why it happens now if it didn't before.
14841484
if (specMember.info.typeParams.isEmpty && residualTargs.nonEmpty) {
1485-
log("!!! Type args to be applied, but symbol says no parameters: " + ((specMember.defString, residualTargs)))
1485+
devWarning("Type args to be applied, but symbol says no parameters: " + ((specMember.defString, residualTargs)))
14861486
localTyper.typed(sel)
14871487
}
14881488
else {

src/compiler/scala/tools/nsc/transform/UnCurry.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ abstract class UnCurry extends InfoTransform
297297
* If there's a default case, the original match is used for applyOrElse, and isDefinedAt returns `true`
298298
*/
299299
def synthPartialFunction(fun: Function) = {
300-
if (!settings.XoldPatmat.value) debugwarn("Under the new pattern matching scheme, PartialFunction should have been synthesized during typers.")
300+
if (!settings.XoldPatmat.value)
301+
devWarning("Under the new pattern matching scheme, PartialFunction should have been synthesized during typers.")
301302

302303
val targs = fun.tpe.typeArgs
303304
val (formals, restpe) = (targs.init, targs.last)
@@ -704,7 +705,7 @@ abstract class UnCurry extends InfoTransform
704705
val finalizer = tree.finalizer
705706
if (!settings.XoldPatmat.value) {
706707
if (catches exists (cd => !treeInfo.isCatchCase(cd)))
707-
debugwarn("VPM BUG! illegal try/catch " + catches)
708+
devWarning("VPM BUG - illegal try/catch " + catches)
708709
tree
709710
} else if (catches forall treeInfo.isCatchCase) {
710711
tree

src/compiler/scala/tools/nsc/typechecker/Checkable.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ trait Checkable {
130130
else if (P3) RuntimeCheckable
131131
else if (uncheckableType == NoType) {
132132
// Avoid warning (except ourselves) if we can't pinpoint the uncheckable type
133-
debugwarn("Checkability checker says 'Uncheckable', but uncheckable type cannot be found:\n" + summaryString)
133+
debuglog("Checkability checker says 'Uncheckable', but uncheckable type cannot be found:\n" + summaryString)
134134
CheckabilityError
135135
}
136136
else Uncheckable

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,10 @@ trait Contexts { self: Analyzer =>
398398
unit.error(pos, if (checking) "\n**** ERROR DURING INTERNAL CHECKING ****\n" + msg else msg)
399399

400400
@inline private def issueCommon(err: AbsTypeError)(pf: PartialFunction[AbsTypeError, Unit]) {
401-
debugwarn("issue error: " + err.errMsg)
402-
if (settings.Yissuedebug.value) (new Exception).printStackTrace()
401+
if (settings.Yissuedebug.value) {
402+
log("issue error: " + err.errMsg)
403+
(new Exception).printStackTrace()
404+
}
403405
if (pf isDefinedAt err) pf(err)
404406
else if (bufferErrors) { buffer += err }
405407
else throw new TypeError(err.errPos, err.errMsg)

src/compiler/scala/tools/nsc/typechecker/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ trait Implicits {
8282
val result = new ImplicitSearch(tree, pt, isView, implicitSearchContext, pos).bestImplicit
8383
if (saveAmbiguousDivergent && implicitSearchContext.hasErrors) {
8484
context.updateBuffer(implicitSearchContext.errBuffer.filter(err => err.kind == ErrorKinds.Ambiguous || err.kind == ErrorKinds.Divergent))
85-
debugwarn("update buffer: " + implicitSearchContext.errBuffer)
85+
debuglog("update buffer: " + implicitSearchContext.errBuffer)
8686
}
8787
printInference("[infer implicit] inferred " + result)
8888
context.undetparams = context.undetparams filterNot result.subst.from.contains

src/compiler/scala/tools/nsc/typechecker/Infer.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,8 @@ trait Infer extends Checkable {
13191319
new TreeTypeSubstituter(undetparams, targs).traverse(tree)
13201320
notifyUndetparamsInferred(undetparams, targs)
13211321
case _ =>
1322-
debugwarn("failed inferConstructorInstance for "+ tree +" : "+ tree.tpe +" under "+ undetparams +" pt = "+ pt +(if(isFullyDefined(pt)) " (fully defined)" else " (not fully defined)"))
1322+
def full = if (isFullyDefined(pt)) "(fully defined)" else "(not fully defined)"
1323+
devWarning(s"failed inferConstructorInstance for $tree: ${tree.tpe} undet=$undetparams, pt=$pt $full")
13231324
// if (settings.explaintypes.value) explainTypes(resTp.instantiateTypeParams(undetparams, tvars), pt)
13241325
ConstrInstantiationError(tree, resTp, pt)
13251326
}

src/compiler/scala/tools/nsc/typechecker/Namers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ trait Namers extends MethodSynthesis {
336336

337337
private def enterClassSymbol(tree: ClassDef, clazz: ClassSymbol): Symbol = {
338338
if (clazz.sourceFile != null && clazz.sourceFile != contextFile)
339-
debugwarn("!!! Source mismatch in " + clazz + ": " + clazz.sourceFile + " vs. " + contextFile)
339+
devWarning(s"Source file mismatch in $clazz: ${clazz.sourceFile} vs. $contextFile")
340340

341341
clazz.associatedFile = contextFile
342342
if (clazz.sourceFile != null) {

src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
271271
// we don't transform after uncurry
272272
// (that would require more sophistication when generating trees,
273273
// and the only place that emits Matches after typers is for exception handling anyway)
274-
if(phase.id >= currentRun.uncurryPhase.id) debugwarn("running translateMatch at "+ phase +" on "+ selector +" match "+ cases)
274+
if (phase.id >= currentRun.uncurryPhase.id)
275+
devWarning(s"running translateMatch past uncurry (at $phase) on $selector match $cases")
276+
275277
patmatDebug("translating "+ cases.mkString("{", "\n", "}"))
276278

277279
val start = if (Statistics.canEnable) Statistics.startTimer(patmatNanos) else null

src/compiler/scala/tools/nsc/typechecker/RefChecks.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
139139
}
140140
}
141141

142-
if (settings.lint.value) {
142+
// This has become noisy with implicit classes.
143+
if (settings.lint.value && settings.developer.value) {
143144
clazz.info.decls filter (x => x.isImplicit && x.typeParams.nonEmpty) foreach { sym =>
144145
val alts = clazz.info.decl(sym.name).alternatives
145146
if (alts.size > 1)

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ trait Typers extends Modes with Adaptations with Tags {
15471547

15481548
val preSuperVals = treeInfo.preSuperFields(templ.body)
15491549
if (preSuperVals.isEmpty && preSuperStats.nonEmpty)
1550-
debugwarn("Wanted to zip empty presuper val list with " + preSuperStats)
1550+
devWarning("Wanted to zip empty presuper val list with " + preSuperStats)
15511551
else
15521552
map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe)
15531553

src/reflect/scala/reflect/internal/Scopes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
243243
// in package objects.)
244244
val alts = lookupAll(name).toList
245245
def alts_s = alts map (s => s.defString) mkString " <and> "
246-
log(s"!!! scope lookup of $name found multiple symbols: $alts_s")
246+
devWarning(s"scope lookup of $name found multiple symbols: $alts_s")
247247
// FIXME - how is one supposed to create an overloaded symbol without
248248
// knowing the correct owner? Using the symbol owner is not correct;
249249
// say for instance this is List's scope and the symbols are its three

src/reflect/scala/reflect/internal/SymbolTable.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,16 @@ abstract class SymbolTable extends macros.Universe
5454
@deprecated("Give us a reason", "2.10.0")
5555
def abort(): Nothing = abort("unknown error")
5656

57+
@deprecated("Use devWarning if this is really a warning; otherwise use log", "2.11.0")
58+
def debugwarn(msg: => String): Unit = devWarning(msg)
59+
5760
/** Override with final implementation for inlining. */
5861
def debuglog(msg: => String): Unit = if (settings.debug.value) log(msg)
59-
def debugwarn(msg: => String): Unit = if (settings.debug.value) Console.err.println(msg)
62+
def devWarning(msg: => String): Unit = if (settings.debug.value) Console.err.println(msg)
6063
def throwableAsString(t: Throwable): String = "" + t
6164

6265
/** Prints a stack trace if -Ydebug or equivalent was given, otherwise does nothing. */
63-
def debugStack(t: Throwable): Unit = debugwarn(throwableAsString(t))
66+
def debugStack(t: Throwable): Unit = devWarning(throwableAsString(t))
6467

6568
/** Overridden when we know more about what was happening during a failure. */
6669
def supplementErrorMessage(msg: String): String = msg

src/reflect/scala/reflect/internal/Symbols.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,13 +1272,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
12721272
cnt += 1
12731273
// allow for two completions:
12741274
// one: sourceCompleter to LazyType, two: LazyType to completed type
1275-
if (cnt == 3) abort("no progress in completing " + this + ":" + tp)
1275+
if (cnt == 3) abort(s"no progress in completing $this: $tp")
12761276
}
12771277
rawInfo
12781278
}
12791279
catch {
12801280
case ex: CyclicReference =>
1281-
debugwarn("... hit cycle trying to complete " + this.fullLocationString)
1281+
devWarning("... hit cycle trying to complete " + this.fullLocationString)
12821282
throw ex
12831283
}
12841284

@@ -3165,7 +3165,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
31653165
override def companionSymbol = fail(NoSymbol)
31663166

31673167
locally {
3168-
debugwarn("creating stub symbol for " + stubWarning)
3168+
devWarning("creating stub symbol for " + stubWarning)
31693169
}
31703170
}
31713171
class StubClassSymbol(owner0: Symbol, name0: TypeName) extends ClassSymbol(owner0, owner0.pos, name0) with StubSymbol

src/reflect/scala/reflect/internal/TreeInfo.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,10 @@ abstract class TreeInfo {
147147
val plen = params.length
148148
val alen = args.length
149149
def fail() = {
150-
global.debugwarn(
151-
"Mismatch trying to zip method parameters and argument list:\n" +
152-
" params = " + params + "\n" +
153-
" args = " + args + "\n"
154-
)
150+
global.devWarning(
151+
s"""|Mismatch trying to zip method parameters and argument list:
152+
| params = $params
153+
| args = $args""".stripMargin)
155154
false
156155
}
157156

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,7 +1969,7 @@ trait Types extends api.Types { self: SymbolTable =>
19691969
case tr @ TypeRef(_, sym, args) if args.nonEmpty =>
19701970
val tparams = tr.initializedTypeParams
19711971
if (settings.debug.value && !sameLength(tparams, args))
1972-
debugwarn("Mismatched zip in computeRefs(): " + sym.info.typeParams + ", " + args)
1972+
devWarning(s"Mismatched zip in computeRefs(): ${sym.info.typeParams}, $args")
19731973

19741974
foreach2(tparams, args) { (tparam1, arg) =>
19751975
if (arg contains tparam) {
@@ -2102,7 +2102,7 @@ trait Types extends api.Types { self: SymbolTable =>
21022102
// it later turns out not to have kind *. See SI-4070. Only
21032103
// logging it for now.
21042104
if (sym.typeParams.size != args.size)
2105-
log("!!! %s.transform(%s), but tparams.isEmpty and args=".format(this, tp, args))
2105+
devWarning(s"$this.transform($tp), but tparams.isEmpty and args=$args")
21062106

21072107
asSeenFromOwner(tp).instantiateTypeParams(sym.typeParams, args)
21082108
}
@@ -3691,7 +3691,7 @@ trait Types extends api.Types { self: SymbolTable =>
36913691
tycon match {
36923692
case TypeRef(pre, sym @ (NothingClass|AnyClass), _) => copyTypeRef(tycon, pre, sym, Nil) //@M drop type args to Any/Nothing
36933693
case TypeRef(pre, sym, Nil) => copyTypeRef(tycon, pre, sym, args)
3694-
case TypeRef(pre, sym, bogons) => debugwarn(s"Dropping $bogons from $tycon in appliedType.") ; copyTypeRef(tycon, pre, sym, args)
3694+
case TypeRef(pre, sym, bogons) => devWarning(s"Dropping $bogons from $tycon in appliedType.") ; copyTypeRef(tycon, pre, sym, args)
36953695
case PolyType(tparams, restpe) => restpe.instantiateTypeParams(tparams, args)
36963696
case ExistentialType(tparams, restpe) => newExistentialType(tparams, appliedType(restpe, args))
36973697
case st: SingletonType => appliedType(st.widen, args) // @M TODO: what to do? see bug1
@@ -5036,7 +5036,7 @@ trait Types extends api.Types { self: SymbolTable =>
50365036
else {
50375037
var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true) orElse {
50385038
if (sym.isAliasType) throw missingAliasException
5039-
debugwarn(pre+"."+sym+" does no longer exist, phase = "+phase)
5039+
devWarning(s"$pre.$sym no longer exist at phase $phase")
50405040
throw new MissingTypeControl // For build manager and presentation compiler purposes
50415041
}
50425042
/** The two symbols have the same fully qualified name */
@@ -5094,7 +5094,7 @@ trait Types extends api.Types { self: SymbolTable =>
50945094
if ((pre1 eq pre) && (sym1 eq sym) && (args1 eq args)/* && sym.isExternal*/) {
50955095
tp
50965096
} else if (sym1 == NoSymbol) {
5097-
debugwarn("adapt fail: "+pre+" "+pre1+" "+sym)
5097+
devWarning(s"adapt to new run failed: pre=$pre pre1=$pre1 sym=$sym")
50985098
tp
50995099
} else {
51005100
copyTypeRef(tp, pre1, sym1, args1)
@@ -7283,7 +7283,7 @@ trait Types extends api.Types { self: SymbolTable =>
72837283

72847284
protected def typeToString(tpe: Type): String =
72857285
if (tostringRecursions >= maxTostringRecursions) {
7286-
debugwarn("Exceeded recursion depth attempting to print type.")
7286+
devWarning("Exceeded recursion depth attempting to print " + util.shortClassOfInstance(tpe))
72877287
if (settings.debug.value)
72887288
(new Throwable).printStackTrace
72897289

src/reflect/scala/reflect/internal/transform/Erasure.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ trait Erasure {
233233
// It seems there is a deeper problem here, which needs
234234
// following up to. But we will not risk regressions
235235
// in 2.10 because of it.
236-
log(s"!!! unexpected constructor erasure $tp for $clazz")
236+
devWarning(s"unexpected constructor erasure $tp for $clazz")
237237
specialScalaErasure(tp)
238238
}
239239
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
-Xlint -Xfatal-warnings
1+
-Xlint -Xfatal-warnings -Xdev

0 commit comments

Comments
 (0)