diff --git a/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala b/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala index 1c951a0c0846..8100f78e50e7 100644 --- a/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala +++ b/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala @@ -150,7 +150,7 @@ extension (tp: Type) case tp @ CapturingType(parent, refs) => val pcs = getBoxed(parent) if tp.isBoxed then refs ++ pcs else pcs - case tp: TypeRef if tp.symbol.isAbstractType => CaptureSet.empty + case tp: TypeRef if tp.symbol.isAbstractOrParamType => CaptureSet.empty case tp: TypeProxy => getBoxed(tp.superType) case tp: AndType => getBoxed(tp.tp1) ** getBoxed(tp.tp2) case tp: OrType => getBoxed(tp.tp1) ++ getBoxed(tp.tp2) diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index bfaaf78883ae..73190991a2c1 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -685,11 +685,9 @@ object SymDenotations { def isWrappedToplevelDef(using Context): Boolean = !isConstructor && owner.isPackageObject - /** Is this symbol an abstract type? */ - final def isAbstractType(using Context): Boolean = this.is(DeferredType) - /** Is this symbol an alias type? */ - final def isAliasType(using Context): Boolean = isAbstractOrAliasType && !this.is(Deferred) + final def isAliasType(using Context): Boolean = + isAbstractOrAliasType && !isAbstractOrParamType /** Is this symbol an abstract or alias type? */ final def isAbstractOrAliasType: Boolean = isType & !isClass diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 0474aff4087a..b4d2934fb04b 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -266,7 +266,7 @@ object TypeErasure { tp.paramNames, tp.paramNames map (Function.const(TypeBounds.upper(defn.ObjectType))), tp.resultType) if (defn.isPolymorphicAfterErasure(sym)) eraseParamBounds(sym.info.asInstanceOf[PolyType]) - else if (sym.isAbstractType) TypeAlias(WildcardType) + else if (sym.isAbstractOrParamType) TypeAlias(WildcardType) else if sym.is(ConstructorProxy) then NoType else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(using preErasureCtx)) else if (sym.is(Label)) erase.eraseResult(sym.info)(using preErasureCtx) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 47ba9833fc2f..ed66ecc2d498 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2700,7 +2700,7 @@ object Types extends TypeUtils { symd.maybeOwner.membersNeedAsSeenFrom(prefix) && !symd.is(NonMember) || prefix.match case prefix: Types.ThisType => - (symd.isAbstractType + (symd.isAbstractOrParamType || symd.isTerm && !symd.flagsUNSAFE.isOneOf(Module | Final | Param) && !symd.isConstructor diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala index 138cda099040..50825907be43 100644 --- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala +++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala @@ -564,7 +564,7 @@ private class ExtractAPICollector(nonLocalClassSymbols: mutable.HashSet[Symbol]) if (sym.isAliasType) api.TypeAlias.of(name, access, modifiers, as.toArray, typeParams, apiType(tpe.bounds.hi)) else { - assert(sym.isAbstractType) + assert(sym.isAbstractOrParamType) api.TypeDeclaration.of(name, access, modifiers, as.toArray, typeParams, apiType(tpe.bounds.lo), apiType(tpe.bounds.hi)) } } diff --git a/compiler/src/dotty/tools/dotc/typer/Deriving.scala b/compiler/src/dotty/tools/dotc/typer/Deriving.scala index f3be1dcff766..619dfcf4d7cb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Deriving.scala +++ b/compiler/src/dotty/tools/dotc/typer/Deriving.scala @@ -31,7 +31,7 @@ trait Deriving { /** A version of Type#underlyingClassRef that works also for higher-kinded types */ private def underlyingClassRef(tp: Type): Type = tp match { case tp: TypeRef if tp.symbol.isClass => tp - case tp: TypeRef if tp.symbol.isAbstractType => NoType + case tp: TypeRef if tp.symbol.isAbstractOrParamType => NoType case tp: TermRef => NoType case tp: TypeProxy => underlyingClassRef(tp.superType) case _ => NoType diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 5ffc81744d85..f4545db81e9a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -621,7 +621,7 @@ trait ImplicitRunInfo: private def isAnchor(sym: Symbol) = sym.isClass && !isExcluded(sym) || sym.isOpaqueAlias - || sym.is(Deferred, butNot = Param) + || sym.is(Deferred) || sym.info.isMatchAlias private def computeIScope(rootTp: Type): OfTypeImplicits = diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 1016fe467a0a..db015846391c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -274,7 +274,7 @@ class Namer { typer: Typer => analyzeRHS(body) case _ => if rhs.isEmpty || flags.is(Opaque) then flags |= Deferred - analyzeRHS(tree.rhs) + if flags.is(Param) then tree.rhs else analyzeRHS(tree.rhs) // to complete a constructor, move one context further out -- this // is the context enclosing the class. Note that the context in which a diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index d244af12dd91..192fdd404aba 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -671,7 +671,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): def canManifest(tp: Manifestable, topLevel: Boolean) = val sym = tp.typeSymbol - !sym.isAbstractType + !sym.isAbstractOrParamType && hasStableErasure(tp) && !(topLevel && defn.isBottomClassAfterErasure(sym)) diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 81fadb6baa89..f98147cf5052 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -2687,7 +2687,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def isAliasType: Boolean = self.denot.isAliasType def isAnonymousClass: Boolean = self.denot.isAnonymousClass def isAnonymousFunction: Boolean = self.denot.isAnonymousFunction - def isAbstractType: Boolean = self.denot.isAbstractType + def isAbstractType: Boolean = self.denot.isAbstractOrParamType def isClassConstructor: Boolean = self.denot.isClassConstructor def isSuperAccessor = self.name.is(dotc.core.NameKinds.SuperAccessorName) def isType: Boolean = self.isType diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index b49763c38221..1bb8405662ac 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -4025,7 +4025,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Is this symbol an anonymous function? */ def isAnonymousFunction: Boolean - /** Is this symbol an abstract type? */ + /** Is this symbol an abstract type or a type parameter? */ def isAbstractType: Boolean /** Is this the constructor of a class? */ diff --git a/tests/neg/i20079/Lib_1.scala b/tests/neg/i20079/Lib_1.scala new file mode 100644 index 000000000000..6d72042464ce --- /dev/null +++ b/tests/neg/i20079/Lib_1.scala @@ -0,0 +1,5 @@ +object Foo: + def xyz[A, CC[X] <: Iterable[X]](coll: CC[A]): Unit = () + +object Bar: + export Foo.xyz diff --git a/tests/neg/i20079/Test_2.scala b/tests/neg/i20079/Test_2.scala new file mode 100644 index 000000000000..c19d98b55bd8 --- /dev/null +++ b/tests/neg/i20079/Test_2.scala @@ -0,0 +1,6 @@ +object Test: + val ints = List(1) + Foo.xyz[Int, List](ints) + Foo.xyz[Int, scala.collection.View](ints) // error + Bar.xyz[Int, List](ints) + Bar.xyz[Int, scala.collection.View](ints) // error \ No newline at end of file