From 9ddca02bbf09b4604737c90429a1c96ee9fd3dbb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 25 Aug 2020 22:04:40 +0200 Subject: [PATCH] Avoid using show or toText before an error is reported --- compiler/src/dotty/tools/dotc/ast/Trees.scala | 5 +++-- compiler/src/dotty/tools/dotc/ast/untpd.scala | 2 +- compiler/src/dotty/tools/dotc/core/Denotations.scala | 2 +- compiler/src/dotty/tools/dotc/core/StdNames.scala | 2 ++ .../dotty/tools/dotc/printing/RefinedPrinter.scala | 4 ++-- compiler/src/dotty/tools/dotc/report.scala | 4 ++-- .../src/dotty/tools/dotc/reporting/Reporter.scala | 12 +++++++----- .../src/dotty/tools/dotc/typer/Applications.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Implicits.scala | 8 +++++--- 9 files changed, 24 insertions(+), 17 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 2cbccdd32e61..0b11ce90d94a 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -393,9 +393,10 @@ object Trees { def isBackquoted: Boolean = hasAttachment(Backquoted) } - class SearchFailureIdent[-T >: Untyped] private[ast] (name: Name)(implicit @constructorOnly src: SourceFile) + class SearchFailureIdent[-T >: Untyped] private[ast] (name: Name, expl: => String)(implicit @constructorOnly src: SourceFile) extends Ident[T](name) { - override def toString: String = s"SearchFailureIdent($name)" + def explanation = expl + override def toString: String = s"SearchFailureIdent($explanation)" } /** qualifier.name, or qualifier#name, if qualifier is a type */ diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index cfed797b857c..5e87ef6aeeed 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -359,7 +359,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { // ------ Creation methods for untyped only ----------------- def Ident(name: Name)(implicit src: SourceFile): Ident = new Ident(name) - def SearchFailureIdent(name: Name)(implicit src: SourceFile): SearchFailureIdent = new SearchFailureIdent(name) + def SearchFailureIdent(name: Name, explanation: => String)(implicit src: SourceFile): SearchFailureIdent = new SearchFailureIdent(name, explanation) def Select(qualifier: Tree, name: Name)(implicit src: SourceFile): Select = new Select(qualifier, name) def SelectWithSig(qualifier: Tree, name: Name, sig: Signature)(implicit src: SourceFile): Select = new SelectWithSig(qualifier, name, sig) def This(qual: Ident)(implicit src: SourceFile): This = new This(qual) diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index fd6d3152bf60..004cd9e0ce30 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -317,7 +317,7 @@ object Denotations { def requiredMethod(pname: PreName, argTypes: List[Type])(using Context): TermSymbol = { val name = pname.toTermName - info.member(name).requiredSymbol(i"method", name, this, argTypes) { x => + info.member(name).requiredSymbol("method", name, this, argTypes) { x => x.is(Method) && { x.info.paramInfoss match { case paramInfos :: Nil => paramInfos.corresponds(argTypes)(_ =:= _) diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 4670ee104e3a..12c8d4ea817b 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -143,6 +143,8 @@ object StdNames { val QUOTE: N = "'" val TYPE_QUOTE: N = "type_'" val TRAIT_SETTER_SEPARATOR: N = str.TRAIT_SETTER_SEPARATOR + val AMBIGUOUS: N = "/* ambiguous */" + val MISSING: N = "/* missing */" // value types (and AnyRef) are all used as terms as well // as (at least) arguments to the @specialize annotation. diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 1a6fc489a06e..2f76a9cf3f48 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -352,10 +352,10 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { case id: Trees.SearchFailureIdent[?] => tree.typeOpt match { case reason: Implicits.SearchFailureType => - toText(id.name) + Str(id.explanation) ~ ("summon[" ~ toText(reason.clarify(reason.expectedType)) ~ "]").close case _ => - toText(id.name) + Str(id.explanation) } case id @ Ident(name) => val txt = tree.typeOpt match { diff --git a/compiler/src/dotty/tools/dotc/report.scala b/compiler/src/dotty/tools/dotc/report.scala index fe69b92a02a7..61e5dde75ad6 100644 --- a/compiler/src/dotty/tools/dotc/report.scala +++ b/compiler/src/dotty/tools/dotc/report.scala @@ -43,7 +43,7 @@ object report: def featureWarning(msg: Message, pos: SrcPos = NoSourcePosition)(using Context): Unit = issueWarning(new FeatureWarning(msg, pos.sourcePos)) - def featureWarning(feature: String, featureDescription: String, + def featureWarning(feature: String, featureDescription: => String, featureUseSite: Symbol, required: Boolean, pos: SrcPos)(using Context): Unit = { val req = if (required) "needs to" else "should" val fqname = s"scala.language.$feature" @@ -56,7 +56,7 @@ object report: |See the Scala docs for value $fqname for a discussion |why the feature $req be explicitly enabled.""".stripMargin - val msg = s"""$featureDescription $req be enabled + def msg = s"""$featureDescription $req be enabled |by adding the import clause 'import $fqname' |or by setting the compiler option -language:$feature.$explain""".stripMargin if (required) error(msg, pos) diff --git a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala index c7da7d9f5810..b517e6d17481 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala @@ -17,7 +17,6 @@ import util.NoSourcePosition import java.io.{ BufferedReader, PrintWriter } - object Reporter { /** Convert a SimpleReporter into a real Reporter */ def fromSimpleReporter(simple: interfaces.SimpleReporter): Reporter = @@ -142,9 +141,14 @@ abstract class Reporter extends interfaces.ReporterResult { var unreportedWarnings: Map[String, Int] = Map.empty def report(dia: Diagnostic)(using Context): Unit = - if (!isHidden(dia)) { + val isSummarized = dia match + case dia: ConditionalWarning => !dia.enablingOption.value + case _ => false + if isSummarized // avoid isHidden test for summarized warnings so that message is not forced + || !isHidden(dia) + then withMode(Mode.Printing)(doReport(dia)) - dia match { + dia match case dia: ConditionalWarning if !dia.enablingOption.value => val key = dia.enablingOption.name unreportedWarnings = @@ -155,8 +159,6 @@ abstract class Reporter extends interfaces.ReporterResult { _errorCount += 1 case dia: Info => // nothing to do here // match error if d is something else - } - } def incomplete(dia: Diagnostic)(using Context): Unit = incompleteHandler(dia, ctx) diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index c4fef408ae48..e95e6b5b274f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -617,7 +617,7 @@ trait Applications extends Compatibility { case nil => args match { case arg :: args1 => - val msg = arg match + def msg = arg match case untpd.Tuple(Nil) if applyKind == ApplyKind.InfixTuple && funType.widen.isNullaryMethod => i"can't supply unit value with infix notation because nullary $methString takes no arguments; use dotted invocation instead: (...).${methRef.name}()" diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 7a4f1dcab4c4..835665aba478 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -393,9 +393,11 @@ object Implicits: object SearchFailure { def apply(tpe: SearchFailureType)(using Context): SearchFailure = { val id = tpe match - case tpe: AmbiguousImplicits => i"/* ambiguous: ${tpe.explanation} */" - case _ => "/* missing */" - SearchFailure(untpd.SearchFailureIdent(id.toTermName).withTypeUnchecked(tpe)) + case tpe: AmbiguousImplicits => + untpd.SearchFailureIdent(nme.AMBIGUOUS, s"/* ambiguous: ${tpe.explanation} */") + case _ => + untpd.SearchFailureIdent(nme.MISSING, "/* missing */") + SearchFailure(id.withTypeUnchecked(tpe)) } }