diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala index 30bd3c168269..fdc37000735f 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala @@ -14,16 +14,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] @@ -154,13 +148,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. + */ +class TypeApplications: + import TypeApplications.* + extension (self: Type) { // braces to avoid indenting existing code /** 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. @@ -562,7 +556,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) @@ -596,4 +590,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/TypeUtils.scala b/compiler/src/dotty/tools/dotc/core/TypeUtils.scala index 594249065d98..cb4beee434c5 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeUtils.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeUtils.scala @@ -11,7 +11,7 @@ import Names.Name import StdNames.nme import config.Feature -class TypeUtils: +class TypeUtils extends TypeApplications: /** A decorator that provides methods on types * that are needed in the transformer pipeline. */ diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 6bf19c5a27a1..ad3c0b7fbf3c 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2169,8 +2169,7 @@ object Types extends TypeUtils { /** Is the `hash` of this type the same for all possible sequences of enclosing binders? */ def hashIsStable: Boolean = true } - - // end Type + end Type // ----- Type categories ---------------------------------------------- @@ -7302,8 +7301,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/dotty/tools/dotc/transform/MixinOps.scala b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala index 3a3fa65ff64b..d0725f05ca95 100644 --- a/compiler/src/dotty/tools/dotc/transform/MixinOps.scala +++ b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala @@ -4,6 +4,7 @@ package transform import core.* import Symbols.*, Types.*, Contexts.*, DenotTransformers.*, Flags.* import NameKinds.* +import TypeApplications.* import util.Spans.* import StdNames.*, NameOps.* diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala b/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala index db3a0c6c71f2..0e02ddc57266 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala @@ -12,6 +12,7 @@ import dotty.tools.dotc.core.Symbols.* import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.printing.Formatting.* import dotty.tools.dotc.reporting.BadFormatInterpolation +import dotty.tools.dotc.core.TypeApplications.* import dotty.tools.dotc.transform.MegaPhase.MiniPhase import dotty.tools.dotc.typer.ConstFold diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 3a7f7704edff..f8dc48f28c3a 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1911,9 +1911,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.appliedTo(self)(targ) def appliedTo(targs: List[TypeRepr]): TypeRepr = - dotc.core.Types.decorateTypeApplications(self).appliedTo(targs) + Types.appliedTo(self)(targs) def substituteTypes(from: List[Symbol], to: List[TypeRepr]): TypeRepr = self.subst(from, to)