diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala index 136384413810..c08391345845 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala @@ -13,16 +13,10 @@ import StdNames.nme import Flags.{Module, Provisional} import dotty.tools.dotc.config.Config -object TypeApplications { +object TypeApplications: type TypeParamInfo = ParamInfo.Of[TypeName] - /** Assert type is not a TypeBounds instance and return it unchanged */ - def noBounds(tp: Type): Type = tp match { - case tp: TypeBounds => throw new AssertionError("no TypeBounds allowed") - case _ => tp - } - /** Extractor for * * [X1: B1, ..., Xn: Bn] -> C[X1, ..., Xn] @@ -153,13 +147,13 @@ object TypeApplications { mapOver(t) } } -} - -import TypeApplications.* -/** A decorator that provides methods for modeling type application */ -class TypeApplications(val self: Type) extends AnyVal { +/** Extensions that model type application. + */ +trait TypeApplications: + import TypeApplications.* + extension (self: Type) { // braces to avoid indent /** The type parameters of this type are: * For a ClassInfo type, the type parameters of its class. * For a typeref referring to a class, the type parameters of the class. @@ -554,7 +548,7 @@ class TypeApplications(val self: Type) extends AnyVal { case _ => self.dropDependentRefinement.dealias.argInfos /** Argument types where existential types in arguments are disallowed */ - def argTypes(using Context): List[Type] = argInfos mapConserve noBounds + def argTypes(using Context): List[Type] = argInfos.mapConserve(_.noBounds) /** Argument types where existential types in arguments are approximated by their lower bound */ def argTypesLo(using Context): List[Type] = argInfos.mapConserve(_.loBound) @@ -588,4 +582,9 @@ class TypeApplications(val self: Type) extends AnyVal { .orElse(self.baseType(defn.ArrayClass)) .argInfos.headOption.getOrElse(NoType) } -} + + /** Assert type is not a TypeBounds instance and return it unchanged */ + def noBounds: self.type = + assert(!self.isInstanceOf[TypeBounds], "no TypeBounds allowed") + self + } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index e18785e3aace..3e907bc4787a 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2132,6 +2132,9 @@ object Types extends TypeUtils { /** Is the `hash` of this type the same for all possible sequences of enclosing binders? */ def hashIsStable: Boolean = true } + object Type: + // Extensions that model type application. + given TypeApplications() // end Type @@ -7160,8 +7163,6 @@ object Types extends TypeUtils { // ----- Helpers and Decorator implicits -------------------------------------- - implicit def decorateTypeApplications(tpe: Type): TypeApplications = new TypeApplications(tpe) - extension (tps1: List[Type]) { @tailrec def hashIsStable: Boolean = tps1.isEmpty || tps1.head.hashIsStable && tps1.tail.hashIsStable diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 852d7ee8b20f..7e025e207866 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1897,9 +1897,9 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler dotc.core.Symbols.defn.isTupleNType(self) def select(sym: Symbol): TypeRepr = self.select(sym) def appliedTo(targ: TypeRepr): TypeRepr = - dotc.core.Types.decorateTypeApplications(self).appliedTo(targ) + Types.Type.given_TypeApplications.appliedTo(self)(targ) def appliedTo(targs: List[TypeRepr]): TypeRepr = - dotc.core.Types.decorateTypeApplications(self).appliedTo(targs) + Types.Type.given_TypeApplications.appliedTo(self)(targs) def substituteTypes(from: List[Symbol], to: List[TypeRepr]): TypeRepr = self.subst(from, to)