Skip to content
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

Fix #13320: add .type to modules in messages #13374

Merged
merged 2 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
30 changes: 17 additions & 13 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,12 @@ import transform.SymUtils._
val (foundStr, expectedStr) = Formatting.typeDiff(found2, expected2)(using printCtx)
s"""|Found: $foundStr
|Required: $expectedStr""".stripMargin
+ whereSuffix + postScript
+ whereSuffix + postScript

override def explain =
override def explain =
val treeStr = inTree.map(x => s"\nTree: ${x.show}").getOrElse("")
treeStr + "\n" + super.explain


end TypeMismatch

Expand All @@ -298,16 +298,16 @@ import transform.SymUtils._
val maxDist = 3 // maximal number of differences to be considered for a hint
val missing = name.show

// The names of all non-synthetic, non-private members of `site`
// The symbols of all non-synthetic, non-private members of `site`
// that are of the same type/term kind as the missing member.
def candidates: Set[String] =
def candidates: Set[Symbol] =
for
bc <- site.widen.baseClasses.toSet
sym <- bc.info.decls.filter(sym =>
sym.isType == name.isTypeName
&& !sym.isConstructor
&& !sym.flagsUNSAFE.isOneOf(Synthetic | Private))
yield sym.name.show
yield sym

// Calculate Levenshtein distance
def distance(s1: String, s2: String): Int =
Expand All @@ -323,13 +323,13 @@ import transform.SymUtils._
else (dist(j - 1)(i) min dist(j)(i - 1) min dist(j - 1)(i - 1)) + 1
dist(s2.length)(s1.length)

// A list of possible candidate strings with their Levenstein distances
// A list of possible candidate symbols with their Levenstein distances
// to the name of the missing member
def closest: List[(Int, String)] = candidates
def closest: List[(Int, Symbol)] = candidates
.toList
.map(n => (distance(n, missing), n))
.filter((d, n) => d <= maxDist && d < missing.length && d < n.length)
.sorted // sort by distance first, alphabetically second
.map(sym => (distance(sym.name.show, missing), sym))
.filter((d, sym) => d <= maxDist && d < missing.length && d < sym.name.show.length)
.sortBy((d, sym) => (d, sym.name.show)) // sort by distance first, alphabetically second

val enumClause =
if ((name eq nme.values) || (name eq nme.valueOf)) && site.classSymbol.companionClass.isEnumClass then
Expand All @@ -348,11 +348,15 @@ import transform.SymUtils._
val finalAddendum =
if addendum.nonEmpty then prefixEnumClause(addendum)
else closest match
case (d, n) :: _ =>
case (d, sym) :: _ =>
val siteName = site match
case site: NamedType => site.name.show
case site => i"$site"
s" - did you mean $siteName.$n?$enumClause"
val showName =
// Add .type to the name if it is a module
if sym.is(ModuleClass) then s"${sym.name.show}.type"
else sym.name.show
s" - did you mean $siteName.$showName?$enumClause"
case Nil => prefixEnumClause("")

ex"$selected $name is not a member of ${site.widen}$finalAddendum"
Expand Down
12 changes: 12 additions & 0 deletions tests/neg/i13320.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- [E008] Not Found Error: tests/neg/i13320.scala:8:24 -----------------------------------------------------------------
8 | type t = Option[Foo.Boo] // error
| ^^^^^^^
| type Boo is not a member of object Foo - did you mean Foo.Boo.type?
-- [E008] Not Found Error: tests/neg/i13320.scala:4:11 -----------------------------------------------------------------
4 |var x: Foo.Booo = Foo.Booo // error // error
| ^^^^^^^^
| type Booo is not a member of object Foo - did you mean Foo.Boo.type?
-- [E008] Not Found Error: tests/neg/i13320.scala:4:22 -----------------------------------------------------------------
4 |var x: Foo.Booo = Foo.Booo // error // error
| ^^^^^^^^
| value Booo is not a member of object Foo - did you mean Foo.Boo?
8 changes: 8 additions & 0 deletions tests/neg/i13320.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
object Foo:
case object Boo

var x: Foo.Booo = Foo.Booo // error // error

object Main:
def main(args: Array[String]) =
type t = Option[Foo.Boo] // error