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

Backport "bugfix: highlight for enum type params" to LTS #20614

Merged
merged 11 commits into from
Jun 20, 2024
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
Loading