diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 04c345b9d790..063ba96410c8 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -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 @@ -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 = @@ -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 @@ -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" diff --git a/tests/neg/i13320.check b/tests/neg/i13320.check new file mode 100644 index 000000000000..1e336d8fa7bf --- /dev/null +++ b/tests/neg/i13320.check @@ -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? \ No newline at end of file diff --git a/tests/neg/i13320.scala b/tests/neg/i13320.scala new file mode 100644 index 000000000000..05edd7e17008 --- /dev/null +++ b/tests/neg/i13320.scala @@ -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