Skip to content

Commit

Permalink
Backport "bugfix: highlight for enum type params" to LTS (#20614)
Browse files Browse the repository at this point in the history
Backports #18528 to the LTS branch.

PR submitted by the release tooling.
[skip ci]
  • Loading branch information
WojciechMazur committed Jun 20, 2024
2 parents 2ed285b + 34093be commit beb027c
Show file tree
Hide file tree
Showing 30 changed files with 528 additions and 197 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/MainGenericRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ object MainGenericRunner {
case (o @ javaOption(striped)) :: tail =>
processArgs(tail, settings.withJavaArgs(striped).withScalaArgs(o))
case (o @ scalaOption(_*)) :: tail =>
val remainingArgs = (CommandLineParser.expandArg(o) ++ tail).toList
val remainingArgs = CommandLineParser.expandArg(o) ++ tail
processArgs(remainingArgs, settings)
case (o @ colorOption(_*)) :: tail =>
processArgs(tail, settings.withScalaArgs(o))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ object Trees {
val point = span.point
if name.toTermName == nme.ERROR then
Span(point)
else if qualifier.span.start > span.start then // right associative
else if qualifier.span.start > span.point then // right associative
val realName = name.stripModuleClassSuffix.lastPart
Span(span.start, span.start + realName.length, point)
else
Expand Down
7 changes: 5 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2130,8 +2130,11 @@ class Definitions {
this.initCtx = ctx
if (!isInitialized) {
// force initialization of every symbol that is synthesized or hijacked by the compiler
val forced =
syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses() :+ JavaEnumClass
syntheticCoreClasses
syntheticCoreMethods
ScalaValueClasses()
JavaEnumClass
// end force initialization
isInitialized = true
}
addSyntheticSymbolsComments
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/inlines/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ class Inliner(val call: tpd.Tree)(using Context):

override def typedSelect(tree: untpd.Select, pt: Type)(using Context): Tree = {
val locked = ctx.typerState.ownedVars
val qual1 = typed(tree.qualifier, shallowSelectionProto(tree.name, pt, this))
val qual1 = typed(tree.qualifier, shallowSelectionProto(tree.name, pt, this, tree.nameSpan))
val resNoReduce = untpd.cpy.Select(tree)(qual1, tree.name).withType(tree.typeOpt)
val reducedProjection = reducer.reduceProjection(resNoReduce)
if reducedProjection.isType then
Expand Down
11 changes: 4 additions & 7 deletions compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,12 @@ class ExtractSemanticDB extends Phase:
}).toMap
end findGetters

private def selectSpan(tree: Select) =
private def selectSpan(tree: Select)(using Context) =
val end = tree.span.end
val limit = tree.qualifier.span.end
val start =
if limit < end then
val len = tree.name.toString.length
if tree.source.content()(end - 1) == '`' then end - len - 2 else end - len
else limit
Span(start max limit, end)
if limit < end then
tree.nameSpan
else Span(limit, end)

extension (span: Span)
private def hasLength: Boolean = span.exists && !span.isZeroExtent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class SemanticSymbolBuilder:
else
decls0
end decls
val alts = decls.filter(_.isOneOf(Method | Mutable)).toList.reverse
val alts = decls.filter(_.isOneOf(Method | Mutable)).toList.reverse.partition(!_.is(Synthetic)).toList.flatten
def find(filter: Symbol => Boolean) = alts match
case notSym :: rest if !filter(notSym) =>
val idx = rest.indexWhere(filter).ensuring(_ >= 0)
Expand Down
18 changes: 13 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/CheckUnused.scala
Original file line number Diff line number Diff line change
Expand Up @@ -561,11 +561,19 @@ object CheckUnused:
else
Nil
val warnings =
List(sortedImp, sortedLocalDefs, sortedExplicitParams, sortedImplicitParams,
sortedPrivateDefs, sortedPatVars, unsetLocalDefs, unsetPrivateDefs).flatten.sortBy { s =>
val pos = s.pos.sourcePos
(pos.line, pos.column)
}
val unsorted =
sortedImp :::
sortedLocalDefs :::
sortedExplicitParams :::
sortedImplicitParams :::
sortedPrivateDefs :::
sortedPatVars :::
unsetLocalDefs :::
unsetPrivateDefs
unsorted.sortBy { s =>
val pos = s.pos.sourcePos
(pos.line, pos.column)
}
UnusedResult(warnings.toSet)
end getUnused
//============================ HELPERS ====================================
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ trait Applications extends Compatibility {
val resultType =
if !originalResultType.isRef(defn.ObjectClass) then originalResultType
else AvoidWildcardsMap()(proto.resultType.deepenProtoTrans) match
case SelectionProto(nme.asInstanceOf_, PolyProto(_, resTp), _, _) => resTp
case SelectionProto(nme.asInstanceOf_, PolyProto(_, resTp), _, _, _) => resTp
case resTp if isFullyDefined(resTp, ForceDegree.all) => resTp
case _ => defn.ObjectType
val methType = MethodType(proto.typedArgs().map(_.tpe.widen), resultType)
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Types._, ProtoTypes._, Contexts._, Decorators._, Denotations._, Symbols._
import Implicits._, Flags._, Constants.Constant
import Trees._
import NameOps._
import util.Spans.NoSpan
import util.SrcPos
import config.Feature
import reporting._
Expand Down Expand Up @@ -266,7 +267,7 @@ object ErrorReporting {
else
val add = suggestImports(
ViewProto(qualType.widen,
SelectionProto(tree.name, WildcardType, NoViewsAllowed, privateOK = false)))
SelectionProto(tree.name, WildcardType, NoViewsAllowed, privateOK = false, NoSpan)))
if add.isEmpty then ""
else ", but could be made available as an extension method." ++ add
end selectErrorAddendum
Expand Down
12 changes: 6 additions & 6 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ object Implicits:
* method with the selecting name? False otherwise.
*/
def hasExtMethod(tp: Type, expected: Type)(using Context) = expected match
case selProto @ SelectionProto(selName: TermName, _, _, _) =>
case selProto @ SelectionProto(selName: TermName, _, _, _, _) =>
tp.memberBasedOnFlags(selName, required = ExtensionMethod).exists
case _ =>
false
Expand Down Expand Up @@ -437,7 +437,7 @@ object Implicits:
def clarify(tp: Type)(using Context): Type = tp

final protected def qualify(using Context): String = expectedType match {
case SelectionProto(name, mproto, _, _) if !argument.isEmpty =>
case SelectionProto(name, mproto, _, _, _) if !argument.isEmpty =>
i"provide an extension method `$name` on ${argument.tpe}"
case NoType =>
if (argument.isEmpty) i"match expected type"
Expand Down Expand Up @@ -842,8 +842,8 @@ trait Implicits:
NoMatchingImplicitsFailure
else {
def adjust(to: Type) = to.stripTypeVar.widenExpr match {
case SelectionProto(name, memberProto, compat, true) =>
SelectionProto(name, memberProto, compat, privateOK = false)
case SelectionProto(name, memberProto, compat, true, nameSpan) =>
SelectionProto(name, memberProto, compat, privateOK = false, nameSpan)
case tp => tp
}

Expand Down Expand Up @@ -1137,10 +1137,10 @@ trait Implicits:
pt, locked)
}
pt match
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) =>
case selProto @ SelectionProto(selName: TermName, mbrType, _, _, nameSpan) =>

def tryExtension(using Context) =
extMethodApply(untpd.Select(untpdGenerated, selName), argument, mbrType)
extMethodApply(untpd.Select(untpdGenerated, selName).withSpan(nameSpan), argument, mbrType)

def tryConversionForSelection(using Context) =
val converted = tryConversion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ trait ImportSuggestions:
// don't suggest things that are imported by default

def extensionImports = pt match
case ViewProto(argType, SelectionProto(name: TermName, _, _, _)) =>
case ViewProto(argType, SelectionProto(name: TermName, _, _, _, _)) =>
roots.flatMap(extensionMethod(_, name, argType))
case _ =>
Nil
Expand Down
39 changes: 20 additions & 19 deletions compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import util.SourceFile
import TypeComparer.necessarySubType

import scala.annotation.internal.sharable
import dotty.tools.dotc.util.Spans.{NoSpan, Span}

object ProtoTypes {

Expand Down Expand Up @@ -165,7 +166,7 @@ object ProtoTypes {
*
* [ ].name: proto
*/
abstract case class SelectionProto(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean)
abstract case class SelectionProto(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean, nameSpan: Span)
extends CachedProxyType with ProtoType with ValueTypeOrProto {

/** Is the set of members of this type unknown, in the sense that we
Expand Down Expand Up @@ -230,24 +231,24 @@ object ProtoTypes {

def underlying(using Context): Type = WildcardType

def derivedSelectionProto(name: Name, memberProto: Type, compat: Compatibility)(using Context): SelectionProto =
if ((name eq this.name) && (memberProto eq this.memberProto) && (compat eq this.compat)) this
else SelectionProto(name, memberProto, compat, privateOK)
def derivedSelectionProto(name: Name, memberProto: Type, compat: Compatibility, nameSpan: Span)(using Context): SelectionProto =
if ((name eq this.name) && (memberProto eq this.memberProto) && (compat eq this.compat) && (nameSpan == this.nameSpan)) this
else SelectionProto(name, memberProto, compat, privateOK, nameSpan)

override def isErroneous(using Context): Boolean =
memberProto.isErroneous

override def unusableForInference(using Context): Boolean =
memberProto.unusableForInference

def map(tm: TypeMap)(using Context): SelectionProto = derivedSelectionProto(name, tm(memberProto), compat)
def map(tm: TypeMap)(using Context): SelectionProto = derivedSelectionProto(name, tm(memberProto), compat, nameSpan)
def fold[T](x: T, ta: TypeAccumulator[T])(using Context): T = ta(x, memberProto)

override def deepenProto(using Context): SelectionProto =
derivedSelectionProto(name, memberProto.deepenProto, compat)
derivedSelectionProto(name, memberProto.deepenProto, compat, nameSpan)

override def deepenProtoTrans(using Context): SelectionProto =
derivedSelectionProto(name, memberProto.deepenProtoTrans, compat)
derivedSelectionProto(name, memberProto.deepenProtoTrans, compat, nameSpan)

override def computeHash(bs: Hashable.Binders): Int = {
val delta = (if (compat eq NoViewsAllowed) 1 else 0) | (if (privateOK) 2 else 0)
Expand All @@ -268,24 +269,24 @@ object ProtoTypes {
}
}

class CachedSelectionProto(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean)
extends SelectionProto(name, memberProto, compat, privateOK)
class CachedSelectionProto(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean, nameSpan: Span)
extends SelectionProto(name, memberProto, compat, privateOK, nameSpan)

object SelectionProto {
def apply(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean)(using Context): SelectionProto = {
val selproto = new CachedSelectionProto(name, memberProto, compat, privateOK)
def apply(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean, nameSpan: Span)(using Context): SelectionProto = {
val selproto = new CachedSelectionProto(name, memberProto, compat, privateOK, nameSpan)
if (compat eq NoViewsAllowed) unique(selproto) else selproto
}
}

/** Create a selection proto-type, but only one level deep;
* treat constructors specially
*/
def shallowSelectionProto(name: Name, tp: Type, typer: Typer)(using Context): TermType =
def shallowSelectionProto(name: Name, tp: Type, typer: Typer, nameSpan: Span)(using Context): TermType =
if (name.isConstructorName) WildcardType
else tp match
case tp: UnapplyFunProto => new UnapplySelectionProto(name)
case tp => SelectionProto(name, IgnoredProto(tp), typer, privateOK = true)
case tp: UnapplyFunProto => new UnapplySelectionProto(name, nameSpan)
case tp => SelectionProto(name, IgnoredProto(tp), typer, privateOK = true, nameSpan)

/** A prototype for expressions [] that are in some unspecified selection operation
*
Expand All @@ -295,12 +296,12 @@ object ProtoTypes {
* operation is further selection. In this case, the expression need not be a value.
* @see checkValue
*/
@sharable object AnySelectionProto extends SelectionProto(nme.WILDCARD, WildcardType, NoViewsAllowed, true)
@sharable object AnySelectionProto extends SelectionProto(nme.WILDCARD, WildcardType, NoViewsAllowed, true, NoSpan)

@sharable object SingletonTypeProto extends SelectionProto(nme.WILDCARD, WildcardType, NoViewsAllowed, true)
@sharable object SingletonTypeProto extends SelectionProto(nme.WILDCARD, WildcardType, NoViewsAllowed, true, NoSpan)

/** A prototype for selections in pattern constructors */
class UnapplySelectionProto(name: Name) extends SelectionProto(name, WildcardType, NoViewsAllowed, true)
class UnapplySelectionProto(name: Name, nameSpan: Span) extends SelectionProto(name, WildcardType, NoViewsAllowed, true, nameSpan)

trait ApplyingProto extends ProtoType // common trait of ViewProto and FunProto
trait FunOrPolyProto extends ProtoType: // common trait of PolyProto and FunProto
Expand Down Expand Up @@ -599,7 +600,7 @@ object ProtoTypes {
def isMatchedBy(tp: Type, keepConstraint: Boolean)(using Context): Boolean =
ctx.typer.isApplicableType(tp, argType :: Nil, resultType) || {
resType match {
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) =>
case selProto @ SelectionProto(selName: TermName, mbrType, _, _, _) =>
ctx.typer.hasExtensionMethodNamed(tp, selName, argType, mbrType)
//.reporting(i"has ext $tp $name $argType $mbrType: $result")
case _ =>
Expand Down Expand Up @@ -921,7 +922,7 @@ object ProtoTypes {
}
approxOr
case tp: SelectionProto =>
tp.derivedSelectionProto(tp.name, wildApprox(tp.memberProto, theMap, seen, internal), NoViewsAllowed)
tp.derivedSelectionProto(tp.name, wildApprox(tp.memberProto, theMap, seen, internal), NoViewsAllowed, tp.nameSpan)
case tp: ViewProto =>
tp.derivedViewProto(
wildApprox(tp.argType, theMap, seen, internal),
Expand Down
10 changes: 5 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
record("typedSelect")

def typeSelectOnTerm(using Context): Tree =
val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this))
val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this, tree.nameSpan))
typedSelect(tree, pt, qual).withSpan(tree.span).computeNullable()

def javaSelectOnType(qual: Tree)(using Context) =
Expand Down Expand Up @@ -782,7 +782,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
tryAlternatively(typeSelectOnTerm)(fallBack)

if (tree.qualifier.isType) {
val qual1 = typedType(tree.qualifier, shallowSelectionProto(tree.name, pt, this))
val qual1 = typedType(tree.qualifier, shallowSelectionProto(tree.name, pt, this, tree.nameSpan))
assignType(cpy.Select(tree)(qual1, tree.name), qual1)
}
else if (ctx.isJava && tree.name.isTypeName)
Expand Down Expand Up @@ -3442,7 +3442,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
then
Some(adapt(tree, pt, locked))
else
val selProto = SelectionProto(name, pt, NoViewsAllowed, privateOK = false)
val selProto = SelectionProto(name, pt, NoViewsAllowed, privateOK = false, tree.nameSpan)
if selProto.isMatchedBy(qual.tpe) || tree.hasAttachment(InsertedImplicitOnQualifier) then
None
else
Expand All @@ -3467,7 +3467,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
(tree: untpd.Select, pt: Type, mbrProto: Type, qual: Tree, locked: TypeVars, compat: Compatibility, inSelect: Boolean)
(using Context): Tree =

def selectionProto = SelectionProto(tree.name, mbrProto, compat, privateOK = inSelect)
def selectionProto = SelectionProto(tree.name, mbrProto, compat, privateOK = inSelect, tree.nameSpan)

def tryExtension(using Context): Tree =
val altImports = new mutable.ListBuffer[TermRef]()
Expand Down Expand Up @@ -3897,7 +3897,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
* function prototype `(...)R`. Otherwise `pt`.
*/
def ptWithoutRedundantApply: Type = pt.revealIgnored match
case SelectionProto(nme.apply, mpt, _, _) =>
case SelectionProto(nme.apply, mpt, _, _, _) =>
mpt.revealIgnored match
case fpt: FunProto => fpt
case _ => pt
Expand Down
Loading

0 comments on commit beb027c

Please sign in to comment.