Skip to content

Commit b3f0aca

Browse files
authored
Fix isAliasType (#20195)
Symbols that had the TypeParam flag set were classified as alias types unless they also had the Deferred flag set. Maybe this did not break that much since Namer always added the Deferred for type parameters. But export forwarders use synthesized parameters which did not have Deferred set. Fixes #20079
2 parents 1fc3916 + 9d88c80 commit b3f0aca

File tree

13 files changed

+23
-14
lines changed

13 files changed

+23
-14
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ extension (tp: Type)
150150
case tp @ CapturingType(parent, refs) =>
151151
val pcs = getBoxed(parent)
152152
if tp.isBoxed then refs ++ pcs else pcs
153-
case tp: TypeRef if tp.symbol.isAbstractType => CaptureSet.empty
153+
case tp: TypeRef if tp.symbol.isAbstractOrParamType => CaptureSet.empty
154154
case tp: TypeProxy => getBoxed(tp.superType)
155155
case tp: AndType => getBoxed(tp.tp1) ** getBoxed(tp.tp2)
156156
case tp: OrType => getBoxed(tp.tp1) ++ getBoxed(tp.tp2)

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

+2-4
Original file line numberDiff line numberDiff line change
@@ -685,11 +685,9 @@ object SymDenotations {
685685
def isWrappedToplevelDef(using Context): Boolean =
686686
!isConstructor && owner.isPackageObject
687687

688-
/** Is this symbol an abstract type? */
689-
final def isAbstractType(using Context): Boolean = this.is(DeferredType)
690-
691688
/** Is this symbol an alias type? */
692-
final def isAliasType(using Context): Boolean = isAbstractOrAliasType && !this.is(Deferred)
689+
final def isAliasType(using Context): Boolean =
690+
isAbstractOrAliasType && !isAbstractOrParamType
693691

694692
/** Is this symbol an abstract or alias type? */
695693
final def isAbstractOrAliasType: Boolean = isType & !isClass

compiler/src/dotty/tools/dotc/core/TypeErasure.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ object TypeErasure {
266266
tp.paramNames, tp.paramNames map (Function.const(TypeBounds.upper(defn.ObjectType))), tp.resultType)
267267

268268
if (defn.isPolymorphicAfterErasure(sym)) eraseParamBounds(sym.info.asInstanceOf[PolyType])
269-
else if (sym.isAbstractType) TypeAlias(WildcardType)
269+
else if (sym.isAbstractOrParamType) TypeAlias(WildcardType)
270270
else if sym.is(ConstructorProxy) then NoType
271271
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(using preErasureCtx))
272272
else if (sym.is(Label)) erase.eraseResult(sym.info)(using preErasureCtx)

compiler/src/dotty/tools/dotc/core/Types.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2700,7 +2700,7 @@ object Types extends TypeUtils {
27002700
symd.maybeOwner.membersNeedAsSeenFrom(prefix) && !symd.is(NonMember)
27012701
|| prefix.match
27022702
case prefix: Types.ThisType =>
2703-
(symd.isAbstractType
2703+
(symd.isAbstractOrParamType
27042704
|| symd.isTerm
27052705
&& !symd.flagsUNSAFE.isOneOf(Module | Final | Param)
27062706
&& !symd.isConstructor

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ private class ExtractAPICollector(nonLocalClassSymbols: mutable.HashSet[Symbol])
513513
if (sym.isAliasType)
514514
api.TypeAlias.of(name, access, modifiers, as.toArray, typeParams, apiType(tpe.bounds.hi))
515515
else {
516-
assert(sym.isAbstractType)
516+
assert(sym.isAbstractOrParamType)
517517
api.TypeDeclaration.of(name, access, modifiers, as.toArray, typeParams, apiType(tpe.bounds.lo), apiType(tpe.bounds.hi))
518518
}
519519
}

compiler/src/dotty/tools/dotc/typer/Deriving.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ trait Deriving {
3131
/** A version of Type#underlyingClassRef that works also for higher-kinded types */
3232
private def underlyingClassRef(tp: Type): Type = tp match {
3333
case tp: TypeRef if tp.symbol.isClass => tp
34-
case tp: TypeRef if tp.symbol.isAbstractType => NoType
34+
case tp: TypeRef if tp.symbol.isAbstractOrParamType => NoType
3535
case tp: TermRef => NoType
3636
case tp: TypeProxy => underlyingClassRef(tp.superType)
3737
case _ => NoType

compiler/src/dotty/tools/dotc/typer/Implicits.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ trait ImplicitRunInfo:
621621
private def isAnchor(sym: Symbol) =
622622
sym.isClass && !isExcluded(sym)
623623
|| sym.isOpaqueAlias
624-
|| sym.is(Deferred, butNot = Param)
624+
|| sym.is(Deferred)
625625
|| sym.info.isMatchAlias
626626

627627
private def computeIScope(rootTp: Type): OfTypeImplicits =

compiler/src/dotty/tools/dotc/typer/Namer.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ class Namer { typer: Typer =>
274274
analyzeRHS(body)
275275
case _ =>
276276
if rhs.isEmpty || flags.is(Opaque) then flags |= Deferred
277-
analyzeRHS(tree.rhs)
277+
if flags.is(Param) then tree.rhs else analyzeRHS(tree.rhs)
278278

279279
// to complete a constructor, move one context further out -- this
280280
// is the context enclosing the class. Note that the context in which a

compiler/src/dotty/tools/dotc/typer/Synthesizer.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
672672

673673
def canManifest(tp: Manifestable, topLevel: Boolean) =
674674
val sym = tp.typeSymbol
675-
!sym.isAbstractType
675+
!sym.isAbstractOrParamType
676676
&& hasStableErasure(tp)
677677
&& !(topLevel && defn.isBottomClassAfterErasure(sym))
678678

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2687,7 +2687,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
26872687
def isAliasType: Boolean = self.denot.isAliasType
26882688
def isAnonymousClass: Boolean = self.denot.isAnonymousClass
26892689
def isAnonymousFunction: Boolean = self.denot.isAnonymousFunction
2690-
def isAbstractType: Boolean = self.denot.isAbstractType
2690+
def isAbstractType: Boolean = self.denot.isAbstractOrParamType
26912691
def isClassConstructor: Boolean = self.denot.isClassConstructor
26922692
def isSuperAccessor = self.name.is(dotc.core.NameKinds.SuperAccessorName)
26932693
def isType: Boolean = self.isType

library/src/scala/quoted/Quotes.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -4025,7 +4025,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
40254025
/** Is this symbol an anonymous function? */
40264026
def isAnonymousFunction: Boolean
40274027

4028-
/** Is this symbol an abstract type? */
4028+
/** Is this symbol an abstract type or a type parameter? */
40294029
def isAbstractType: Boolean
40304030

40314031
/** Is this the constructor of a class? */

tests/neg/i20079/Lib_1.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Foo:
2+
def xyz[A, CC[X] <: Iterable[X]](coll: CC[A]): Unit = ()
3+
4+
object Bar:
5+
export Foo.xyz

tests/neg/i20079/Test_2.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test:
2+
val ints = List(1)
3+
Foo.xyz[Int, List](ints)
4+
Foo.xyz[Int, scala.collection.View](ints) // error
5+
Bar.xyz[Int, List](ints)
6+
Bar.xyz[Int, scala.collection.View](ints) // error

0 commit comments

Comments
 (0)