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
Mention if missing class is on the class path #10774
base: 2.13.x
Are you sure you want to change the base?
Mention if missing class is on the class path #10774
Conversation
|
I re-ran the Jenkins build, now that the community build runs that were using all the disk have finished. I wonder sometimes if we should have a dedicated worker behemoth just for PR validation, separate from the behemoths used for the community build. |
Needs refinement, as it does add verbiage for incremental compilation error.
because (as will surprise no one) the class is still there, i.e., previous artifacts are not cleaned first.
|
Hint if there is an object in scope, in a package, which has a class, and the class path finds it.
a41bb8c
to
f89150a
Compare
The clever test is tweaked to allow The output check in typer may require tweaking: it uses single output only, and compares the path strings to mean "includes". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems a helpful addition. Given
package p {
object T
class C extends T
}
and
package p {
trait T
}
I assume IntelliJ would happily navigate from extends T
to the definition of trait T
, which makes it harder to figure why compilation fails.
@@ -0,0 +1,6 @@ | |||
//> using options -d /tmp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make it a DirectTest
and use testOutput.path
?
case NoSymbol => issue(SymbolNotFoundError(tree, name, context.owner, startContext, mode.in(all = PATTERNmode, none = APPSELmode | TYPEPATmode))) | ||
case NoSymbol => | ||
def hasOutput = settings.outputDirs.getSingleOutput.isDefined || settings.outputDirs.outputs.nonEmpty | ||
val hidden = !unit.isJava && name.isTypeName && hasOutput && { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue doesn't manifest the other way around, if name.isTermName
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was too lazy to check after getting a first cut. Also, I considered it more likely to add an object as factory for an existing class.
val hidden = !unit.isJava && name.isTypeName && hasOutput && { | ||
startContext.lookupSymbol(name.toTermName, _ => true) match { | ||
case LookupSucceeded(qualifier, symbol) if symbol.owner.hasPackageFlag && symbol.sourceFile != null => | ||
symbol.owner.info.decls.lookupAll(name).toList match { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This I don't immediately understand; lookup for name
failed (we're about to issue an error), but lookupSymbol(name.toTermName).owner.info.decls.lookupAll(name)
gives a result. How is that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package is loaded from class path first, which creates symbols of existing class + its module & module class. Then compilation of source takes over the existing module symbol, which is entered into scope.
It's fishy that the package class has a set of members but not all are in scope. Previously I've read a comment about stale symbols from previous run; symbol history, like human history, is a story of wreckage and detritus. Somehow I had never fully considered the state of the environment during incremental compilation.
NormalTypeError(tree, s"not found: ${decodeWithKind(name, owner)}$help") | ||
def SymbolNotFoundError(tree: Tree, name: Name, owner: Symbol, inPattern: Boolean, hidden: Boolean) = { | ||
val help = if (inPattern && name.isTermName) s"\nIdentifiers ${if (name.charAt(0).isUpper) "that begin with uppercase" else "enclosed in backticks"} are not pattern variables but match the value in scope." else "" | ||
val path = if (hidden) s"\nA definition on the class path may be hidden by a source artifact. (Companions must be defined together.)" else "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can find a message that's a bit more explicit, hands-on. Connecting the dots between a "definition hidden by a source artifact" and "companions" is not easy simple.
Hint if there is an object in scope, in a package, which has a class, and the class path finds it.
Fixes scala/bug#12289