diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index a75716cd2ab2..a5810f04780e 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -206,7 +206,7 @@ class JSCodeGen()(using genCtx: Context) { withScopedVars( currentClassSym := sym ) { - val tree = if (isJSType(sym)) { + val tree = if (sym.isJSType) { if (!sym.is(Trait) && sym.isNonNativeJSClass) genNonNativeJSClass(td) else @@ -702,7 +702,7 @@ class JSCodeGen()(using genCtx: Context) { Nil } else { val moduleClass = module.moduleClass - if (!isJSType(moduleClass)) + if (!moduleClass.isJSType) genStaticForwardersFromModuleClass(existingMembers, moduleClass) else Nil @@ -1678,7 +1678,7 @@ class JSCodeGen()(using genCtx: Context) { } fun match { - case _ if isJSDefaultParam(sym) => + case _ if sym.isJSDefaultParam => js.Transient(UndefinedParam)(toIRType(sym.info.finalResultType)) case Select(Super(_, _), _) => @@ -1771,7 +1771,7 @@ class JSCodeGen()(using genCtx: Context) { } else /*if (translatedAnonFunctions contains tpe.typeSymbol) { val functionMaker = translatedAnonFunctions(tpe.typeSymbol) functionMaker(args map genExpr) - } else*/ if (isJSType(clsSym)) { + } else*/ if (clsSym.isJSType) { genNewJSClass(tree) } else { toTypeRef(tpe) match { @@ -2406,7 +2406,7 @@ class JSCodeGen()(using genCtx: Context) { * and `-0.0`, see Javadoc (scala-dev#329, scala-js#2799). */ val mustUseAnyComparator: Boolean = { - isJSType(lsym) || isJSType(rsym) || { + lsym.isJSType || rsym.isJSType || { val p = ctx.platform p.isMaybeBoxed(lsym) && p.isMaybeBoxed(rsym) && { val areSameFinals = lsym.is(Final) && rsym.is(Final) && (ltpe =:= rtpe) @@ -2603,7 +2603,7 @@ class JSCodeGen()(using genCtx: Context) { if (isMethodStaticInIR(sym)) { genApplyStatic(sym, genActualArgs(sym, args)) - } else if (isJSType(sym.owner)) { + } else if (sym.owner.isJSType) { if (!sym.owner.isNonNativeJSClass || sym.isJSExposed) genApplyJSMethodGeneric(sym, genExprOrGlobalScope(receiver), genActualJSArgs(sym, args), isStat)(tree.sourcePos) else @@ -2689,13 +2689,13 @@ class JSCodeGen()(using genCtx: Context) { } } - if (isJSGetter(sym)) { + if (sym.isJSGetter) { assert(noSpread && argc == 0) genSelectGet(jsFunName) - } else if (isJSSetter(sym)) { + } else if (sym.isJSSetter) { assert(noSpread && argc == 1) genSelectSet(jsFunName, requireNotSpread(args.head)) - } else if (isJSBracketAccess(sym)) { + } else if (sym.isJSBracketAccess) { assert(noSpread && (argc == 1 || argc == 2), s"@JSBracketAccess methods should have 1 or 2 non-varargs arguments") (args: @unchecked) match { @@ -2704,7 +2704,7 @@ class JSCodeGen()(using genCtx: Context) { case List(keyArg, valueArg) => genSelectSet(requireNotSpread(keyArg), requireNotSpread(valueArg)) } - } else if (isJSBracketCall(sym)) { + } else if (sym.isJSBracketCall) { val (methodName, actualArgs) = extractFirstArg(args) genCall(methodName, actualArgs) } else { @@ -3187,7 +3187,7 @@ class JSCodeGen()(using genCtx: Context) { val sym = to.typeSymbol - if (sym == defn.ObjectClass || isJSType(sym)) { + if (sym == defn.ObjectClass || sym.isJSType) { /* asInstanceOf[Object] always succeeds, and * asInstanceOf to a raw JS type is completely erased. */ @@ -3217,7 +3217,7 @@ class JSCodeGen()(using genCtx: Context) { if (sym == defn.ObjectClass) { js.BinaryOp(js.BinaryOp.!==, value, js.Null()) - } else if (isJSType(sym)) { + } else if (sym.isJSType) { if (sym.is(Trait)) { report.error( s"isInstanceOf[${sym.fullName}] not supported because it is a JS trait", @@ -3347,7 +3347,7 @@ class JSCodeGen()(using genCtx: Context) { arg match { case Literal(value) if value.tag == Constants.ClazzTag => val classSym = value.typeValue.typeSymbol - if (isJSType(classSym) && !classSym.is(Trait) && !classSym.is(ModuleClass)) + if (classSym.isJSType && !classSym.is(Trait) && !classSym.is(ModuleClass)) classSym else fail() @@ -3999,7 +3999,7 @@ class JSCodeGen()(using genCtx: Context) { } else { val cls = encodeClassName(sym) val tree = - if (isJSType(sym)) js.LoadJSModule(cls) + if (sym.isJSType) js.LoadJSModule(cls) else js.LoadModule(cls) MaybeGlobalScope.NotGlobalScope(tree) } diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 5640492efaa9..256255060e8b 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -814,7 +814,7 @@ object desugar { } flatTree(cdef1 :: companions ::: implicitWrappers ::: enumScaffolding) - }.reporting(i"desugared: $result", Printers.desugar) + }.showing(i"desugared: $result", Printers.desugar) /** Expand * @@ -895,7 +895,7 @@ object desugar { mdef.tparams.head.srcPos) defDef( cpy.DefDef(mdef)( - name = normalizeName(mdef, ext).toExtensionName, + name = normalizeName(mdef, ext).asTermName, tparams = ext.tparams ++ mdef.tparams, vparamss = mdef.vparamss match case vparams1 :: vparamss1 if mdef.name.isRightAssocOperatorName => @@ -928,10 +928,10 @@ object desugar { /** The normalized name of `mdef`. This means * 1. Check that the name does not redefine a Scala core class. - * If it does redefine, issue an error and return a mangled name instead of the original one. - * 2. Check that the name does not start with `extension_` unless the - * method is an extension method. - * 3. If the name is missing (this can be the case for instance definitions), invent one instead. + * If it does redefine, issue an error and return a mangled name instead + * of the original one. + * 2. If the name is missing (this can be the case for instance definitions), + * invent one instead. */ def normalizeName(mdef: MemberDef, impl: Tree)(using Context): Name = { var name = mdef.name @@ -942,31 +942,16 @@ object desugar { report.error(IllegalRedefinitionOfStandardKind(kind, name), errPos) name = name.errorName } - mdef match { - case vdef: ValDef if name.isExtension && isSetterNeeded(vdef) => - report.error(em"illegal setter name: `extension_=`", errPos) - case memDef if name.isExtensionName && !mdef.mods.is(ExtensionMethod) => - report.error(em"illegal name: $name may not start with `extension_`", errPos) - case _ => - } name } - /** Invent a name for an anonympus given or extension of type or template `impl`. */ + /** Invent a name for an anonympus given of type or template `impl`. */ def inventGivenOrExtensionName(impl: Tree)(using Context): SimpleName = val str = impl match case impl: Template => if impl.parents.isEmpty then - impl.body.find { - case dd: DefDef if dd.mods.is(ExtensionMethod) => true - case _ => false - } - match - case Some(DefDef(name, _, (vparam :: _) :: _, _, _)) => - s"extension_${name}_${inventTypeName(vparam.tpt)}" - case _ => - report.error(AnonymousInstanceCannotBeEmpty(impl), impl.srcPos) - nme.ERROR.toString + report.error(AnonymousInstanceCannotBeEmpty(impl), impl.srcPos) + nme.ERROR.toString else impl.parents.map(inventTypeName(_)).mkString("given_", "_", "") case impl: Tree => diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 9470ae045083..186329292c10 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -343,10 +343,7 @@ object Trees { if (rawMods.is(Synthetic) || span.isSynthetic || name.toTermName == nme.ERROR) Span(point) else { val realName = name.stripModuleClassSuffix.lastPart - var length = realName.length - if (rawMods.is(ExtensionMethod) || symbol.is(ExtensionMethod)) && name.isExtensionName then - length -= "extension_".length - Span(point, point + length, point) + Span(point, point + realName.length, point) } } else span diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 3fd1210f61ad..1cba0631bcc9 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -24,15 +24,20 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { } /** A typed subtree of an untyped tree needs to be wrapped in a TypedSplice - * @param owner The current owner at the time the tree was defined + * @param owner The current owner at the time the tree was defined + * @param isExtensionReceiver The splice was created from the receiver `e` in an extension + * method call `e.f(...)` */ - abstract case class TypedSplice(splice: tpd.Tree)(val owner: Symbol)(implicit @constructorOnly src: SourceFile) extends ProxyTree { + abstract case class TypedSplice(splice: tpd.Tree)(val owner: Symbol, val isExtensionReceiver: Boolean)(implicit @constructorOnly src: SourceFile) extends ProxyTree { def forwardTo: tpd.Tree = splice + override def toString = + def ext = if isExtensionReceiver then ", isExtensionReceiver = true" else "" + s"TypedSplice($splice$ext)" } object TypedSplice { - def apply(tree: tpd.Tree)(using Context): TypedSplice = - new TypedSplice(tree)(ctx.owner) {} + def apply(tree: tpd.Tree, isExtensionReceiver: Boolean = false)(using Context): TypedSplice = + new TypedSplice(tree)(ctx.owner, isExtensionReceiver) {} } /** mods object name impl */ diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index 4aa72d8bc712..5d73475f4e0b 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -159,7 +159,7 @@ trait ConstraintHandling { val bound = adjust(rawBound) bound.exists && addOneBound(param, bound, isUpper) && others.forall(addOneBound(_, bound, isUpper)) - .reporting(i"added $description = $result$location", constr) + .showing(i"added $description = $result$location", constr) end addBoundTransitively protected def addLess(p1: TypeParamRef, p2: TypeParamRef)(using Context): Boolean = { diff --git a/compiler/src/dotty/tools/dotc/core/Decorators.scala b/compiler/src/dotty/tools/dotc/core/Decorators.scala index 7e6fb0c7f252..585ebff66aaf 100644 --- a/compiler/src/dotty/tools/dotc/core/Decorators.scala +++ b/compiler/src/dotty/tools/dotc/core/Decorators.scala @@ -232,7 +232,7 @@ object Decorators { } extension [T](x: T) - def reporting( + def showing( op: WrappedResult[T] ?=> String, printer: config.Printers.Printer = config.Printers.default): T = { printer.println(op(using WrappedResult(x))) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 200b08b5d65e..70d7c6106ea0 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -229,7 +229,6 @@ class Definitions { @tu lazy val Compiletime_requireConst: Symbol = CompiletimePackageObject.requiredMethod("requireConst") @tu lazy val Compiletime_constValue : Symbol = CompiletimePackageObject.requiredMethod("constValue") @tu lazy val Compiletime_constValueOpt: Symbol = CompiletimePackageObject.requiredMethod("constValueOpt") - @tu lazy val Compiletime_code : Symbol = CompiletimePackageObject.requiredMethod("extension_code") @tu lazy val Compiletime_summonFrom : Symbol = CompiletimePackageObject.requiredMethod("summonFrom") @tu lazy val CompiletimeTestingPackageObject: Symbol = requiredModule("scala.compiletime.testing.package") @tu lazy val CompiletimeTesting_typeChecks: Symbol = CompiletimeTestingPackageObject.requiredMethod("typeChecks") diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 970807d30000..adf8a7681149 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -152,6 +152,10 @@ object Flags { def flagsString: String = x.flagStrings("").mkString(" ") } + // Temporary while extension names are in flux + def or(x1: FlagSet, x2: FlagSet) = x1 | x2 + def and(x1: FlagSet, x2: FlagSet) = x1 & x2 + def termFlagSet(x: Long) = FlagSet(TERMS | x) private inline val TYPESHIFT = 2 diff --git a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala index 73ff0a846295..7d84b9892057 100644 --- a/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/GadtConstraint.scala @@ -125,7 +125,7 @@ final class ProperGadtConstraint private( // The replaced symbols are picked up here. addToConstraint(poly1, tvars) - .reporting(i"added to constraint: [$poly1] $params%, %\n$debugBoundsDescription", gadts) + .showing(i"added to constraint: [$poly1] $params%, %\n$debugBoundsDescription", gadts) } override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(using Context): Boolean = { @@ -158,7 +158,7 @@ final class ProperGadtConstraint private( case bound => addBoundTransitively(symTvar.origin, bound, isUpper) } - ).reporting({ + ).showing({ val descr = if (isUpper) "upper" else "lower" val op = if (isUpper) "<:" else ">:" i"adding $descr bound $sym $op $bound = $result" @@ -187,7 +187,7 @@ final class ProperGadtConstraint private( case tb => tb } retrieveBounds - //.reporting(i"gadt bounds $sym: $result", gadts) + //.showing(i"gadt bounds $sym: $result", gadts) //.ensuring(containsNoInternalTypes(_)) } diff --git a/compiler/src/dotty/tools/dotc/core/Mode.scala b/compiler/src/dotty/tools/dotc/core/Mode.scala index 219099adcfb1..796806fe1da7 100644 --- a/compiler/src/dotty/tools/dotc/core/Mode.scala +++ b/compiler/src/dotty/tools/dotc/core/Mode.scala @@ -112,4 +112,7 @@ object Mode { /** Are we in a quote in a pattern? */ val QuotedPattern: Mode = newMode(25, "QuotedPattern") + + /** Are we typechecking the rhs of an extension method? */ + val InExtensionMethod: Mode = newMode(26, "InExtensionMethod") } diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 15afb7a69576..8e5fc94f549a 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -145,16 +145,10 @@ object NameOps { case name: SimpleName => name.startsWith("extension_") case _ => false + // TODO: Drop next 3 methods once extension names have stabilized /** Add an `extension_` in front of this name */ def toExtensionName(using Context): SimpleName = "extension_".concat(name) - /** Drop `extension_` in front of this name, if it has this prefix */ - def dropExtension = name match - case name: SimpleName if name.startsWith("extension_") => - name.drop("extension_".length) - case _ => - name - /** The expanded name. * This is the fully qualified name of `base` with `ExpandPrefixName` as separator, * followed by `kind` and the name. @@ -218,7 +212,7 @@ object NameOps { /** Same as `funArity`, except that it returns -1 if the prefix * is not one of "", "Context", "Erased", "ErasedContext" */ - private def checkedFunArity(suffixStart: Int) = + private def checkedFunArity(suffixStart: Int): Int = if suffixStart == 0 || isPreceded("Context", suffixStart) || isPreceded("Erased", suffixStart) diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index 84f44010e3a2..08702827a9dd 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -506,7 +506,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, merge(this.boundsMap, that.boundsMap, mergeEntries), merge(this.lowerMap, that.lowerMap, mergeParams), merge(this.upperMap, that.upperMap, mergeParams)) - }.reporting(i"constraint merge $this with $other = $result", constr) + }.showing(i"constraint merge $this with $other = $result", constr) def rename(tl: TypeLambda)(using Context): OrderingConstraint = { assert(contains(tl)) diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 5910be6e2f51..8f29eedd2990 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -325,6 +325,7 @@ object SymDenotations { case _ => Nil + ensureCompleted() if rawParamss.isEmpty then recurWithoutParamss(info) else recurWithParamss(info, rawParamss) end paramSymss @@ -339,6 +340,7 @@ object SymDenotations { case (fst :: Nil) :: _ => fst case _ => NoSymbol assert(isAllOf(ExtensionMethod)) + ensureCompleted() leadParam(rawParamss) /** The denotation is completed: info is not a lazy type and attributes have defined values */ diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 55b35731543d..1498eec4bbbd 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -370,7 +370,7 @@ object TypeOps: } if needsRefinement then RefinedType(parent, decl.name, decl.info) - .reporting(i"add ref $parent $decl --> " + result, typr) + .showing(i"add ref $parent $decl --> " + result, typr) else parent } diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index e214677a7b98..cba7cc3c2343 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -752,11 +752,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { private def useSymbol(tree: untpd.Tree) = tree.hasType && tree.symbol.exists && ctx.settings.YprintSyms.value - protected def nameIdText[T >: Untyped](tree: NameTree[T], dropExtension: Boolean = false): Text = + protected def nameIdText[T >: Untyped](tree: NameTree[T]): Text = if (tree.hasType && tree.symbol.exists) { - var str = nameString(tree.symbol) - if tree.symbol.is(ExtensionMethod) && dropExtension && str.startsWith("extension_") then - str = str.drop("extension_".length) + val str = nameString(tree.symbol) tree match { case tree: RefTree => withPos(str, tree.sourcePos) case tree: MemberDef => withPos(str, tree.sourcePos.withSpan(tree.nameSpan)) @@ -808,7 +806,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { case vparams1 :: rest => (vparams1, rest) (keywordStr("extension") ~~ paramsText(leadingParams) - ~~ (defKeyword ~~ valDefText(nameIdText(tree, dropExtension = true))).close, + ~~ (defKeyword ~~ valDefText(nameIdText(tree))).close, otherParamss) else (defKeyword ~~ valDefText(nameIdText(tree)), tree.vparamss) diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala index 6d820094c216..f47fad82e9b9 100644 --- a/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala @@ -29,9 +29,9 @@ object QuoteContextImpl { def showDecompiledTree(tree: tpd.Tree)(using Context): String = { val qctx: QuoteContextImpl = new QuoteContextImpl(MacroExpansion.context(tree)) if ctx.settings.color.value == "always" then - qctx.reflect.TreeMethodsImpl.extension_showAnsiColored(tree) + qctx.reflect.TreeMethodsImpl.temporaryShowAnsiColored(tree) else - qctx.reflect.TreeMethodsImpl.extension_show(tree) + qctx.reflect.TreeMethodsImpl.temporaryShow(tree) } private[dotty] def checkScopeId(id: ScopeId)(using Context): Unit = @@ -2535,8 +2535,8 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern object FlagsMethodsImpl extends FlagsMethods: extension (self: Flags): def is(that: Flags): Boolean = self.isAllOf(that) - def |(that: Flags): Flags = dotc.core.Flags.extension_|(self)(that) - def &(that: Flags): Flags = dotc.core.Flags.extension_&(self)(that) + def |(that: Flags): Flags = dotc.core.Flags.or(self, that) // TODO: Replace with dotc.core.Flags.|(self)(that) once extension names have stabilized + def &(that: Flags): Flags = dotc.core.Flags.and(self, that)// TODO: Replace with dotc.core.Flags.&(self)(that) once extension names have stabilized def showExtractors: String = Extractors.showFlags(using QuoteContextImpl.this)(self) def show: String = diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index bb4dc7aece23..b90d72ab2996 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1187,7 +1187,7 @@ trait Applications extends Compatibility { typedType(untpd.rename(tree, tree.name.toTypeName))(using nestedCtx) ttree.tpe match { case alias: TypeRef if alias.info.isTypeAlias && !nestedCtx.reporter.hasErrors => - companionRef(alias) match { + Inferencing.companionRef(alias) match { case companion: TermRef => return untpd.ref(companion).withSpan(tree.span) case _ => } @@ -1392,7 +1392,7 @@ trait Applications extends Compatibility { } /** Does `tp` have an extension method named `xname` with this-argument `argType` and - * result matching `resultType`? `xname` is supposed to start with `extension_`. + * result matching `resultType`? */ def hasExtensionMethodNamed(tp: Type, xname: TermName, argType: Type, resultType: Type)(using Context) = { def qualifies(mbr: Denotation) = @@ -2162,7 +2162,9 @@ trait Applications extends Compatibility { val (core, pt1) = normalizePt(methodRef, pt) val app = withMode(Mode.SynthesizeExtMethodReceiver) { - typed(untpd.Apply(core, untpd.TypedSplice(receiver) :: Nil), pt1, ctx.typerState.ownedVars) + typed( + untpd.Apply(core, untpd.TypedSplice(receiver, isExtensionReceiver = true) :: Nil), + pt1, ctx.typerState.ownedVars) } def isExtension(tree: Tree): Boolean = methPart(tree) match { case Inlined(call, _, _) => isExtension(call) diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index c97c41098182..180be8d83128 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -75,8 +75,9 @@ object Implicits: * method with the selecting name? False otherwise. */ def hasExtMethod(tp: Type, expected: Type)(using Context) = expected match - case selProto @ SelectionProto(_: TermName, _, _, _) => - tp.memberBasedOnFlags(selProto.extensionName, required = ExtensionMethod).exists + case selProto @ SelectionProto(selName: TermName, _, _, _) => + tp.memberBasedOnFlags(selName, required = ExtensionMethod).exists + || tp.memberBasedOnFlags(selProto.extensionName, required = ExtensionMethod).exists case _ => false def strictEquality(using Context): Boolean = @@ -993,9 +994,14 @@ trait Implicits: pt, locked) } pt match - case selProto @ SelectionProto(_: TermName, mbrType, _, _) if cand.isExtension => + case selProto @ SelectionProto(selName: TermName, mbrType, _, _) if cand.isExtension => def tryExtension(using Context) = - extMethodApply(untpd.Select(untpdGenerated, selProto.extensionName), argument, mbrType) + val xname = + if ref.memberBasedOnFlags(selProto.extensionName, required = ExtensionMethod).exists then + selProto.extensionName + else + selName + extMethodApply(untpd.Select(untpdGenerated, xname), argument, mbrType) if cand.isConversion then val extensionCtx, conversionCtx = ctx.fresh.setNewTyperState() val extensionResult = tryExtension(using extensionCtx) diff --git a/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala b/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala index 0cf4dff29009..ecee8265d038 100644 --- a/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala +++ b/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala @@ -219,7 +219,7 @@ trait ImportSuggestions: * applicable to `argType`. */ def extensionMethod(site: TermRef, name: TermName, argType: Type): Option[TermRef] = - site.member(name.toExtensionName) + site.member(name) .alternatives .map(mbr => TermRef(site, mbr.symbol)) .filter(ref => @@ -320,7 +320,7 @@ trait ImportSuggestions: def importString(ref: TermRef): String = val imported = if ref.symbol.is(ExtensionMethod) then - s"${ctx.printer.toTextPrefix(ref.prefix).show}${ref.symbol.name.dropExtension}" + s"${ctx.printer.toTextPrefix(ref.prefix).show}${ref.symbol.name}" else ctx.printer.toTextRef(ref).show s" import $imported" diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index abda621ae7fd..7efd0f8fc58c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -203,7 +203,7 @@ object Inliner { ref(meth).appliedToTypes(targs).appliedToArgss(prefss) .withSpan(mdef.rhs.span.startPos))( using ctx.withOwner(retainer))) - .reporting(i"retainer for $meth: $result", inlining) + .showing(i"retainer for $meth: $result", inlining) /** Replace `Inlined` node by a block that contains its bindings and expansion */ def dropInlined(inlined: Inlined)(using Context): Tree = @@ -853,7 +853,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { if (idx >= 0 && idx < args.length) { def finish(arg: Tree) = new TreeTypeMap().transform(arg) // make sure local bindings in argument have fresh symbols - .reporting(i"projecting $tree -> $result", inlining) + .showing(i"projecting $tree -> $result", inlining) val arg = args(idx) if (precomputed) if (isElideableExpr(arg)) finish(arg) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index c753150bc4b5..2ee42903c14e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1016,7 +1016,7 @@ class Namer { typer: Typer => def addForwardersNamed(name: TermName, alias: TermName, span: Span): Unit = { val size = buf.size - val mbrs = List(name, name.toTypeName, name.toExtensionName).flatMap(path.tpe.member(_).alternatives) + val mbrs = List(name, name.toTypeName).flatMap(path.tpe.member(_).alternatives) mbrs.foreach(addForwarder(alias, _, span)) if (buf.size == size) { val reason = mbrs.map(whyNoForwarder).dropWhile(_ == SKIP) match { @@ -1353,7 +1353,8 @@ class Namer { typer: Typer => def dealiasIfUnit(tp: Type) = if (tp.isRef(defn.UnitClass)) defn.UnitType else tp var rhsCtx = ctx.fresh.addMode(Mode.InferringReturnType) - if (sym.isInlineMethod) rhsCtx = rhsCtx.addMode(Mode.InlineableBody) + if sym.isInlineMethod then rhsCtx = rhsCtx.addMode(Mode.InlineableBody) + if sym.is(ExtensionMethod) then rhsCtx = rhsCtx.addMode(Mode.InExtensionMethod) if (typeParams.nonEmpty) { // we'll be typing an expression from a polymorphic definition's body, // so we must allow constraining its type parameters diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 3ef8b979c22c..71d99a210f7d 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -444,8 +444,9 @@ object ProtoTypes { def isMatchedBy(tp: Type, keepConstraint: Boolean)(using Context): Boolean = ctx.typer.isApplicableType(tp, argType :: Nil, resultType) || { resType match { - case selProto @ SelectionProto(_: TermName, mbrType, _, _) => - ctx.typer.hasExtensionMethodNamed(tp, selProto.extensionName, argType, mbrType) + case selProto @ SelectionProto(selName: TermName, mbrType, _, _) => + ctx.typer.hasExtensionMethodNamed(tp, selName, argType, mbrType) + || ctx.typer.hasExtensionMethodNamed(tp, selProto.extensionName, argType, mbrType) //.reporting(i"has ext $tp $name $argType $mbrType: $result") case _ => false @@ -517,6 +518,12 @@ object ProtoTypes { /** A prototype for type constructors that are followed by a type application */ @sharable object AnyTypeConstructorProto extends UncachedGroundType with MatchAlways + extension (pt: Type) + def isExtensionApplyProto: Boolean = pt match + case PolyProto(targs, res) => res.isExtensionApplyProto + case FunProto((arg: untpd.TypedSplice) :: Nil, _) => arg.isExtensionReceiver + case _ => false + /** Add all parameters of given type lambda `tl` to the constraint's domain. * If the constraint contains already some of these parameters in its domain, * make a copy of the type lambda and add the copy's type parameters instead. diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index cd1143418d3b..182725c11bd2 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -217,13 +217,6 @@ class Typer extends Namer */ def namedImportRef(imp: ImportInfo)(using Context): Type = { val termName = name.toTermName - - def adjustExtension(n: Name) = - if required.is(ExtensionMethod) && termName.endsWith(n.lastPart) - // pre-check to avoid forming a new string; form extension only if it has a chance of matching `termName` - then n.toExtensionName - else n - def recur(selectors: List[untpd.ImportSelector]): Type = selectors match case selector :: rest => def checkUnambiguous(found: Type) = @@ -232,12 +225,12 @@ class Typer extends Namer fail(em"reference to `$name` is ambiguous; it is imported twice") found - if adjustExtension(selector.rename) == termName && selector.rename != nme.WILDCARD then + if selector.rename == termName && selector.rename != nme.WILDCARD then val memberName = if selector.name == termName then name else if name.isTypeName then selector.name.toTypeName else selector.name - checkUnambiguous(selection(imp, adjustExtension(memberName), checkBounds = false)) + checkUnambiguous(selection(imp, memberName, checkBounds = false)) else recur(rest) @@ -450,27 +443,23 @@ class Typer extends Namer if (name == nme.ROOTPKG) return tree.withType(defn.RootPackage.termRef) - val rawType = { + val rawType = val saved1 = unimported val saved2 = foundUnderScala2 unimported = Set.empty foundUnderScala2 = NoType - try { - var found = findRef(name, pt, EmptyFlags, tree.srcPos) - if (foundUnderScala2.exists && !(foundUnderScala2 =:= found)) { + try + val found = findRef(name, pt, EmptyFlags, tree.srcPos) + if foundUnderScala2.exists && !(foundUnderScala2 =:= found) then report.migrationWarning( ex"""Name resolution will change. | currently selected : $foundUnderScala2 | in the future, without -source 3.0-migration: $found""", tree.srcPos) - found = foundUnderScala2 - } - found - } - finally { + foundUnderScala2 + else found + finally unimported = saved1 foundUnderScala2 = saved2 - } - } def setType(ownType: Type): Tree = val tree1 = ownType match @@ -482,16 +471,26 @@ class Typer extends Namer checkStableIdentPattern(tree2, pt) tree2 - def fail: Tree = - if ctx.owner.isConstructor && !ctx.owner.isPrimaryConstructor - && ctx.owner.owner.unforcedDecls.lookup(tree.name).exists - then - // we are in the arguments of a this(...) constructor call - errorTree(tree, ex"$tree is not accessible from constructor arguments") - else - errorTree(tree, MissingIdent(tree, kind, name)) + def isLocalExtensionMethodRef: Boolean = rawType match + case rawType: TermRef => + rawType.denot.hasAltWith(_.symbol.is(ExtensionMethod)) + && !pt.isExtensionApplyProto + && { + val xmethod = ctx.owner.enclosingExtensionMethod + rawType.denot.hasAltWith { alt => + alt.symbol.is(ExtensionMethod) + && alt.symbol.extensionParam.span == xmethod.extensionParam.span + } + } + case _ => + false - if rawType.exists then + if ctx.mode.is(Mode.InExtensionMethod) && isLocalExtensionMethodRef then + val xmethod = ctx.owner.enclosingExtensionMethod + val qualifier = untpd.ref(xmethod.extensionParam.termRef) + val selection = untpd.cpy.Select(tree)(qualifier, name) + typed(selection, pt) + else if rawType.exists then setType(ensureAccessible(rawType, superAccess = false, tree.srcPos)) else if name == nme._scope then // gross hack to support current xml literals. @@ -499,24 +498,12 @@ class Typer extends Namer ref(defn.XMLTopScopeModule.termRef) else if name.toTermName == nme.ERROR then setType(UnspecifiedErrorType) - else if name.isTermName then - // Convert a reference `f` to an extension method select `p.f`, where - // `p` is the closest enclosing extension parameter, or else convert to `this.f`. - val xmethod = ctx.owner.enclosingExtensionMethod - if xmethod.exists then - val qualifier = untpd.ref(xmethod.extensionParam.termRef) - val selection = untpd.cpy.Select(tree)(qualifier, name) - val result = tryEither(typed(selection, pt))((_, _) => fail) - def canAccessUnqualified(sym: Symbol) = - sym.is(ExtensionMethod) && (sym.extensionParam.span == xmethod.extensionParam.span) - if result.tpe.isError || canAccessUnqualified(result.symbol) then - result - else - fail - else - fail + else if ctx.owner.isConstructor && !ctx.owner.isPrimaryConstructor + && ctx.owner.owner.unforcedDecls.lookup(tree.name).exists + then // we are in the arguments of a this(...) constructor call + errorTree(tree, ex"$tree is not accessible from constructor arguments") else - fail + errorTree(tree, MissingIdent(tree, kind, name)) end typedIdent /** Check that a stable identifier pattern is indeed stable (SLS 8.1.5) @@ -842,7 +829,9 @@ class Typer extends Namer case fn @ TypeApply(fn1, targs) => untpd.cpy.TypeApply(fn)(toSetter(fn1), targs.map(untpd.TypedSplice(_))) case fn @ Apply(fn1, args) => - val result = untpd.cpy.Apply(fn)(toSetter(fn1), args.map(untpd.TypedSplice(_))) + val result = untpd.cpy.Apply(fn)( + toSetter(fn1), + args.map(untpd.TypedSplice(_, isExtensionReceiver = true))) fn1 match case Apply(_, _) => // current apply is to implicit arguments result.setApplyKind(ApplyKind.Using) @@ -1976,7 +1965,8 @@ class Typer extends Namer } } - if (sym.isInlineMethod) rhsCtx.addMode(Mode.InlineableBody) + if sym.isInlineMethod then rhsCtx.addMode(Mode.InlineableBody) + if sym.is(ExtensionMethod) then rhsCtx.addMode(Mode.InExtensionMethod) val rhs1 = PrepareInlineable.dropInlineIfError(sym, if sym.isScala2Macro then typedScala2MacroBody(ddef.rhs)(using rhsCtx) else typedExpr(ddef.rhs, tpt1.tpe.widenExpr)(using rhsCtx)) @@ -2775,7 +2765,7 @@ class Typer extends Namer typed(untpd.Select(untpd.New(untpd.TypedSplice(tpt)), nme.CONSTRUCTOR), pt) } recur(tycon, pt) - .reporting(i"try new $tree -> $result", typr) + .showing(i"try new $tree -> $result", typr) } } { (nu, nuState) => if (nu.isEmpty) fallBack(nuState) @@ -2947,7 +2937,10 @@ class Typer extends Namer } def adaptOverloaded(ref: TermRef) = { - val altDenots = ref.denot.alternatives + val altDenots = + val allDenots = ref.denot.alternatives + if pt.isExtensionApplyProto then allDenots.filter(_.symbol.is(ExtensionMethod)) + else allDenots typr.println(i"adapt overloaded $ref with alternatives ${altDenots map (_.info)}%\n\n %") def altRef(alt: SingleDenotation) = TermRef(ref.prefix, ref.name, alt) val alts = altDenots.map(altRef) @@ -3327,8 +3320,12 @@ class Typer extends Namer // where we have an argument that must be converted with another // implicit conversion to the receiver type. def sharpenedPt = pt match - case pt: SelectionProto if pt.name.isExtensionName => pt.deepenProto - case _ => pt + case pt: SelectionProto + if pt.name.isExtensionName + || pt.memberProto.revealIgnored.isExtensionApplyProto => + pt.deepenProto + case _ => + pt def adaptNoArgs(wtp: Type): Tree = { val ptNorm = underlyingApplied(pt) @@ -3471,17 +3468,17 @@ class Typer extends Namer // try an extension method in scope pt match { - case selProto @ SelectionProto(_: TermName, mbrType, _, _) => + case selProto @ SelectionProto(selName: TermName, mbrType, _, _) => def tryExtension(using Context): Tree = try - findRef(selProto.extensionName, WildcardType, ExtensionMethod, tree.srcPos) match { + findRef(selName, WildcardType, ExtensionMethod, tree.srcPos) match case ref: TermRef => extMethodApply(untpd.ref(ref).withSpan(tree.span), tree, mbrType) - case _ => EmptyTree - } - catch { - case ex: TypeError => errorTree(tree, ex, tree.srcPos) - } + case _ => findRef(selProto.extensionName, WildcardType, ExtensionMethod, tree.srcPos) match + case ref: TermRef => + extMethodApply(untpd.ref(ref).withSpan(tree.span), tree, mbrType) + case _ => EmptyTree + catch case ex: TypeError => errorTree(tree, ex, tree.srcPos) val nestedCtx = ctx.fresh.setNewTyperState() val app = tryExtension(using nestedCtx) if (!app.isEmpty && !nestedCtx.reporter.hasErrors) { @@ -3590,7 +3587,6 @@ class Typer extends Namer case _ => tryInsertApplyOrImplicit(tree, pt, locked)(tree) // error will be reported in typedTypeApply } case pt: SelectionProto if tree.isInstanceOf[ExtMethodApply] => - assert(pt.extensionName == tree.symbol.name) tree case _ => if (ctx.mode is Mode.Type) adaptType(tree.tpe) diff --git a/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala b/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala index 4f643f4102f2..1f7785653fa6 100644 --- a/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala +++ b/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala @@ -76,7 +76,7 @@ class SemanticdbTests: |inspect with: | diff $expect ${expect.resolveSibling("" + expect.getFileName + ".out")} |Or else update all expect files with - | sbt 'dotty-compiler-bootstrapped/test:runMain dotty.tools.dotc.semanticdb.updateExpect'""".stripMargin) + | sbt 'scala3-compiler-bootstrapped/test:runMain dotty.tools.dotc.semanticdb.updateExpect'""".stripMargin) Files.walk(target).sorted(Comparator.reverseOrder).forEach(Files.delete) if errors.nonEmpty then fail(s"${errors.size} errors in expect test.") diff --git a/compiler/test/dotty/tools/repl/DocTests.scala b/compiler/test/dotty/tools/repl/DocTests.scala index 0cdf886a1bbc..67f203c9b52b 100644 --- a/compiler/test/dotty/tools/repl/DocTests.scala +++ b/compiler/test/dotty/tools/repl/DocTests.scala @@ -30,7 +30,7 @@ class DocTests extends ReplTest { eval("/** doc */ trait Foo").andThen { implicit s => assertEquals("doc", doc("new Foo")) } - +/* @Test def docOfExtension1 = eval("/** doc */ extension (x: Int) def foo = 0").andThen { implicit s => assertEquals("doc", doc("extension_foo")) @@ -47,7 +47,7 @@ class DocTests extends ReplTest { assertEquals("doc2", doc("extension_bar")) assertEquals("doc0", doc("extension_baz")) } - +*/ @Test def docOfDefInObject = eval("object O { /** doc */ def foo = 0 }").andThen { implicit s => assertEquals("doc", doc("O.foo")) diff --git a/docs/docs/reference/contextual/extension-methods.md b/docs/docs/reference/contextual/extension-methods.md index 5b3e50bfcd03..77e8eef90055 100644 --- a/docs/docs/reference/contextual/extension-methods.md +++ b/docs/docs/reference/contextual/extension-methods.md @@ -21,14 +21,13 @@ circle.circumference ### Translation of Extension Methods -Extension methods are methods that have a parameter clause in front of the defined identifier. -An extension method named `f` translates to the method named `extension_f` that takes the leading parameter section as its first argument list. -So, the definition of `circumference` above translates to the following method, and can also be invoked as such: +An extension method translates to a specially labelled method that takes the leading parameter section as its first argument list. The label, expressed +as `` here, is compiler-internal. So, the definition of `circumference` above translates to the following method, and can also be invoked as such: ```scala -def extension_circumference(c: Circle): Double = c.radius * math.Pi * 2 + def circumference(c: Circle): Double = c.radius * math.Pi * 2 -assert(circle.circumference == extension_circumference(circle)) +assert(circle.circumference == circumference(circle)) ``` ### Operators @@ -51,9 +50,9 @@ x min 3 The three definitions above translate to ```scala -def extension_< (x: String)(y: String): Boolean = ... -def extension_+: (xs: Seq[Elem])(x: Elem): Seq[Elem] = ... -@infix def extension_min(x: Number)(y: Number): Number = ... + def < (x: String)(y: String): Boolean = ... + def +: (xs: Seq[Elem])(x: Elem): Seq[Elem] = ... +@infix def min(x: Number)(y: Number): Number = ... ``` Note the swap of the two parameters `x` and `xs` when translating @@ -101,7 +100,7 @@ By contrast, using clauses can be defined for the `extension` as well as per `de Sometimes, one wants to define several extension methods that share the same left-hand parameter type. In this case one can "pull out" the common parameters into a single extension and enclose all methods in braces or an indented region following a '`:`'. -Following an example using an indented region: +Example: ```scala extension (ss: Seq[String]): @@ -141,6 +140,16 @@ extension (ss: Seq[String]) def longestString: String = ss.longestStrings.head ``` +Collective extensions also can take type parameters and have using clauses. Example: + +```scala +extension [T](xs: List[T])(using Ordering[T]): + def smallest(n: Int): List[T] = xs.sorted.take(n) + def smallestIndices(n: Int): List[Int] = + val limit = smallest(n).max + xs.zipWithIndex.collect { case (x, i) if x <= limit => i } +``` + ### Translation of Calls to Extension Methods To convert a reference to an extension method, the compiler has to know about the extension @@ -218,9 +227,9 @@ The precise rules for resolving a selection to an extension method are as follow Assume a selection `e.m[Ts]` where `m` is not a member of `e`, where the type arguments `[Ts]` are optional, and where `T` is the expected type. The following two rewritings are tried in order: - 1. The selection is rewritten to `extension_m[Ts](e)`. + 1. The selection is rewritten to `m[Ts](e)`. 2. If the first rewriting does not typecheck with expected type `T`, - and there is an extension method `m` in some eligible object `o`, the selection is rewritten to `o.extension_m[Ts](e)`. An object `o` is _eligible_ if + and there is an extension method `m` in some eligible object `o`, the selection is rewritten to `o.m[Ts](e)`. An object `o` is _eligible_ if - `o` forms part of the implicit scope of `T`, or - `o` is a given instance that is visible at the point of the application, or @@ -229,15 +238,13 @@ The following two rewritings are tried in order: This second rewriting is attempted at the time where the compiler also tries an implicit conversion from `T` to a type containing `m`. If there is more than one way of rewriting, an ambiguity error results. -An extension method can also be used as an identifier by itself. If an identifier `m` does not -resolve, the identifier is rewritten to: - -- `x.m` if the identifier appears in an extension with parameter `x` - and the method `m` resolves to an extension method in - a (possibly collective) extension that also contains the call, -- `this.m` otherwise - -and the rewritten term is again tried as an application of an extension method. In +An extension method can also be referenced using a simple identifier without a preceding expression. If an identifier `g` appears in the body of an extension method `f` and refers to an extension method `g` that is defined in the same collective extension +```scala +extension (x: T) + def f ... = ... g ... + def g ... +``` +the identifier is rewritten to `x.g`. This is also the case if `f` and `g` are the same method. Example: ```scala extension (s: String) @@ -249,27 +256,11 @@ extension (s: String) The recursive call `position(ch, n + 1)` expands to `s.position(ch, n + 1)` in this case. The whole extension method rewrites to ```scala -def extension_position(s: String)(ch: Char, n: Int): Int = - if n < s.length && s(n) != ch then extension_position(s)(ch, n + 1) +def position(s: String)(ch: Char, n: Int): Int = + if n < s.length && s(n) != ch then position(s)(ch, n + 1) else n ``` -### More Details - -1. To avoid confusion, names of normal methods are not allowed to start with `extension_`. - -2. A named import such as `import a.m` of an extension method in `a` will make `m` only available as an extension method. - To access it under `extension_m` that name has to be imported separately. Example: - - ```scala - object DoubleOps: - extension (x: Double) def ** (exponent: Int): Double = - require(exponent >= 0) - if exponent == 0 then 1 else x * (x ** (exponent - 1)) - - import DoubleOps.{**, extension_**} - assert(2.0 ** 3 == extension_**(2.0)(3)) - ``` ### Syntax diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index f16ebe9c1e4f..5055e27d1cab 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -140,6 +140,10 @@ trait Reflection { reflection => protected val TreeMethodsImpl: TreeMethods trait TreeMethods { + // Dodo: Drop once extension methods have stabilized + def temporaryShowAnsiColored(self: Tree): String = self.showAnsiColored + def temporaryShow(self: Tree): String = self.show + extension (self: Tree): /** Position in the source code */ def pos: Position diff --git a/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala b/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala index ea3e64445ac5..79cebb865f3d 100644 --- a/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala +++ b/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala @@ -60,15 +60,15 @@ extension (member: Member): val memberWithExtra = member.asInstanceOf[WithExtraProperties[Member]] memberWithExtra.withNewExtras(memberWithExtra.getExtra plus ext).asInstanceOf[Member] - def copy(modifiers: Seq[Modifier]) = + def copy(modifiers: Seq[Modifier]): Member = val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(modifiers = modifiers) putInMember(ext) - def withOrigin(origin: Origin) = + def withOrigin(origin: Origin): Member = val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(origin = origin) putInMember(ext) - def withKind(kind: Kind) = + def withKind(kind: Kind): Member = val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(kind = kind) putInMember(ext) diff --git a/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala b/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala index 495295a3a4e1..87d0a8297248 100644 --- a/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala +++ b/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala @@ -238,7 +238,6 @@ trait ClassLikeSupport: val name = methodKind match case Kind.Constructor => "this" case Kind.Given(_, _) => methodSymbol.name.stripPrefix("given_") - case Kind.Extension(_) => methodSymbol.name.stripPrefix("extension_") case _ => methodSymbol.name new DFunction( diff --git a/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala b/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala index f9348eb5b815..a450b52c1a49 100644 --- a/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala +++ b/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala @@ -36,9 +36,7 @@ class ScalaPageCreator( override def pageForModule(m: DModule): ModulePageNode = super.pageForModule(m) private def updatePageNameForMember(page: PageNode, p: Member) = - val name = p.kind match - case Kind.Extension(_) => s"extension_${page.getName}" - case _ => page.getName + val name = page.getName page.modified(name, page.getChildren) @@ -164,7 +162,7 @@ class ScalaPageCreator( extension (b: DocBuilder): def descriptionIfNotEmpty(d: Documentable): DocBuilder = { - val desc = contentForDescription(d).asScala.toSeq + val desc = this.contentForDescription(d).asScala.toSeq val res = if desc.isEmpty then b else b .sourceSetDependentHint( Set(d.getDri), diff --git a/tests/pos/i8311.scala b/tests/disabled/pos/i8311.scala similarity index 70% rename from tests/pos/i8311.scala rename to tests/disabled/pos/i8311.scala index fa6c68b40536..93649a06154d 100644 --- a/tests/pos/i8311.scala +++ b/tests/disabled/pos/i8311.scala @@ -13,7 +13,7 @@ object test: def run(s: Box[Box[Foo]]): Unit = val x = summon[Show[Box[Box[Foo]]]] - x.extension_show(s) - val r: String = box.extension_show(s) - println(s"step: ${box[Box[Foo]].extension_show(s)}") + x.show(s) + val r: String = box.show(s) + println(s"step: ${box[Box[Foo]].show(s)}") println(s"step: ${s.show}") diff --git a/tests/neg/enum-values.check b/tests/neg/enum-values.check index c8632ed17e45..3d1f3e84b805 100644 --- a/tests/neg/enum-values.check +++ b/tests/neg/enum-values.check @@ -6,7 +6,7 @@ | meaning a values array is not defined. | An extension method was tried, but could not be fully constructed: | - | example.Extensions.extension_values(Tag) + | example.Extensions.values(Tag) -- [E008] Not Found Error: tests/neg/enum-values.scala:33:50 ----------------------------------------------------------- 33 | val listlikes: Array[ListLike[?]] = ListLike.values // error | ^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ | meaning a values array is not defined. | An extension method was tried, but could not be fully constructed: | - | example.Extensions.extension_values(ListLike) + | example.Extensions.values(ListLike) -- [E008] Not Found Error: tests/neg/enum-values.scala:34:52 ----------------------------------------------------------- 34 | val typeCtorsK: Array[TypeCtorsK[?]] = TypeCtorsK.values // error | ^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ | meaning a values array is not defined. | An extension method was tried, but could not be fully constructed: | - | example.Extensions.extension_values(TypeCtorsK) + | example.Extensions.values(TypeCtorsK) -- [E008] Not Found Error: tests/neg/enum-values.scala:36:6 ------------------------------------------------------------ 36 | Tag.valueOf("Int") // error | ^^^^^^^^^^^ @@ -54,7 +54,7 @@ | value values is not a member of object example.NotAnEnum. | An extension method was tried, but could not be fully constructed: | - | example.Extensions.extension_values(NotAnEnum) + | example.Extensions.values(NotAnEnum) -- [E008] Not Found Error: tests/neg/enum-values.scala:41:12 ----------------------------------------------------------- 41 | NotAnEnum.valueOf("Foo") // error | ^^^^^^^^^^^^^^^^^ diff --git a/tests/neg/i6183.check b/tests/neg/i6183.check index e0f826c8be35..0f09c0b0c166 100644 --- a/tests/neg/i6183.check +++ b/tests/neg/i6183.check @@ -1,16 +1,16 @@ --- [E008] Not Found Error: tests/neg/i6183.scala:5:5 ------------------------------------------------------------------- -5 | 42.render // error - | ^^^^^^^^^ - | value render is not a member of Int. - | An extension method was tried, but could not be fully constructed: +-- [E008] Not Found Error: tests/neg/i6183.scala:6:7 ------------------------------------------------------------------- +6 | 42.render // error + | ^^^^^^^^^ + | value render is not a member of Int. + | An extension method was tried, but could not be fully constructed: | - | extension_render(42) --- [E051] Reference Error: tests/neg/i6183.scala:6:2 ------------------------------------------------------------------- -6 | extension_render(42) // error - | ^^^^^^^^^^^^^^^^ - | Ambiguous overload. The overloaded alternatives of method extension_render with types - | [B](b: B)(using x$1: DummyImplicit): Char - | [A](a: A): String - | both match arguments ((42 : Int)) + | render(42) +-- [E051] Reference Error: tests/neg/i6183.scala:7:9 ------------------------------------------------------------------- +7 | Test.render(42) // error + | ^^^^^^^^^^^ + | Ambiguous overload. The overloaded alternatives of method render in object Test with types + | [B](b: B)(using x$1: DummyImplicit): Char + | [A](a: A): String + | both match arguments ((42 : Int)) longer explanation available when compiling with `-explain` diff --git a/tests/neg/i6183.scala b/tests/neg/i6183.scala index 5a6366533d49..30eae3abdbe3 100644 --- a/tests/neg/i6183.scala +++ b/tests/neg/i6183.scala @@ -1,7 +1,8 @@ -extension [A](a: A) def render: String = "Hi" -extension [B](b: B) def render(using DummyImplicit): Char = 'x' +object Test: + extension [A](a: A) def render: String = "Hi" + extension [B](b: B) def render(using DummyImplicit): Char = 'x' -val test = { - 42.render // error - extension_render(42) // error -} + val test = { + 42.render // error + Test.render(42) // error + } diff --git a/tests/neg/i6779.check b/tests/neg/i6779.check index 8f5055eee857..4e1ebd5da972 100644 --- a/tests/neg/i6779.check +++ b/tests/neg/i6779.check @@ -1,15 +1,15 @@ --- [E007] Type Mismatch Error: tests/neg/i6779.scala:9:30 -------------------------------------------------------------- -9 |def g1[T](x: T): F[G[T]] = x.f(using summon[Stuff]) // error - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: F[T] - | Required: F[G[T]] --- [E007] Type Mismatch Error: tests/neg/i6779.scala:11:29 ------------------------------------------------------------- -11 |def g2[T](x: T): F[G[T]] = x.f // error - | ^^^ - | Found: F[T] - | Required: F[G[T]] --- [E007] Type Mismatch Error: tests/neg/i6779.scala:13:41 ------------------------------------------------------------- -13 |def g3[T](x: T): F[G[T]] = extension_f(x)(using summon[Stuff]) // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: F[T] - | Required: F[G[T]] +-- [E007] Type Mismatch Error: tests/neg/i6779.scala:10:32 ------------------------------------------------------------- +10 | def g1[T](x: T): F[G[T]] = x.f(using summon[Stuff]) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: F[T] + | Required: F[G[T]] +-- [E007] Type Mismatch Error: tests/neg/i6779.scala:12:31 ------------------------------------------------------------- +12 | def g2[T](x: T): F[G[T]] = x.f // error + | ^^^ + | Found: F[T] + | Required: F[G[T]] +-- [E007] Type Mismatch Error: tests/neg/i6779.scala:14:38 ------------------------------------------------------------- +14 | def g3[T](x: T): F[G[T]] = this.f(x)(using summon[Stuff]) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: F[T] + | Required: F[G[T]] diff --git a/tests/neg/i6779.scala b/tests/neg/i6779.scala index bd40387be3d9..c83a2368940e 100644 --- a/tests/neg/i6779.scala +++ b/tests/neg/i6779.scala @@ -3,11 +3,12 @@ type G[T] type Stuff given Stuff = ??? -extension [T](x: T) def f(using Stuff): F[T] = ??? +object Test: + extension [T](x: T) def f(using Stuff): F[T] = ??? -def g1[T](x: T): F[G[T]] = x.f(using summon[Stuff]) // error + def g1[T](x: T): F[G[T]] = x.f(using summon[Stuff]) // error -def g2[T](x: T): F[G[T]] = x.f // error + def g2[T](x: T): F[G[T]] = x.f // error -def g3[T](x: T): F[G[T]] = extension_f(x)(using summon[Stuff]) // error + def g3[T](x: T): F[G[T]] = this.f(x)(using summon[Stuff]) // error diff --git a/tests/neg/i9185.check b/tests/neg/i9185.check index 9fb873f57334..c469b447742e 100644 --- a/tests/neg/i9185.check +++ b/tests/neg/i9185.check @@ -4,17 +4,17 @@ |value pure is not a member of String. |An extension method was tried, but could not be fully constructed: | - | M.extension_pure[A, F]("ola")( + | M.pure[A, F]("ola")( | /* ambiguous: both object listMonad in object M and object optionMonad in object M match type M[F] */summon[M[F]] | ) --- Error: tests/neg/i9185.scala:8:36 ----------------------------------------------------------------------------------- -8 | val value3 = extension_pure("ola") // error - | ^ - |ambiguous implicit arguments: both object listMonad in object M and object optionMonad in object M match type M[F] of parameter m of method extension_pure in object M +-- Error: tests/neg/i9185.scala:8:28 ----------------------------------------------------------------------------------- +8 | val value3 = M.pure("ola") // error + | ^ + |ambiguous implicit arguments: both object listMonad in object M and object optionMonad in object M match type M[F] of parameter m of method pure in object M -- [E008] Not Found Error: tests/neg/i9185.scala:11:16 ----------------------------------------------------------------- 11 | val l = "abc".len // error | ^^^^^^^^^ | value len is not a member of String. | An extension method was tried, but could not be fully constructed: | - | M.extension_len("abc") + | M.len("abc") diff --git a/tests/neg/i9185.scala b/tests/neg/i9185.scala index c4b47623ed0c..d4558e28bbbd 100644 --- a/tests/neg/i9185.scala +++ b/tests/neg/i9185.scala @@ -5,7 +5,7 @@ object M { given optionMonad as M[Option] { def pure[A](x: A): Option[A] = Some(x) } val value1: List[String] = "ola".pure val value2 = "ola".pure // error - val value3 = extension_pure("ola") // error + val value3 = M.pure("ola") // error extension (x: Int) def len: Int = x val l = "abc".len // error diff --git a/tests/neg/illegal-extension.check b/tests/neg/illegal-extension.check deleted file mode 100644 index 524c8c822db5..000000000000 --- a/tests/neg/illegal-extension.check +++ /dev/null @@ -1,20 +0,0 @@ --- Error: tests/neg/illegal-extension.scala:2:6 ------------------------------------------------------------------------ -2 | def extension_n: String = "illegal method" // error: illegal name: extension_n may not start with `extension_` - | ^^^^^^^^^^^ - | illegal name: extension_n may not start with `extension_` --- Error: tests/neg/illegal-extension.scala:4:6 ------------------------------------------------------------------------ -4 | val extension_val = 23 // error: illegal name: extension_val may not start with `extension_` - | ^^^^^^^^^^^^^ - | illegal name: extension_val may not start with `extension_` --- Error: tests/neg/illegal-extension.scala:5:14 ----------------------------------------------------------------------- -5 | private var extension = Nil // error: illegal setter name: `extension_=` - | ^^^^^^^^^ - | illegal setter name: `extension_=` --- Error: tests/neg/illegal-extension.scala:16:23 ---------------------------------------------------------------------- -16 |extension (x: Any) def extension_foo: String = "foo" // error: illegal name: extension_foo may not start with `extension_` - | ^^^^^^^^^^^^^ - | illegal name: extension_foo may not start with `extension_` --- Error: tests/neg/illegal-extension.scala:9:6 ------------------------------------------------------------------------ -9 | var extension = 1337 // error: illegal setter name: `extension_=` - | ^^^^^^^^^ - | illegal setter name: `extension_=` diff --git a/tests/neg/illegal-extension.scala b/tests/neg/illegal-extension.scala deleted file mode 100644 index 03bde296adc2..000000000000 --- a/tests/neg/illegal-extension.scala +++ /dev/null @@ -1,20 +0,0 @@ -trait A { - def extension_n: String = "illegal method" // error: illegal name: extension_n may not start with `extension_` - type extension_type = Int // allowed because it's a type alias - val extension_val = 23 // error: illegal name: extension_val may not start with `extension_` - private var extension = Nil // error: illegal setter name: `extension_=` -} - -class B { - var extension = 1337 // error: illegal setter name: `extension_=` -} - -class C { - private var extension = "OK" // allowed because it does not require a setter -} - -extension (x: Any) def extension_foo: String = "foo" // error: illegal name: extension_foo may not start with `extension_` -extension (some: Any) def valid_extension_name: String = { - var extension = "foo" // `extension` name allowed because it doesn't require a setter - s"$extension bar" -} \ No newline at end of file diff --git a/tests/neg/missing-implicit1.check b/tests/neg/missing-implicit1.check index 5b3d0dc6a4e9..4ff1d5d84225 100644 --- a/tests/neg/missing-implicit1.check +++ b/tests/neg/missing-implicit1.check @@ -19,7 +19,7 @@ -- Error: tests/neg/missing-implicit1.scala:23:42 ---------------------------------------------------------------------- 23 | List(1, 2, 3).traverse(x => Option(x)) // error | ^ - |no implicit argument of type testObjectInstance.Zip[Option] was found for an implicit parameter of method extension_traverse in trait Traverse + |no implicit argument of type testObjectInstance.Zip[Option] was found for an implicit parameter of method traverse in trait Traverse | |The following import might fix the problem: | diff --git a/tests/neg/missing-implicit4.check b/tests/neg/missing-implicit4.check index 2baa37b0e5e9..4653dd8df351 100644 --- a/tests/neg/missing-implicit4.check +++ b/tests/neg/missing-implicit4.check @@ -19,7 +19,7 @@ -- Error: tests/neg/missing-implicit4.scala:20:42 ---------------------------------------------------------------------- 20 | List(1, 2, 3).traverse(x => Option(x)) // error | ^ - |no implicit argument of type Zip[Option] was found for an implicit parameter of method extension_traverse in trait Traverse + |no implicit argument of type Zip[Option] was found for an implicit parameter of method traverse in trait Traverse | |The following import might fix the problem: | diff --git a/tests/new/test.scala b/tests/new/test.scala index c42aaf364300..6563875e2cac 100644 --- a/tests/new/test.scala +++ b/tests/new/test.scala @@ -1,3 +1,9 @@ -trait T { - object O + +trait SemiGroup[T] { + extension (x: T) def combine(y: T): T } +trait Monoid[T] extends SemiGroup[T] { + def unit: T +} +def sum[T: Monoid](xs: List[T]): T = + xs.foldLeft(implicitly[Monoid[T]].unit)((x, y) => x.combine(y)) diff --git a/tests/pos/i5773.scala b/tests/pos/i5773.scala index 0cc0bfdf9207..9d8da69e81a2 100644 --- a/tests/pos/i5773.scala +++ b/tests/pos/i5773.scala @@ -31,6 +31,6 @@ object Main { def f3 = { import Semigroup.SumSemiGroupDeco - sumSemigroup.extension_append(1)(2) + sumSemigroup.append(1)(2) } } \ No newline at end of file diff --git a/tests/pos/i7401.scala b/tests/pos/i7401.scala index fe7d11aba7a5..4754eefbb95b 100644 --- a/tests/pos/i7401.scala +++ b/tests/pos/i7401.scala @@ -6,6 +6,6 @@ object Test { val x: Int = 5 x.foo(4) x.foo - Test.extension_foo(x)(4) - extension_foo(x) + Test.foo(x)(4) + foo(x) } \ No newline at end of file diff --git a/tests/pos/opaque-xm.scala b/tests/pos/opaque-xm.scala index de2210d1ae3d..fac02902d13d 100644 --- a/tests/pos/opaque-xm.scala +++ b/tests/pos/opaque-xm.scala @@ -30,6 +30,6 @@ object usesites { // as a contextual implicit this takes precedence over the // implicit scope implicit LogarithmOps. // TODO: Remove any2stringadd - val d = Logarithm.extension_toDouble(l3) + val d = Logarithm.toDouble(l3) val l5: Logarithm = (1.0).asInstanceOf[Logarithm] } diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index 5c830a1a2e1d..44be54d0684d 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -65,7 +65,7 @@ object Instances extends Common: xs.reduceLeft((x, y) => if (x < y) y else x) def descending[T](using asc: Ord[T]): Ord[T] = new Ord[T]: - extension (x: T) def compareTo(y: T) = asc.extension_compareTo(y)(x) + extension (x: T) def compareTo(y: T) = asc.compareTo(y)(x) def minimum[T](xs: List[T])(using Ord[T]) = maximum(xs)(using descending) @@ -163,7 +163,7 @@ object AnonymousInstances extends Common: def second = xs.tail.head given [From, To](using c: Convertible[From, To]) as Convertible[List[From], List[To]]: - extension (x: List[From]) def convert: List[To] = x.map(c.extension_convert) + extension (x: List[From]) def convert: List[To] = x.map(c.convert) given Monoid[String]: extension (x: String) def combine(y: String): String = x.concat(y) @@ -190,7 +190,7 @@ object Implicits extends Common: class given_Convertible_List_List[From, To](implicit c: Convertible[From, To]) extends Convertible[List[From], List[To]]: - extension (x: List[From]) def convert: List[To] = x.map(c.extension_convert) + extension (x: List[From]) def convert: List[To] = x.map(c.convert) implicit def given_Convertible_List_List[From, To](implicit c: Convertible[From, To]) : Convertible[List[From], List[To]] = new given_Convertible_List_List[From, To] @@ -200,7 +200,7 @@ object Implicits extends Common: xs.reduceLeft((x, y) => if (x < y) y else x) def descending[T](implicit asc: Ord[T]): Ord[T] = new Ord[T]: - extension (x: T) def compareTo(y: T) = asc.extension_compareTo(y)(x) + extension (x: T) def compareTo(y: T) = asc.compareTo(y)(x) def minimum[T](xs: List[T])(implicit cmp: Ord[T]) = maximum(xs)(descending) diff --git a/tests/pos/reference/extension-methods.scala b/tests/pos/reference/extension-methods.scala index b74815fbdf82..2f4f6d6ee195 100644 --- a/tests/pos/reference/extension-methods.scala +++ b/tests/pos/reference/extension-methods.scala @@ -9,7 +9,7 @@ object ExtMethods: val circle = Circle(0, 0, 1) circle.circumference - assert(circle.circumference == extension_circumference(circle)) + assert(circle.circumference == circumference(circle)) extension (x: String) def < (y: String) = x.compareTo(y) < 0 extension [Elem](x: Elem) def #: (xs: Seq[Elem]) = x +: xs @@ -103,7 +103,7 @@ object ExtMethods: summon[Ord[Lst[Lst[Int]]]] - assert(Lst.ord[Lst[Int]].extension_less(xss)(Lst(Lst(3)))) + assert(Lst.ord[Lst[Int]].less(xss)(Lst(Lst(3)))) assert(xss `less` Lst(Lst(3))) assert(xss.flatten `less` Lst(3)) @@ -117,7 +117,7 @@ object ExtMethods: require(exponent > 0) if exponent == 0 then 1 else x * (x ** (exponent - 1)) - import DoubleOps.{**, extension_**} - assert(2.0 ** 3 == extension_**(2.0)(3)) + import DoubleOps.{**} + assert(2.0 ** 3 == **(2.0)(3)) end ExtMethods \ No newline at end of file diff --git a/tests/run-macros/i6201/test_2.scala b/tests/run-macros/i6201/test_2.scala index 86519b41eb3d..cb8c2053e673 100644 --- a/tests/run-macros/i6201/test_2.scala +++ b/tests/run-macros/i6201/test_2.scala @@ -1,6 +1,6 @@ object Test { def main(args: Array[String]): Unit = { - assert(isHello(extension_strip("hello"))) - assert(!isHello(extension_strip("bonjour"))) + assert(isHello(strip("hello"))) + assert(!isHello(strip("bonjour"))) } } \ No newline at end of file diff --git a/tests/run-macros/xml-interpolation-7/Macros_1.scala b/tests/run-macros/xml-interpolation-7/Macros_1.scala index bec14ea29429..5cf4e3e3ee41 100644 --- a/tests/run-macros/xml-interpolation-7/Macros_1.scala +++ b/tests/run-macros/xml-interpolation-7/Macros_1.scala @@ -26,7 +26,7 @@ object XmlQuote { def impl(receiver: Expr[XMLOps.StringContext], args: Expr[Seq[Any]])(using QuoteContext): Expr[Xml] = { val string = receiver match { - case '{ XMLOps.extension_xml(${Unlifted(sc)}) } => sc.parts.mkString("??") + case '{ XMLOps.xml(${Unlifted(sc)}) } => sc.parts.mkString("??") } '{new Xml(${Expr(string)}, $args.toList)} } diff --git a/tests/run/collective-extensions.scala b/tests/run/collective-extensions.scala index c76dda6d2a1b..3ed15e4ec9a7 100644 --- a/tests/run/collective-extensions.scala +++ b/tests/run/collective-extensions.scala @@ -4,11 +4,12 @@ extension (x: String) def baz(y: String): String = val x = y bar(x) - def bam(y: String): String = this.extension_baz(x)(y) + def bam(y: String): String = this.baz(x)(y) def ban(foo: String): String = x + foo def bao(y: String): String = - val bam = "ABC" + val bam = name x ++ y ++ bam + def name: String = "ABC" def app(n: Int, suffix: String): String = if n == 0 then x ++ suffix diff --git a/tests/run/extension-methods.scala b/tests/run/extension-methods.scala index 897f3ff41896..04aa06d882eb 100644 --- a/tests/run/extension-methods.scala +++ b/tests/run/extension-methods.scala @@ -2,7 +2,7 @@ object Test extends App { extension (x: Int) def em: Boolean = x > 0 - assert(1.em == extension_em(1)) + assert(1.em == em(1)) case class Circle(x: Double, y: Double, radius: Double) @@ -10,7 +10,7 @@ object Test extends App { val circle = new Circle(1, 1, 2.0) - assert(circle.circumference == extension_circumference(circle)) + assert(circle.circumference == this.circumference(circle)) extension (xs: Seq[String]) def longestStrings: Seq[String] = { val maxLength = xs.map(_.length).max @@ -113,7 +113,7 @@ object Test extends App { def mappAll[F[_]: Monad, T](x: T, fs: List[T => T]): F[T] = fs.foldLeft(implicitly[Monad[F]].pure(x))((x: F[T], f: T => T) => - if (true) implicitly[Monad[F]].extension_map(x)(f) + if (true) implicitly[Monad[F]].map(x)(f) else if (true) x.map(f) else x.map[T, T](f) ) diff --git a/tests/run/extension-override.scala b/tests/run/extension-override.scala new file mode 100644 index 000000000000..00246f611391 --- /dev/null +++ b/tests/run/extension-override.scala @@ -0,0 +1,12 @@ +class A: + extension (s: String) + def len: Int = s.length + +object B extends A: + extension (s: String) + override def len: Int = s.length + 1 + +@main def Test = + import B._ + assert("abc".len == 4) + diff --git a/tests/run/extmethods2.scala b/tests/run/extmethods2.scala index 61766a4c3a79..f1369d37d306 100644 --- a/tests/run/extmethods2.scala +++ b/tests/run/extmethods2.scala @@ -34,8 +34,8 @@ object Test extends App { val xs = List(1, 2, 3) assert(xs.second[Int] == 2) assert(xs.third == 3) - assert(A.extension_second[Int](xs) == 2) - assert(A.extension_third(xs) == 3) + assert(A.second[Int](xs) == 2) + assert(A.third(xs) == 3) assert(xs.prod == 6) assert(xs.concat(xs).length == 6) assert(xs.zipp(xs).map(_ + _).prod == 36) diff --git a/tests/run/instances-anonymous.scala b/tests/run/instances-anonymous.scala index 4a189f9811ce..6df12e5d52e7 100644 --- a/tests/run/instances-anonymous.scala +++ b/tests/run/instances-anonymous.scala @@ -4,7 +4,7 @@ object Test extends App { extension (x: Int) def em: Boolean = x > 0 } - assert(1.em == O.extension_em(1)) + assert(1.em == O.em(1)) case class Circle(x: Double, y: Double, radius: Double) @@ -117,7 +117,7 @@ object Test extends App { def mappAll[F[_]: Monad, T](x: T, fs: List[T => T]): F[T] = fs.foldLeft(implicitly[Monad[F]].pure(x))((x: F[T], f: T => T) => - if (true) implicitly[Monad[F]].extension_map(x)(f) + if (true) implicitly[Monad[F]].map(x)(f) else if (true) x.map(f) else x.map[T, T](f) ) diff --git a/tests/run/instances.scala b/tests/run/instances.scala index fd120fa2dabe..6c3ea675ff5c 100644 --- a/tests/run/instances.scala +++ b/tests/run/instances.scala @@ -4,7 +4,7 @@ object Test extends App { extension (x: Int) def em: Boolean = x > 0 } - assert(1.em == O.extension_em(1)) + assert(1.em == O.em(1)) case class Circle(x: Double, y: Double, radius: Double) @@ -13,7 +13,7 @@ object Test extends App { val circle = new Circle(1, 1, 2.0) - assert(circle.circumference == Test.extension_circumference(circle)) + assert(circle.circumference == Test.circumference(circle)) extension (xs: Seq[String]) def longestStrings: Seq[String] = @@ -113,7 +113,7 @@ object Test extends App { def mapAll[F[_]: Monad, T](x: T, fs: List[T => T]): F[T] = fs.foldLeft(summon[Monad[F]].pure(x))((x: F[T], f: T => T) => - if true then summon[Monad[F]].extension_map(x)(f) + if true then summon[Monad[F]].map(x)(f) else if true then x.map(f) else x.map[T, T](f) ) diff --git a/tests/semanticdb/expect/Enums.expect.scala b/tests/semanticdb/expect/Enums.expect.scala index d75883742758..1ad378177f9b 100644 --- a/tests/semanticdb/expect/Enums.expect.scala +++ b/tests/semanticdb/expect/Enums.expect.scala @@ -12,10 +12,10 @@ object Enums/*<-_empty_::Enums.*/: case Hearts/*<-_empty_::Enums.Suits.Hearts.*/, Spades/*<-_empty_::Enums.Suits.Spades.*/, Clubs/*<-_empty_::Enums.Suits.Clubs.*/, Diamonds/*<-_empty_::Enums.Suits.Diamonds.*/ object Suits/*<-_empty_::Enums.Suits.*/: - extension (suit/*<-_empty_::Enums.Suits.extension_isRed().(suit)*/: Suits/*->_empty_::Enums.Suits#*/) def isRed/*<-_empty_::Enums.Suits.extension_isRed().*/: Boolean/*->scala::Boolean#*/ = - suit/*->_empty_::Enums.Suits.extension_isRed().(suit)*/ ==/*->scala::Any#`==`().*/ Hearts/*->_empty_::Enums.Suits.Hearts.*/ ||/*->scala::Boolean#`||`().*/ suit/*->_empty_::Enums.Suits.extension_isRed().(suit)*/ ==/*->scala::Any#`==`().*/ Diamonds/*->_empty_::Enums.Suits.Diamonds.*/ + extension (suit/*<-_empty_::Enums.Suits.isRed().(suit)*/: Suits/*->_empty_::Enums.Suits#*/) def isRed/*<-_empty_::Enums.Suits.isRed().*/: Boolean/*->scala::Boolean#*/ = + suit/*->_empty_::Enums.Suits.isRed().(suit)*/ ==/*->scala::Any#`==`().*/ Hearts/*->_empty_::Enums.Suits.Hearts.*/ ||/*->scala::Boolean#`||`().*/ suit/*->_empty_::Enums.Suits.isRed().(suit)*/ ==/*->scala::Any#`==`().*/ Diamonds/*->_empty_::Enums.Suits.Diamonds.*/ - extension (suit/*<-_empty_::Enums.Suits.extension_isBlack().(suit)*/: Suits/*->_empty_::Enums.Suits#*/) def isBlack/*<-_empty_::Enums.Suits.extension_isBlack().*/: Boolean/*->scala::Boolean#*/ = suit/*->_empty_::Enums.Suits.extension_isBlack().(suit)*/ match + extension (suit/*<-_empty_::Enums.Suits.isBlack().(suit)*/: Suits/*->_empty_::Enums.Suits#*/) def isBlack/*<-_empty_::Enums.Suits.isBlack().*/: Boolean/*->scala::Boolean#*/ = suit/*->_empty_::Enums.Suits.isBlack().(suit)*/ match case Spades/*->_empty_::Enums.Suits.Spades.*/ | Clubs/*->_empty_::Enums.Suits.Clubs.*/ => true case _ => false @@ -49,10 +49,10 @@ object Enums/*<-_empty_::Enums.*/: object <:_empty_::Enums.`<:<`.given_T().[T]*/ <:_empty_::Enums.`<:<`#*/ T/*->_empty_::Enums.`<:<`.given_T().[T]*/) = Refl/*->_empty_::Enums.`<:<`.Refl.*//*->_empty_::Enums.`<:<`.Refl.apply().*/() - extension [A/*<-_empty_::Enums.extension_unwrap().[A]*/, B/*<-_empty_::Enums.extension_unwrap().[B]*/](opt/*<-_empty_::Enums.extension_unwrap().(opt)*/: Option/*->scala::Option#*/[A/*->_empty_::Enums.extension_unwrap().[A]*/]) def unwrap/*<-_empty_::Enums.extension_unwrap().*/(using ev/*<-_empty_::Enums.extension_unwrap().(ev)*/: A/*->_empty_::Enums.extension_unwrap().[A]*/ <:_empty_::Enums.`<:<`#*/ Option/*->scala::Option#*/[B/*->_empty_::Enums.extension_unwrap().[B]*/]): Option/*->scala::Option#*/[B/*->_empty_::Enums.extension_unwrap().[B]*/] = ev/*->_empty_::Enums.extension_unwrap().(ev)*/ match - case Refl/*->_empty_::Enums.`<:<`.Refl.*//*->_empty_::Enums.`<:<`.Refl.unapply().*/() => opt/*->_empty_::Enums.extension_unwrap().(opt)*/.flatMap/*->scala::Option#flatMap().*/(identity/*->scala::Predef.identity().*//*->local0*/[Option/*->scala::Option#*/[B/*->_empty_::Enums.extension_unwrap().[B]*/]]) + extension [A/*<-_empty_::Enums.unwrap().[A]*/, B/*<-_empty_::Enums.unwrap().[B]*/](opt/*<-_empty_::Enums.unwrap().(opt)*/: Option/*->scala::Option#*/[A/*->_empty_::Enums.unwrap().[A]*/]) def unwrap/*<-_empty_::Enums.unwrap().*/(using ev/*<-_empty_::Enums.unwrap().(ev)*/: A/*->_empty_::Enums.unwrap().[A]*/ <:_empty_::Enums.`<:<`#*/ Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/]): Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/] = ev/*->_empty_::Enums.unwrap().(ev)*/ match + case Refl/*->_empty_::Enums.`<:<`.Refl.*//*->_empty_::Enums.`<:<`.Refl.unapply().*/() => opt/*->_empty_::Enums.unwrap().(opt)*/.flatMap/*->scala::Option#flatMap().*/(identity/*->scala::Predef.identity().*//*->local0*/[Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/]]) - val some1/*<-_empty_::Enums.some1.*/ = /*->_empty_::Enums.extension_unwrap().*/Some/*->scala::Some.*//*->scala::Some.apply().*/(Some/*->scala::Some.*//*->scala::Some.apply().*/(1))/*->_empty_::Enums.`<:<`.given_T().*/.unwrap + val some1/*<-_empty_::Enums.some1.*/ = /*->_empty_::Enums.unwrap().*/Some/*->scala::Some.*//*->scala::Some.apply().*/(Some/*->scala::Some.*//*->scala::Some.apply().*/(1))/*->_empty_::Enums.`<:<`.given_T().*/.unwrap enum Planet/*<-_empty_::Enums.Planet#*/(mass/*<-_empty_::Enums.Planet#mass.*/: Double/*->scala::Double#*/, radius/*<-_empty_::Enums.Planet#radius.*/: Double/*->scala::Double#*/) extends java.lang.Enum/*->java::lang::Enum#*/[Planet/*->_empty_::Enums.Planet#*/]/*->java::lang::Enum#``().*/: private final val G/*<-_empty_::Enums.Planet#G.*/ = 6.67300E-11 diff --git a/tests/semanticdb/expect/Givens.expect.scala b/tests/semanticdb/expect/Givens.expect.scala index 9d43f162f2d3..b037af9da2ca 100644 --- a/tests/semanticdb/expect/Givens.expect.scala +++ b/tests/semanticdb/expect/Givens.expect.scala @@ -3,25 +3,25 @@ package b object Givens/*<-a::b::Givens.*/: - extension [A/*<-a::b::Givens.extension_sayHello().[A]*/](any/*<-a::b::Givens.extension_sayHello().(any)*/: A/*->a::b::Givens.extension_sayHello().[A]*/) - def sayHello/*<-a::b::Givens.extension_sayHello().*/ = s"/*->scala::StringContext.apply().*/Hello, I am $any/*->a::b::Givens.extension_sayHello().(any)*/"/*->scala::StringContext#s().*/ + extension [A/*<-a::b::Givens.sayHello().[A]*/](any/*<-a::b::Givens.sayHello().(any)*/: A/*->a::b::Givens.sayHello().[A]*/) + def sayHello/*<-a::b::Givens.sayHello().*/ = s"/*->scala::StringContext.apply().*/Hello, I am $any/*->a::b::Givens.sayHello().(any)*/"/*->scala::StringContext#s().*/ - extension [B/*<-a::b::Givens.extension_sayGoodbye().[B]*//*<-a::b::Givens.extension_saySoLong().[B]*/](any/*<-a::b::Givens.extension_sayGoodbye().(any)*//*<-a::b::Givens.extension_saySoLong().(any)*/: B/*->a::b::Givens.extension_sayGoodbye().[B]*//*->a::b::Givens.extension_saySoLong().[B]*/) - def sayGoodbye/*<-a::b::Givens.extension_sayGoodbye().*/ = s"/*->scala::StringContext.apply().*/Goodbye, from $any/*->a::b::Givens.extension_sayGoodbye().(any)*/"/*->scala::StringContext#s().*/ - def saySoLong/*<-a::b::Givens.extension_saySoLong().*/ = s"/*->scala::StringContext.apply().*/So Long, from $any/*->a::b::Givens.extension_saySoLong().(any)*/"/*->scala::StringContext#s().*/ + extension [B/*<-a::b::Givens.sayGoodbye().[B]*//*<-a::b::Givens.saySoLong().[B]*/](any/*<-a::b::Givens.sayGoodbye().(any)*//*<-a::b::Givens.saySoLong().(any)*/: B/*->a::b::Givens.sayGoodbye().[B]*//*->a::b::Givens.saySoLong().[B]*/) + def sayGoodbye/*<-a::b::Givens.sayGoodbye().*/ = s"/*->scala::StringContext.apply().*/Goodbye, from $any/*->a::b::Givens.sayGoodbye().(any)*/"/*->scala::StringContext#s().*/ + def saySoLong/*<-a::b::Givens.saySoLong().*/ = s"/*->scala::StringContext.apply().*/So Long, from $any/*->a::b::Givens.saySoLong().(any)*/"/*->scala::StringContext#s().*/ - val hello1/*<-a::b::Givens.hello1.*/ = /*->a::b::Givens.extension_sayHello().*/1.sayHello - val goodbye1/*<-a::b::Givens.goodbye1.*/ = /*->a::b::Givens.extension_sayGoodbye().*/1.sayGoodbye - val soLong1/*<-a::b::Givens.soLong1.*/ = /*->a::b::Givens.extension_saySoLong().*/1.saySoLong + val hello1/*<-a::b::Givens.hello1.*/ = /*->a::b::Givens.sayHello().*/1.sayHello + val goodbye1/*<-a::b::Givens.goodbye1.*/ = /*->a::b::Givens.sayGoodbye().*/1.sayGoodbye + val soLong1/*<-a::b::Givens.soLong1.*/ = /*->a::b::Givens.saySoLong().*/1.saySoLong trait Monoid/*<-a::b::Givens.Monoid#*/[A/*<-a::b::Givens.Monoid#[A]*/]: def empty/*<-a::b::Givens.Monoid#empty().*/: A/*->a::b::Givens.Monoid#[A]*/ - extension (x/*<-a::b::Givens.Monoid#extension_combine().(x)*/: A/*->a::b::Givens.Monoid#[A]*/) def combine/*<-a::b::Givens.Monoid#extension_combine().*/(y/*<-a::b::Givens.Monoid#extension_combine().(y)*/: A/*->a::b::Givens.Monoid#[A]*/): A/*->a::b::Givens.Monoid#[A]*/ + extension (x/*<-a::b::Givens.Monoid#combine().(x)*/: A/*->a::b::Givens.Monoid#[A]*/) def combine/*<-a::b::Givens.Monoid#combine().*/(y/*<-a::b::Givens.Monoid#combine().(y)*/: A/*->a::b::Givens.Monoid#[A]*/): A/*->a::b::Givens.Monoid#[A]*/ given Monoid[String]: /*<-a::b::Givens.given_Monoid_String.*//*->a::b::Givens.Monoid#*//*->scala::Predef.String#*/ def empty/*<-a::b::Givens.given_Monoid_String.empty().*/ = "" - extension (x/*<-a::b::Givens.given_Monoid_String.extension_combine().(x)*/: String/*->scala::Predef.String#*/) def combine/*<-a::b::Givens.given_Monoid_String.extension_combine().*/(y/*<-a::b::Givens.given_Monoid_String.extension_combine().(y)*/: String/*->scala::Predef.String#*/) = x/*->a::b::Givens.given_Monoid_String.extension_combine().(x)*/ +/*->java::lang::String#`+`().*/ y/*->a::b::Givens.given_Monoid_String.extension_combine().(y)*/ + extension (x/*<-a::b::Givens.given_Monoid_String.combine().(x)*/: String/*->scala::Predef.String#*/) def combine/*<-a::b::Givens.given_Monoid_String.combine().*/(y/*<-a::b::Givens.given_Monoid_String.combine().(y)*/: String/*->scala::Predef.String#*/) = x/*->a::b::Givens.given_Monoid_String.combine().(x)*/ +/*->java::lang::String#`+`().*/ y/*->a::b::Givens.given_Monoid_String.combine().(y)*/ inline given int2String/*<-a::b::Givens.int2String().*/ as Conversion/*->scala::Conversion#*/[Int/*->scala::Int#*/, String/*->scala::Predef.String#*/] = _.toString/*->scala::Any#toString().*/ - def foo/*<-a::b::Givens.foo().*/[A/*<-a::b::Givens.foo().[A]*/](using A/*<-a::b::Givens.foo().(A)*/: Monoid/*->a::b::Givens.Monoid#*/[A/*->a::b::Givens.foo().[A]*/]): A/*->a::b::Givens.foo().[A]*/ = A/*->a::b::Givens.foo().(A)*/.extension_combine/*->a::b::Givens.Monoid#extension_combine().*/(A/*->a::b::Givens.foo().(A)*/.empty/*->a::b::Givens.Monoid#empty().*/)(A/*->a::b::Givens.foo().(A)*/.empty/*->a::b::Givens.Monoid#empty().*/) + def foo/*<-a::b::Givens.foo().*/[A/*<-a::b::Givens.foo().[A]*/](using A/*<-a::b::Givens.foo().(A)*/: Monoid/*->a::b::Givens.Monoid#*/[A/*->a::b::Givens.foo().[A]*/]): A/*->a::b::Givens.foo().[A]*/ = A/*->a::b::Givens.foo().(A)*/.combine/*->a::b::Givens.Monoid#combine().*/(A/*->a::b::Givens.foo().(A)*/.empty/*->a::b::Givens.Monoid#empty().*/)(A/*->a::b::Givens.foo().(A)*/.empty/*->a::b::Givens.Monoid#empty().*/) diff --git a/tests/semanticdb/expect/Givens.scala b/tests/semanticdb/expect/Givens.scala index 2f6add1e12e1..be219b361924 100644 --- a/tests/semanticdb/expect/Givens.scala +++ b/tests/semanticdb/expect/Givens.scala @@ -24,4 +24,4 @@ object Givens: inline given int2String as Conversion[Int, String] = _.toString - def foo[A](using A: Monoid[A]): A = A.extension_combine(A.empty)(A.empty) + def foo[A](using A: Monoid[A]): A = A.combine(A.empty)(A.empty) diff --git a/tests/semanticdb/expect/toplevel.expect.scala b/tests/semanticdb/expect/toplevel.expect.scala index ea8daac5008f..a856d673e68c 100644 --- a/tests/semanticdb/expect/toplevel.expect.scala +++ b/tests/semanticdb/expect/toplevel.expect.scala @@ -1,6 +1,6 @@ /*<-_empty_::toplevel$package.*/inline val a/*<-_empty_::toplevel$package.a.*/ = "" -extension (x/*<-_empty_::toplevel$package.extension_combine().(x)*/: Int/*->scala::Int#*/) def combine/*<-_empty_::toplevel$package.extension_combine().*/ (y/*<-_empty_::toplevel$package.extension_combine().(y)*/: Int/*->scala::Int#*/) = x/*->_empty_::toplevel$package.extension_combine().(x)*/ +/*->scala::Int#`+`(+4).*/ y/*->_empty_::toplevel$package.extension_combine().(y)*/ -def combine/*<-_empty_::toplevel$package.combine().*/(x/*<-_empty_::toplevel$package.combine().(x)*/: Int/*->scala::Int#*/, y/*<-_empty_::toplevel$package.combine().(y)*/: Int/*->scala::Int#*/, z/*<-_empty_::toplevel$package.combine().(z)*/: Int/*->scala::Int#*/) = x/*->_empty_::toplevel$package.combine().(x)*/ +/*->scala::Int#`+`(+4).*/ y/*->_empty_::toplevel$package.combine().(y)*/ +/*->scala::Int#`+`(+4).*/ z/*->_empty_::toplevel$package.combine().(z)*/ -def combine/*<-_empty_::toplevel$package.combine(+1).*/ = 0 +extension (x/*<-_empty_::toplevel$package.combine().(x)*/: Int/*->scala::Int#*/) def combine/*<-_empty_::toplevel$package.combine().*/ (y/*<-_empty_::toplevel$package.combine().(y)*/: Int/*->scala::Int#*/) = x/*->_empty_::toplevel$package.combine().(x)*/ +/*->scala::Int#`+`(+4).*/ y/*->_empty_::toplevel$package.combine().(y)*/ +def combine/*<-_empty_::toplevel$package.combine(+1).*/(x/*<-_empty_::toplevel$package.combine(+1).(x)*/: Int/*->scala::Int#*/, y/*<-_empty_::toplevel$package.combine(+1).(y)*/: Int/*->scala::Int#*/, z/*<-_empty_::toplevel$package.combine(+1).(z)*/: Int/*->scala::Int#*/) = x/*->_empty_::toplevel$package.combine(+1).(x)*/ +/*->scala::Int#`+`(+4).*/ y/*->_empty_::toplevel$package.combine(+1).(y)*/ +/*->scala::Int#`+`(+4).*/ z/*->_empty_::toplevel$package.combine(+1).(z)*/ +def combine/*<-_empty_::toplevel$package.combine(+2).*/ = 0 def foo/*<-_empty_::toplevel$package.foo().*/ = "foo" /*<-_empty_::MyProgram#*//*->_empty_::toplevel$package.MyProgram().*//*->scala::util::CommandLineParser.parseArgument().*//*->_empty_::MyProgram#main().(args)*//*->scala::util::CommandLineParser.FromString.given_FromString_Int.*//*->scala::util::CommandLineParser.showError().*//*->local0*/@main/*->scala::main#*/ def MyProgram/*<-_empty_::toplevel$package.MyProgram().*/(times/*<-_empty_::toplevel$package.MyProgram().(times)*/: Int/*->scala::Int#*/): Unit/*->scala::Unit#*/ = (/*->scala::LowPriorityImplicits#intWrapper().*/1 to/*->scala::runtime::RichInt#to().*/ times/*->_empty_::toplevel$package.MyProgram().(times)*/) foreach/*->scala::collection::immutable::Range#foreach().*/ (_ => println/*->scala::Predef.println(+1).*/("hello")) diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 44b24919b9c2..a2021ced9e36 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -757,12 +757,12 @@ _empty_/Enums.Suits.Diamonds. => case val static enum method Diamonds _empty_/Enums.Suits.Hearts. => case val static enum method Hearts _empty_/Enums.Suits.Spades. => case val static enum method Spades _empty_/Enums.Suits.derived$Eql(). => implicit method derived$Eql -_empty_/Enums.Suits.extension_isBlack(). => method extension_isBlack -_empty_/Enums.Suits.extension_isBlack().(suit) => param suit -_empty_/Enums.Suits.extension_isRed(). => method extension_isRed -_empty_/Enums.Suits.extension_isRed().(suit) => param suit _empty_/Enums.Suits.fromOrdinal(). => method fromOrdinal _empty_/Enums.Suits.fromOrdinal().(ordinal) => param ordinal +_empty_/Enums.Suits.isBlack(). => method isBlack +_empty_/Enums.Suits.isBlack().(suit) => param suit +_empty_/Enums.Suits.isRed(). => method isRed +_empty_/Enums.Suits.isRed().(suit) => param suit _empty_/Enums.Suits.valueOf(). => method valueOf _empty_/Enums.Suits.valueOf().($name) => param $name _empty_/Enums.Suits.values(). => method values @@ -819,12 +819,12 @@ _empty_/Enums.`<:<`.fromOrdinal(). => method fromOrdinal _empty_/Enums.`<:<`.fromOrdinal().(ordinal) => param ordinal _empty_/Enums.`<:<`.given_T(). => final implicit method given_T _empty_/Enums.`<:<`.given_T().[T] => typeparam T -_empty_/Enums.extension_unwrap(). => method extension_unwrap -_empty_/Enums.extension_unwrap().(ev) => implicit param ev -_empty_/Enums.extension_unwrap().(opt) => param opt -_empty_/Enums.extension_unwrap().[A] => typeparam A -_empty_/Enums.extension_unwrap().[B] => typeparam B _empty_/Enums.some1. => val method some1 +_empty_/Enums.unwrap(). => method unwrap +_empty_/Enums.unwrap().(ev) => implicit param ev +_empty_/Enums.unwrap().(opt) => param opt +_empty_/Enums.unwrap().[A] => typeparam A +_empty_/Enums.unwrap().[B] => typeparam B local0 => param x Occurrences: @@ -851,22 +851,22 @@ Occurrences: [11:25..11:30): Clubs <- _empty_/Enums.Suits.Clubs. [11:32..11:40): Diamonds <- _empty_/Enums.Suits.Diamonds. [13:9..13:14): Suits <- _empty_/Enums.Suits. -[14:15..14:19): suit <- _empty_/Enums.Suits.extension_isRed().(suit) +[14:15..14:19): suit <- _empty_/Enums.Suits.isRed().(suit) [14:21..14:26): Suits -> _empty_/Enums.Suits# -[14:32..14:37): isRed <- _empty_/Enums.Suits.extension_isRed(). +[14:32..14:37): isRed <- _empty_/Enums.Suits.isRed(). [14:39..14:46): Boolean -> scala/Boolean# -[15:6..15:10): suit -> _empty_/Enums.Suits.extension_isRed().(suit) +[15:6..15:10): suit -> _empty_/Enums.Suits.isRed().(suit) [15:11..15:13): == -> scala/Any#`==`(). [15:14..15:20): Hearts -> _empty_/Enums.Suits.Hearts. [15:21..15:23): || -> scala/Boolean#`||`(). -[15:24..15:28): suit -> _empty_/Enums.Suits.extension_isRed().(suit) +[15:24..15:28): suit -> _empty_/Enums.Suits.isRed().(suit) [15:29..15:31): == -> scala/Any#`==`(). [15:32..15:40): Diamonds -> _empty_/Enums.Suits.Diamonds. -[17:15..17:19): suit <- _empty_/Enums.Suits.extension_isBlack().(suit) +[17:15..17:19): suit <- _empty_/Enums.Suits.isBlack().(suit) [17:21..17:26): Suits -> _empty_/Enums.Suits# -[17:32..17:39): isBlack <- _empty_/Enums.Suits.extension_isBlack(). +[17:32..17:39): isBlack <- _empty_/Enums.Suits.isBlack(). [17:41..17:48): Boolean -> scala/Boolean# -[17:51..17:55): suit -> _empty_/Enums.Suits.extension_isBlack().(suit) +[17:51..17:55): suit -> _empty_/Enums.Suits.isBlack().(suit) [18:11..18:17): Spades -> _empty_/Enums.Suits.Spades. [18:20..18:25): Clubs -> _empty_/Enums.Suits.Clubs. [21:7..21:15): WeekDays <- _empty_/Enums.WeekDays# @@ -944,30 +944,30 @@ Occurrences: [49:24..49:25): T -> _empty_/Enums.`<:<`.given_T().[T] [49:29..49:33): Refl -> _empty_/Enums.`<:<`.Refl. [49:33..49:33): -> _empty_/Enums.`<:<`.Refl.apply(). -[51:13..51:14): A <- _empty_/Enums.extension_unwrap().[A] -[51:16..51:17): B <- _empty_/Enums.extension_unwrap().[B] -[51:19..51:22): opt <- _empty_/Enums.extension_unwrap().(opt) +[51:13..51:14): A <- _empty_/Enums.unwrap().[A] +[51:16..51:17): B <- _empty_/Enums.unwrap().[B] +[51:19..51:22): opt <- _empty_/Enums.unwrap().(opt) [51:24..51:30): Option -> scala/Option# -[51:31..51:32): A -> _empty_/Enums.extension_unwrap().[A] -[51:39..51:45): unwrap <- _empty_/Enums.extension_unwrap(). -[51:52..51:54): ev <- _empty_/Enums.extension_unwrap().(ev) -[51:56..51:57): A -> _empty_/Enums.extension_unwrap().[A] +[51:31..51:32): A -> _empty_/Enums.unwrap().[A] +[51:39..51:45): unwrap <- _empty_/Enums.unwrap(). +[51:52..51:54): ev <- _empty_/Enums.unwrap().(ev) +[51:56..51:57): A -> _empty_/Enums.unwrap().[A] [51:58..51:61): <:< -> _empty_/Enums.`<:<`# [51:62..51:68): Option -> scala/Option# -[51:69..51:70): B -> _empty_/Enums.extension_unwrap().[B] +[51:69..51:70): B -> _empty_/Enums.unwrap().[B] [51:74..51:80): Option -> scala/Option# -[51:81..51:82): B -> _empty_/Enums.extension_unwrap().[B] -[51:86..51:88): ev -> _empty_/Enums.extension_unwrap().(ev) +[51:81..51:82): B -> _empty_/Enums.unwrap().[B] +[51:86..51:88): ev -> _empty_/Enums.unwrap().(ev) [52:9..52:13): Refl -> _empty_/Enums.`<:<`.Refl. [52:13..52:13): -> _empty_/Enums.`<:<`.Refl.unapply(). -[52:19..52:22): opt -> _empty_/Enums.extension_unwrap().(opt) +[52:19..52:22): opt -> _empty_/Enums.unwrap().(opt) [52:23..52:30): flatMap -> scala/Option#flatMap(). [52:31..52:39): identity -> scala/Predef.identity(). [52:31..52:31): -> local0 [52:40..52:46): Option -> scala/Option# -[52:47..52:48): B -> _empty_/Enums.extension_unwrap().[B] +[52:47..52:48): B -> _empty_/Enums.unwrap().[B] [54:6..54:11): some1 <- _empty_/Enums.some1. -[54:14..54:14): -> _empty_/Enums.extension_unwrap(). +[54:14..54:14): -> _empty_/Enums.unwrap(). [54:14..54:18): Some -> scala/Some. [54:18..54:18): -> scala/Some.apply(). [54:19..54:23): Some -> scala/Some. @@ -1239,86 +1239,86 @@ a/b/Givens. => final object Givens a/b/Givens.Monoid# => trait Monoid a/b/Givens.Monoid#[A] => typeparam A a/b/Givens.Monoid#``(). => primary ctor +a/b/Givens.Monoid#combine(). => abstract method combine +a/b/Givens.Monoid#combine().(x) => param x +a/b/Givens.Monoid#combine().(y) => param y a/b/Givens.Monoid#empty(). => abstract method empty -a/b/Givens.Monoid#extension_combine(). => abstract method extension_combine -a/b/Givens.Monoid#extension_combine().(x) => param x -a/b/Givens.Monoid#extension_combine().(y) => param y -a/b/Givens.extension_sayGoodbye(). => method extension_sayGoodbye -a/b/Givens.extension_sayGoodbye().(any) => param any -a/b/Givens.extension_sayGoodbye().[B] => typeparam B -a/b/Givens.extension_sayHello(). => method extension_sayHello -a/b/Givens.extension_sayHello().(any) => param any -a/b/Givens.extension_sayHello().[A] => typeparam A -a/b/Givens.extension_saySoLong(). => method extension_saySoLong -a/b/Givens.extension_saySoLong().(any) => param any -a/b/Givens.extension_saySoLong().[B] => typeparam B a/b/Givens.foo(). => method foo a/b/Givens.foo().(A) => implicit param A a/b/Givens.foo().[A] => typeparam A a/b/Givens.given_Monoid_String. => final implicit object given_Monoid_String +a/b/Givens.given_Monoid_String.combine(). => method combine +a/b/Givens.given_Monoid_String.combine().(x) => param x +a/b/Givens.given_Monoid_String.combine().(y) => param y a/b/Givens.given_Monoid_String.empty(). => method empty -a/b/Givens.given_Monoid_String.extension_combine(). => method extension_combine -a/b/Givens.given_Monoid_String.extension_combine().(x) => param x -a/b/Givens.given_Monoid_String.extension_combine().(y) => param y a/b/Givens.goodbye1. => val method goodbye1 a/b/Givens.hello1. => val method hello1 a/b/Givens.int2String(). => final implicit macro int2String +a/b/Givens.sayGoodbye(). => method sayGoodbye +a/b/Givens.sayGoodbye().(any) => param any +a/b/Givens.sayGoodbye().[B] => typeparam B +a/b/Givens.sayHello(). => method sayHello +a/b/Givens.sayHello().(any) => param any +a/b/Givens.sayHello().[A] => typeparam A +a/b/Givens.saySoLong(). => method saySoLong +a/b/Givens.saySoLong().(any) => param any +a/b/Givens.saySoLong().[B] => typeparam B a/b/Givens.soLong1. => val method soLong1 Occurrences: [0:8..0:9): a <- a/ [1:8..1:9): b <- a/b/ [3:7..3:13): Givens <- a/b/Givens. -[5:13..5:14): A <- a/b/Givens.extension_sayHello().[A] -[5:16..5:19): any <- a/b/Givens.extension_sayHello().(any) -[5:21..5:22): A -> a/b/Givens.extension_sayHello().[A] -[6:8..6:16): sayHello <- a/b/Givens.extension_sayHello(). +[5:13..5:14): A <- a/b/Givens.sayHello().[A] +[5:16..5:19): any <- a/b/Givens.sayHello().(any) +[5:21..5:22): A -> a/b/Givens.sayHello().[A] +[6:8..6:16): sayHello <- a/b/Givens.sayHello(). [6:21..6:21): -> scala/StringContext.apply(). -[6:34..6:37): any -> a/b/Givens.extension_sayHello().(any) +[6:34..6:37): any -> a/b/Givens.sayHello().(any) [6:37..6:38): " -> scala/StringContext#s(). -[8:13..8:14): B <- a/b/Givens.extension_sayGoodbye().[B] -[8:13..8:14): B <- a/b/Givens.extension_saySoLong().[B] -[8:16..8:19): any <- a/b/Givens.extension_sayGoodbye().(any) -[8:16..8:19): any <- a/b/Givens.extension_saySoLong().(any) -[8:21..8:22): B -> a/b/Givens.extension_sayGoodbye().[B] -[8:21..8:22): B -> a/b/Givens.extension_saySoLong().[B] -[9:8..9:18): sayGoodbye <- a/b/Givens.extension_sayGoodbye(). +[8:13..8:14): B <- a/b/Givens.sayGoodbye().[B] +[8:13..8:14): B <- a/b/Givens.saySoLong().[B] +[8:16..8:19): any <- a/b/Givens.sayGoodbye().(any) +[8:16..8:19): any <- a/b/Givens.saySoLong().(any) +[8:21..8:22): B -> a/b/Givens.sayGoodbye().[B] +[8:21..8:22): B -> a/b/Givens.saySoLong().[B] +[9:8..9:18): sayGoodbye <- a/b/Givens.sayGoodbye(). [9:23..9:23): -> scala/StringContext.apply(). -[9:38..9:41): any -> a/b/Givens.extension_sayGoodbye().(any) +[9:38..9:41): any -> a/b/Givens.sayGoodbye().(any) [9:41..9:42): " -> scala/StringContext#s(). -[10:8..10:17): saySoLong <- a/b/Givens.extension_saySoLong(). +[10:8..10:17): saySoLong <- a/b/Givens.saySoLong(). [10:22..10:22): -> scala/StringContext.apply(). -[10:37..10:40): any -> a/b/Givens.extension_saySoLong().(any) +[10:37..10:40): any -> a/b/Givens.saySoLong().(any) [10:40..10:41): " -> scala/StringContext#s(). [12:6..12:12): hello1 <- a/b/Givens.hello1. -[12:15..12:15): -> a/b/Givens.extension_sayHello(). +[12:15..12:15): -> a/b/Givens.sayHello(). [13:6..13:14): goodbye1 <- a/b/Givens.goodbye1. -[13:17..13:17): -> a/b/Givens.extension_sayGoodbye(). +[13:17..13:17): -> a/b/Givens.sayGoodbye(). [14:6..14:13): soLong1 <- a/b/Givens.soLong1. -[14:16..14:16): -> a/b/Givens.extension_saySoLong(). +[14:16..14:16): -> a/b/Givens.saySoLong(). [16:8..16:14): Monoid <- a/b/Givens.Monoid# [16:14..16:14): <- a/b/Givens.Monoid#``(). [16:15..16:16): A <- a/b/Givens.Monoid#[A] [17:8..17:13): empty <- a/b/Givens.Monoid#empty(). [17:15..17:16): A -> a/b/Givens.Monoid#[A] -[18:15..18:16): x <- a/b/Givens.Monoid#extension_combine().(x) +[18:15..18:16): x <- a/b/Givens.Monoid#combine().(x) [18:18..18:19): A -> a/b/Givens.Monoid#[A] -[18:25..18:32): combine <- a/b/Givens.Monoid#extension_combine(). -[18:33..18:34): y <- a/b/Givens.Monoid#extension_combine().(y) +[18:25..18:32): combine <- a/b/Givens.Monoid#combine(). +[18:33..18:34): y <- a/b/Givens.Monoid#combine().(y) [18:36..18:37): A -> a/b/Givens.Monoid#[A] [18:40..18:41): A -> a/b/Givens.Monoid#[A] [20:8..21:3): <- a/b/Givens.given_Monoid_String. [20:8..20:14): Monoid -> a/b/Givens.Monoid# [20:15..20:21): String -> scala/Predef.String# [21:8..21:13): empty <- a/b/Givens.given_Monoid_String.empty(). -[22:15..22:16): x <- a/b/Givens.given_Monoid_String.extension_combine().(x) +[22:15..22:16): x <- a/b/Givens.given_Monoid_String.combine().(x) [22:18..22:24): String -> scala/Predef.String# -[22:30..22:37): combine <- a/b/Givens.given_Monoid_String.extension_combine(). -[22:38..22:39): y <- a/b/Givens.given_Monoid_String.extension_combine().(y) +[22:30..22:37): combine <- a/b/Givens.given_Monoid_String.combine(). +[22:38..22:39): y <- a/b/Givens.given_Monoid_String.combine().(y) [22:41..22:47): String -> scala/Predef.String# -[22:51..22:52): x -> a/b/Givens.given_Monoid_String.extension_combine().(x) +[22:51..22:52): x -> a/b/Givens.given_Monoid_String.combine().(x) [22:53..22:54): + -> java/lang/String#`+`(). -[22:55..22:56): y -> a/b/Givens.given_Monoid_String.extension_combine().(y) +[22:55..22:56): y -> a/b/Givens.given_Monoid_String.combine().(y) [24:15..24:25): int2String <- a/b/Givens.int2String(). [24:29..24:39): Conversion -> scala/Conversion# [24:40..24:43): Int -> scala/Int# @@ -1331,11 +1331,11 @@ Occurrences: [26:29..26:30): A -> a/b/Givens.foo().[A] [26:34..26:35): A -> a/b/Givens.foo().[A] [26:38..26:39): A -> a/b/Givens.foo().(A) -[26:40..26:57): extension_combine -> a/b/Givens.Monoid#extension_combine(). -[26:58..26:59): A -> a/b/Givens.foo().(A) -[26:60..26:65): empty -> a/b/Givens.Monoid#empty(). -[26:67..26:68): A -> a/b/Givens.foo().(A) -[26:69..26:74): empty -> a/b/Givens.Monoid#empty(). +[26:40..26:47): combine -> a/b/Givens.Monoid#combine(). +[26:48..26:49): A -> a/b/Givens.foo().(A) +[26:50..26:55): empty -> a/b/Givens.Monoid#empty(). +[26:57..26:58): A -> a/b/Givens.foo().(A) +[26:59..26:64): empty -> a/b/Givens.Monoid#empty(). expect/ImplicitConversion.scala ------------------------------- @@ -3935,38 +3935,38 @@ _empty_/toplevel$package.a. => val method a _empty_/toplevel$package.combine(). => method combine _empty_/toplevel$package.combine().(x) => param x _empty_/toplevel$package.combine().(y) => param y -_empty_/toplevel$package.combine().(z) => param z _empty_/toplevel$package.combine(+1). => method combine -_empty_/toplevel$package.extension_combine(). => method extension_combine -_empty_/toplevel$package.extension_combine().(x) => param x -_empty_/toplevel$package.extension_combine().(y) => param y +_empty_/toplevel$package.combine(+1).(x) => param x +_empty_/toplevel$package.combine(+1).(y) => param y +_empty_/toplevel$package.combine(+1).(z) => param z +_empty_/toplevel$package.combine(+2). => method combine _empty_/toplevel$package.foo(). => method foo local0 => val local error Occurrences: [0:0..0:0): <- _empty_/toplevel$package. [0:11..0:12): a <- _empty_/toplevel$package.a. -[1:11..1:12): x <- _empty_/toplevel$package.extension_combine().(x) +[1:11..1:12): x <- _empty_/toplevel$package.combine().(x) [1:14..1:17): Int -> scala/Int# -[1:23..1:30): combine <- _empty_/toplevel$package.extension_combine(). -[1:32..1:33): y <- _empty_/toplevel$package.extension_combine().(y) +[1:23..1:30): combine <- _empty_/toplevel$package.combine(). +[1:32..1:33): y <- _empty_/toplevel$package.combine().(y) [1:35..1:38): Int -> scala/Int# -[1:42..1:43): x -> _empty_/toplevel$package.extension_combine().(x) +[1:42..1:43): x -> _empty_/toplevel$package.combine().(x) [1:44..1:45): + -> scala/Int#`+`(+4). -[1:46..1:47): y -> _empty_/toplevel$package.extension_combine().(y) -[2:4..2:11): combine <- _empty_/toplevel$package.combine(). -[2:12..2:13): x <- _empty_/toplevel$package.combine().(x) +[1:46..1:47): y -> _empty_/toplevel$package.combine().(y) +[2:4..2:11): combine <- _empty_/toplevel$package.combine(+1). +[2:12..2:13): x <- _empty_/toplevel$package.combine(+1).(x) [2:15..2:18): Int -> scala/Int# -[2:20..2:21): y <- _empty_/toplevel$package.combine().(y) +[2:20..2:21): y <- _empty_/toplevel$package.combine(+1).(y) [2:23..2:26): Int -> scala/Int# -[2:28..2:29): z <- _empty_/toplevel$package.combine().(z) +[2:28..2:29): z <- _empty_/toplevel$package.combine(+1).(z) [2:31..2:34): Int -> scala/Int# -[2:38..2:39): x -> _empty_/toplevel$package.combine().(x) +[2:38..2:39): x -> _empty_/toplevel$package.combine(+1).(x) [2:40..2:41): + -> scala/Int#`+`(+4). -[2:42..2:43): y -> _empty_/toplevel$package.combine().(y) +[2:42..2:43): y -> _empty_/toplevel$package.combine(+1).(y) [2:44..2:45): + -> scala/Int#`+`(+4). -[2:46..2:47): z -> _empty_/toplevel$package.combine().(z) -[3:4..3:11): combine <- _empty_/toplevel$package.combine(+1). +[2:46..2:47): z -> _empty_/toplevel$package.combine(+1).(z) +[3:4..3:11): combine <- _empty_/toplevel$package.combine(+2). [4:4..4:7): foo <- _empty_/toplevel$package.foo(). [5:0..5:0): <- _empty_/MyProgram# [5:0..5:0): <- _empty_/MyProgram#``().