Skip to content

Ref #1589: Add error message for bad symbolic reference. #3605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import util.Stats
import java.util.WeakHashMap
import config.Config
import config.Printers.{incremental, noPrinter}
import reporting.diagnostic.Message
import reporting.diagnostic.messages.BadSymbolicReference
import reporting.trace

trait SymDenotations { this: Context =>
Expand Down Expand Up @@ -1943,7 +1945,7 @@ object SymDenotations {
/** A completer for missing references */
class StubInfo() extends LazyType {

def initializeToDefaults(denot: SymDenotation, errMsg: => String)(implicit ctx: Context) = {
def initializeToDefaults(denot: SymDenotation, errMsg: => Message)(implicit ctx: Context): Unit = {
denot.info = denot match {
case denot: ClassDenotation =>
ClassInfo(denot.owner.thisType, denot.classSymbol, Nil, EmptyScope)
Expand All @@ -1955,18 +1957,9 @@ object SymDenotations {

def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
val sym = denot.symbol
val file = sym.associatedFile
val (location, src) =
if (file != null) (s" in $file", file.toString)
else ("", "the signature")
val name = ctx.fresh.setSetting(ctx.settings.YdebugNames, true).nameString(denot.name)
def errMsg =
i"""bad symbolic reference. A signature$location
|refers to $name in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
|It may be completely missing from the current classpath, or the version on
|the classpath might be incompatible with the version used when compiling $src."""
ctx.error(errMsg)
if (ctx.debug) throw new Error()
def errMsg = BadSymbolicReference(denot)
ctx.error(errMsg, sym.pos)
if (ctx.debug) throw new scala.Error()
initializeToDefaults(denot, errMsg)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public enum ErrorMessageID {
UnapplyInvalidNumberOfArgumentsID,
StaticFieldsOnlyAllowedInObjectsID,
CyclicInheritanceID,
BadSymbolicReferenceID,
UnableToExtendSealedClassID,
SymbolHasUnparsableVersionNumberID,
SymbolChangedSemanticsInVersionID,
Expand Down
20 changes: 20 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1968,6 +1968,26 @@ object messages {
}
}

case class BadSymbolicReference(denot: SymDenotation)(implicit ctx: Context) extends Message(BadSymbolicReferenceID) {
val kind = "Reference"

private val file = denot.symbol.associatedFile
private val (location, src) =
if (file != null) (s" in $file", file.toString)
else ("", "the signature")
private val name = ctx.fresh.setSetting(ctx.settings.YdebugNames, true).nameString(denot.name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually don't create fields to only store temporary values. If you need to precompute something for msg , you can use a block:

val msg = {
  val tmp1 = ...
  val tmp2 = ...
  doSomethingWith(tmp1, tmp2)
}

If a temporary computation is shared like name, we usually make it a def. We might want to create a field if we don't want to perform a computation multiple times. In this case I guess it make sense to keep name a field since ctx.fresh... may be expensive.


val msg =
hl"""Bad symbolic reference. A signature$location
|refers to $name in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you can also store the result of owner in a temporary val within the block

|It may be completely missing from the current classpath, or the version on
|the classpath might be incompatible with the version used when compiling $src."""
val explanation =
hl"""A missing or invalid dependency was detected while loading class file '$name'.
|Check your build definition for missing or conflicting dependencies.
|Re-run with ${"-Ylog-classpath"} to obtain the information about what classpath is being applied."""
}

case class UnableToExtendSealedClass(pclazz: Symbol)(implicit ctx: Context) extends Message(UnableToExtendSealedClassID) {
val kind = "Syntax"
val msg = hl"Cannot extend ${"sealed"} $pclazz in a different source file"
Expand Down