diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 057a93196154..8fd06ddc3933 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -783,7 +783,7 @@ object desugar { DefDef( className.toTermName, joinParams(constrTparams, defParamss), classTypeRef, creatorExpr) - .withMods(companionMods | mods.flags.toTermFlags & GivenOrImplicit | Synthetic | Final) + .withMods(companionMods | mods.flags.toTermFlags & GivenOrImplicit | Final) .withSpan(cdef.span) :: Nil } @@ -809,7 +809,7 @@ object desugar { Nil } } - val classMods = if mods.is(Given) then mods &~ Given | Synthetic else mods + val classMods = if mods.is(Given) then mods | Synthetic else mods cpy.TypeDef(cdef: TypeDef)( name = className, rhs = cpy.Template(impl)(constr, parents1, clsDerived, self1, diff --git a/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala b/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala index 9e5b7f036aa0..359f5d5c2580 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala @@ -63,7 +63,7 @@ class TreeMapWithImplicits extends tpd.TreeMap { private def nestedScopeCtx(defs: List[Tree])(using Context): Context = { val nestedCtx = ctx.fresh.setNewScope defs foreach { - case d: DefTree if d.symbol.isOneOf(GivenOrImplicit) => nestedCtx.enter(d.symbol) + case d: DefTree if d.symbol.isOneOf(GivenOrImplicitVal) => nestedCtx.enter(d.symbol) case _ => } nestedCtx @@ -74,7 +74,7 @@ class TreeMapWithImplicits extends tpd.TreeMap { new TreeTraverser { def traverse(tree: Tree)(using Context): Unit = { tree match { - case d: DefTree if d.symbol.isOneOf(GivenOrImplicit) => + case d: DefTree if d.symbol.isOneOf(GivenOrImplicitVal) => nestedCtx.enter(d.symbol) case _ => } diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index 3c5adcba3aec..0b1646e23620 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -13,7 +13,6 @@ import Scopes._ import Uniques._ import ast.Trees._ import ast.untpd -import Flags.GivenOrImplicit import util.{NoSource, SimpleIdentityMap, SourceFile, HashSet, ReusableInstance} import typer.{Implicits, ImportInfo, Inliner, SearchHistory, SearchRoot, TypeAssigner, Typer, Nullables} import Nullables._ diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 890a0763938e..cb590e2384a0 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -233,7 +233,7 @@ object Flags { val (Param @ _, TermParam @ _, TypeParam @ _) = newFlags(8, "") /** Labeled with `implicit` modifier (implicit value) */ - val (Implicit @ _, ImplicitTerm @ _, _) = newFlags(9, "implicit") + val (Implicit @ _, ImplicitVal @ _, _) = newFlags(9, "implicit") /** Labeled with `lazy` (a lazy val) / a trait */ val (LazyOrTrait @ _, Lazy @ _, Trait @ _) = newFlags(10, "lazy", "") @@ -321,7 +321,7 @@ object Flags { val (Extension @ _, ExtensionMethod @ _, _) = newFlags(28, "") /** An inferable (`given`) parameter */ - val (Given @ _, _, _) = newFlags(29, "given") + val (Given @ _, GivenVal @ _, _) = newFlags(29, "given") /** Symbol is defined by a Java class */ val (JavaDefined @ _, JavaDefinedVal @ _, _) = newFlags(30, "") @@ -568,6 +568,7 @@ object Flags { val FinalOrSealed: FlagSet = Final | Sealed val GivenOrImplicit: FlagSet = Given | Implicit val GivenOrImplicitVal: FlagSet = GivenOrImplicit.toTermFlags + val GivenMethod: FlagSet = Given | Method val InlineOrProxy: FlagSet = Inline | InlineProxy // An inline method or inline argument proxy */ val InlineMethod: FlagSet = Inline | Method val InlineParam: FlagSet = Inline | Param @@ -600,7 +601,6 @@ object Flags { val Scala2Trait: FlagSet = Scala2x | Trait val SyntheticArtifact: FlagSet = Synthetic | Artifact val SyntheticCase: FlagSet = Synthetic | Case - val SyntheticGivenMethod: FlagSet = Synthetic | Given | Method val SyntheticModule: FlagSet = Synthetic | Module val SyntheticOpaque: FlagSet = Synthetic | Opaque val SyntheticParam: FlagSet = Synthetic | Param diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala index b22ce84849c1..5dc7ce168c24 100644 --- a/compiler/src/dotty/tools/dotc/core/Scopes.scala +++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala @@ -411,7 +411,7 @@ object Scopes { var irefs = new mutable.ListBuffer[TermRef] var e = lastEntry while (e ne null) { - if (e.sym.isOneOf(GivenOrImplicit)) { + if (e.sym.isOneOf(GivenOrImplicitVal)) { val d = e.sym.denot irefs += TermRef(NoPrefix, d.symbol.asTerm).withDenot(d) } diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index a7d45abd7a41..fcfbba208eb9 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -711,6 +711,19 @@ object SymDenotations { } ) + /** Do this symbol and `cls` represent a pair of a given or implicit method and + * its associated class that were defined by a single definition? + * This can mean one of two things: + * - the method and class are defined in a structural given instance, or + * - the class is an implicit class and the method is its implicit conversion. + */ + final def isCoDefinedGiven(cls: Symbol)(using Context): Boolean = + is(Method) && isOneOf(GivenOrImplicit) + && ( is(Synthetic) // previous scheme used in 3.0 + || cls.isOneOf(GivenOrImplicit) // new scheme from 3.1 + ) + && name == cls.name.toTermName && owner == cls.owner + /** Is this a denotation of a stable term (or an arbitrary type)? * Terms are stable if they are idempotent (as in TreeInfo.Idempotent): that is, they always return the same value, * if any. @@ -2231,7 +2244,7 @@ object SymDenotations { if (keepOnly eq implicitFilter) if (this.is(Package)) Iterator.empty // implicits in package objects are added by the overriding `memberNames` in `PackageClassDenotation` - else info.decls.iterator.filter(_.isOneOf(GivenOrImplicit)) + else info.decls.iterator.filter(_.isOneOf(GivenOrImplicitVal)) else info.decls.iterator for (sym <- ownSyms) maybeAdd(sym.name) names diff --git a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala index 950963497fbc..c9ca98f65f5e 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala @@ -141,7 +141,7 @@ class CyclicReference private (val denot: SymDenotation) extends TypeError { } // Give up and give generic errors. - else if (cycleSym.isOneOf(GivenOrImplicit, butNot = Method) && cycleSym.owner.isTerm) + else if (cycleSym.isOneOf(GivenOrImplicitVal, butNot = Method) && cycleSym.owner.isTerm) CyclicReferenceInvolvingImplicit(cycleSym) else CyclicReferenceInvolving(denot) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 59047c22403d..18db42f9e276 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -722,9 +722,9 @@ class TreePickler(pickler: TastyPickler) { if flags.is(Invisible) then writeModTag(INVISIBLE) if (flags.is(Erased)) writeModTag(ERASED) if (flags.is(Exported)) writeModTag(EXPORTED) + if (flags.is(Given)) writeModTag(GIVEN) + if (flags.is(Implicit)) writeModTag(IMPLICIT) if (isTerm) { - if (flags.is(Implicit)) writeModTag(IMPLICIT) - if (flags.is(Given)) writeModTag(GIVEN) if (flags.is(Lazy, butNot = Module)) writeModTag(LAZY) if (flags.is(AbsOverride)) { writeModTag(ABSTRACT); writeModTag(OVERRIDE) } if (flags.is(Mutable)) writeModTag(MUTABLE) diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 8c19671293e0..bc63b958f1f0 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -323,7 +323,7 @@ object Completion { val extMethodsFromImplicitScope = extractMemberExtensionMethods(implicitScopeCompanions) // 4. The reference is of the form r.m and the extension method is defined in some given instance in the implicit scope of the type of r. - val givensInImplicitScope = implicitScopeCompanions.flatMap(_.membersBasedOnFlags(required = Given, excluded = EmptyFlags)).map(_.info) + val givensInImplicitScope = implicitScopeCompanions.flatMap(_.membersBasedOnFlags(required = GivenVal, excluded = EmptyFlags)).map(_.info) val extMethodsFromGivensInImplicitScope = extractMemberExtensionMethods(givensInImplicitScope) val availableExtMethods = extMethodsFromGivensInImplicitScope ++ extMethodsFromImplicitScope ++ extMethodsFromGivensInScope ++ extMethodsInScope diff --git a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala index e3d6711af97f..aa1d7b102fb5 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala @@ -79,6 +79,8 @@ class ExtractSemanticDB extends Phase: || sym.isLocalDummy || sym.is(Synthetic) || sym.isSetter + || sym.isOldStyleImplicitConversion(forImplicitClassOnly = true) + || sym.owner.isGivenInstanceSummoner || excludeDefOrUse(sym) private def excludeDefOrUse(sym: Symbol)(using Context): Boolean = @@ -102,6 +104,7 @@ class ExtractSemanticDB extends Phase: private def excludeChildren(sym: Symbol)(using Context): Boolean = !sym.exists || sym.is(Param) && sym.info.bounds.hi.isInstanceOf[Types.HKTypeLambda] + || sym.isOldStyleImplicitConversion(forImplicitClassOnly = true) /** Uses of this symbol where the reference has given span should be excluded from semanticdb */ private def excludeUse(qualifier: Option[Symbol], sym: Symbol)(using Context): Boolean = diff --git a/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala b/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala index a7bfdcefc047..ec427523195e 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala @@ -41,6 +41,11 @@ object Tools: document.copy(text = text) end loadTextDocument + def loadTextDocumentUnsafe(scalaAbsolutePath: Path, semanticdbAbsolutePath: Path): TextDocument = + val docs = parseTextDocuments(semanticdbAbsolutePath).documents + assert(docs.length == 1) + docs.head.copy(text = new String(Files.readAllBytes(scalaAbsolutePath), StandardCharsets.UTF_8)) + /** Parses SemanticDB text documents from an absolute path to a `*.semanticdb` file. */ private def parseTextDocuments(path: Path): TextDocuments = val bytes = Files.readAllBytes(path) // NOTE: a semanticdb file is a TextDocuments message, not TextDocument diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala index 353ebee25c29..acfb4be5c022 100644 --- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala @@ -87,6 +87,31 @@ object SymUtils: def isGenericProduct(using Context): Boolean = whyNotGenericProduct.isEmpty + /** Is this an old style implicit conversion? + * @param directOnly only consider explicitly written methods + * @param forImplicitClassOnly only consider methods generated from implicit classes + */ + def isOldStyleImplicitConversion(directOnly: Boolean = false, forImplicitClassOnly: Boolean = false)(using Context): Boolean = + self.is(Implicit) && self.info.stripPoly.match + case mt @ MethodType(_ :: Nil) if !mt.isImplicitMethod => + if self.isCoDefinedGiven(mt.finalResultType.typeSymbol) + then !directOnly + else !forImplicitClassOnly + case _ => + false + + /** Is this the method that summons a structural given instance? */ + def isGivenInstanceSummoner(using Context): Boolean = + def isCodefined(info: Type): Boolean = info.stripPoly match + case mt: MethodType => + // given summoner can only have contextual params + mt.isImplicitMethod && isCodefined(mt.resultType) + case mt: ExprType => + isCodefined(mt.resultType) + case res => + self.isCoDefinedGiven(res.typeSymbol) + self.isAllOf(Given | Method) && isCodefined(self.info) + def useCompanionAsMirror(using Context): Boolean = self.linkedClass.exists && !self.is(Scala2x) /** Is this a sealed class or trait for which a sum mirror is generated? diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 9a83f9da4f02..2f34caf0e2f7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1631,7 +1631,7 @@ trait Applications extends Compatibility { /** Widen the result type of synthetic given methods from the implementation class to the * type that's implemented. Example * - * given I[X] as T { ... } + * given I[X]: T with { ... } * * This desugars to * @@ -1641,7 +1641,7 @@ trait Applications extends Compatibility { * To compare specificity we should compare with `T`, not with its implementation `I[X]`. * No such widening is performed for given aliases, which are not synthetic. E.g. * - * given J[X] as T = rhs + * given J[X]: T = rhs * * already has the right result type `T`. Neither is widening performed for given * objects, since these are anyway taken to be more specific than methods @@ -1652,8 +1652,8 @@ trait Applications extends Compatibility { mt.derivedLambdaType(mt.paramNames, mt.paramInfos, widenGiven(mt.resultType, alt)) case pt: PolyType => pt.derivedLambdaType(pt.paramNames, pt.paramInfos, widenGiven(pt.resultType, alt)) - case _ => - if (alt.symbol.isAllOf(SyntheticGivenMethod)) tp.widenToParents + case rt => + if alt.symbol.isCoDefinedGiven(rt.typeSymbol) then tp.widenToParents else tp } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 5534d0c795fc..0f838ac20755 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -473,7 +473,7 @@ object Checking { if (sym.is(Implicit)) { if (sym.owner.is(Package)) fail(TopLevelCantBeImplicit(sym)) - if (sym.isType) + if sym.isType && (!sym.isClass || sym.is(Trait)) then fail(TypesAndTraitsCantBeImplicit()) } if sym.is(Transparent) then @@ -861,22 +861,14 @@ trait Checking { /** If `sym` is an old-style implicit conversion, check that implicit conversions are enabled. * @pre sym.is(GivenOrImplicit) */ - def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit = { - def check(): Unit = + def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit = + if sym.isOldStyleImplicitConversion(directOnly = true) then checkFeature( nme.implicitConversions, i"Definition of implicit conversion $sym", ctx.owner.topLevelClass, sym.srcPos) - sym.info.stripPoly match { - case mt @ MethodType(_ :: Nil) - if !mt.isImplicitMethod && !sym.is(Synthetic) => // it's an old-styleconversion - check() - case _ => - } - } - /** If `tree` is an application of a new-style implicit conversion (using the apply * method of a `scala.Conversion` instance), check that implicit conversions are * enabled. diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala index a975dd206d22..e8a923427b38 100644 --- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala +++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala @@ -151,7 +151,7 @@ class ImportInfo(symf: Context ?=> Symbol, else for renamed <- reverseMapping.keys - denot <- pre.member(reverseMapping(renamed)).altsWith(_.isOneOf(GivenOrImplicit)) + denot <- pre.member(reverseMapping(renamed)).altsWith(_.isOneOf(GivenOrImplicitVal)) yield val original = reverseMapping(renamed) val ref = TermRef(pre, original, denot) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 29a6da138e6c..1eb6c47bce4a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -241,7 +241,7 @@ class Namer { typer: Typer => tree match { case tree: TypeDef if tree.isClassDef => - val flags = checkFlags(tree.mods.flags &~ Implicit) + val flags = checkFlags(tree.mods.flags) val name = checkNoConflict(tree.name, flags.is(Private), tree.span).asTypeName val cls = createOrRefine[ClassSymbol](tree, name, flags, ctx.owner, diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index ac11d819b24d..919469529cb5 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -326,7 +326,7 @@ trait QuotesAndSplices { tdef.symbol.addAnnotation(Annotation(New(ref(defn.QuotedRuntimePatterns_fromAboveAnnot.typeRef)).withSpan(tdef.span))) val bindingType = getBinding(tdef.symbol).symbol.typeRef val bindingTypeTpe = AppliedType(defn.QuotedTypeClass.typeRef, bindingType :: Nil) - val sym = newPatternBoundSymbol(nameOfSyntheticGiven, bindingTypeTpe, tdef.span, flags = ImplicitTerm)(using ctx0) + val sym = newPatternBoundSymbol(nameOfSyntheticGiven, bindingTypeTpe, tdef.span, flags = ImplicitVal)(using ctx0) buff += Bind(sym, untpd.Ident(nme.WILDCARD).withType(bindingTypeTpe)).withSpan(tdef.span) super.transform(tdef) } diff --git a/compiler/test-resources/repl/i1374 b/compiler/test-resources/repl/i1374 index a56b15df2818..3d117fdb4ff9 100644 --- a/compiler/test-resources/repl/i1374 +++ b/compiler/test-resources/repl/i1374 @@ -1,5 +1,6 @@ scala> implicit class Padder(val sb: StringBuilder) extends AnyVal { def pad2(width: Int) = { 1 to width - sb.length foreach { sb append '*' }; sb } } // defined class Padder +def Padder(sb: StringBuilder): Padder scala> val greeting = new StringBuilder("Hello, kitteh!") val greeting: StringBuilder = Hello, kitteh! scala> val a = greeting pad2 20 diff --git a/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala b/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala index 5deeaed114a8..d1f58bf52a91 100644 --- a/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala +++ b/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala @@ -25,6 +25,30 @@ import dotty.tools.dotc.util.SourceFile @main def updateExpect = SemanticdbTests().runExpectTest(updateExpectFiles = true) +/** Useful for printing semanticdb metac output for one file + * + * @param root the output directory containing semanticdb output, + * only 1 semanticdb file should be present + * @param source the single source file producing the semanticdb + */ +@main def metac(root: String, source: String) = + val rootSrc = Paths.get(root) + val sourceSrc = Paths.get(source) + val semanticFile = FileSystems.getDefault.getPathMatcher("glob:**.semanticdb") + def inputFile(): Path = + val ls = Files.walk(rootSrc.resolve("META-INF").resolve("semanticdb")) + val files = + try ls.filter(p => semanticFile.matches(p)).collect(Collectors.toList).asScala + finally ls.close() + require(files.sizeCompare(1) == 0, s"No semanticdb files! $rootSrc") + files.head + val metacSb: StringBuilder = StringBuilder(5000) + val semanticdbPath = inputFile() + val doc = Tools.loadTextDocumentUnsafe(sourceSrc.toAbsolutePath, semanticdbPath) + Tools.metac(doc, Paths.get(doc.uri))(using metacSb) + Files.write(rootSrc.resolve("metac.expect"), metacSb.toString.getBytes(StandardCharsets.UTF_8)) + + @Category(Array(classOf[BootstrappedOnlyTests])) class SemanticdbTests: val javaFile = FileSystems.getDefault.getPathMatcher("glob:**.java") diff --git a/tests/pos/i12949.scala b/tests/pos/i12949.scala new file mode 100644 index 000000000000..5a886aa894b3 --- /dev/null +++ b/tests/pos/i12949.scala @@ -0,0 +1,19 @@ +object Catch22: + trait TC[V] + object TC: + export Hodor.TC.given + +object Hodor: + object TC: + import Catch22.TC + given fromString[V <: String]: TC[V] = ??? + transparent inline given fromDouble[V <: Double]: TC[V] = + new TC[V]: + type Out = Double + given fromInt[V <: Int]: TC[V] with + type Out = Int + +object Test: + summon[Catch22.TC["hi"]] //works + summon[Catch22.TC[7.7]] //works + summon[Catch22.TC[1]] //error diff --git a/tests/semanticdb/expect/InventedNames.expect.scala b/tests/semanticdb/expect/InventedNames.expect.scala index 131d4304da31..7c5b008209c2 100644 --- a/tests/semanticdb/expect/InventedNames.expect.scala +++ b/tests/semanticdb/expect/InventedNames.expect.scala @@ -39,4 +39,4 @@ val f/*<-givens::InventedNames$package.f.*/ = given_Float/*->givens::InventedNam val g/*<-givens::InventedNames$package.g.*/ = `* *`/*->givens::InventedNames$package.`* *`.*/ val x/*<-givens::InventedNames$package.x.*/ = given_X/*->givens::InventedNames$package.given_X.*/ val y/*<-givens::InventedNames$package.y.*/ = given_Y/*->givens::InventedNames$package.given_Y().*/ -val z/*<-givens::InventedNames$package.z.*/ = given_Z_T/*->givens::InventedNames$package.given_Z_T().*/[String/*->scala::Predef.String#*/] \ No newline at end of file +val z/*<-givens::InventedNames$package.z.*/ = given_Z_T/*->givens::InventedNames$package.given_Z_T().*/[String/*->scala::Predef.String#*/] diff --git a/tests/semanticdb/expect/InventedNames.scala b/tests/semanticdb/expect/InventedNames.scala index 3858f22c8331..42c14c90e370 100644 --- a/tests/semanticdb/expect/InventedNames.scala +++ b/tests/semanticdb/expect/InventedNames.scala @@ -39,4 +39,4 @@ val f = given_Float val g = `* *` val x = given_X val y = given_Y -val z = given_Z_T[String] \ No newline at end of file +val z = given_Z_T[String] diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index c367bf48e8d4..d66bf1dc17dd 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -484,7 +484,7 @@ classes/C12#foo2Impl().(context) => param context: Context classes/C12#foo2Impl().(x) => param x: context.Expr[Int] classes/C12#foo2Impl().(y) => param y: context.Expr[String] classes/M. => final object M extends Object { self: M.type => +3 decls } -classes/M.C5# => class C5 extends Object { self: C5 => +2 decls } +classes/M.C5# => implicit class C5 extends Object { self: C5 => +2 decls } classes/M.C5#``(). => primary ctor (param x: Int): C5 classes/M.C5#``().(x) => param x: Int classes/M.C5#x. => private[this] val method x Int @@ -1519,7 +1519,7 @@ example/ImplicitConversion#string2Number().(string) => param string: String example/ImplicitConversion#tuple. => val method tuple Tuple2[Int, Int] example/ImplicitConversion#x. => val method x Int example/ImplicitConversion. => final object ImplicitConversion extends Object { self: ImplicitConversion.type => +6 decls } -example/ImplicitConversion.newAny2stringadd# => final class newAny2stringadd [typeparam A ] extends AnyVal { self: newAny2stringadd[A] => +4 decls } +example/ImplicitConversion.newAny2stringadd# => final implicit class newAny2stringadd [typeparam A ] extends AnyVal { self: newAny2stringadd[A] => +4 decls } example/ImplicitConversion.newAny2stringadd#[A] => typeparam A example/ImplicitConversion.newAny2stringadd#`+`(). => method + (param other: String): String example/ImplicitConversion.newAny2stringadd#`+`().(other) => param other: String @@ -1705,14 +1705,14 @@ givens/InventedNames$package.given_List_T().[T] => typeparam T givens/InventedNames$package.given_String. => final implicit lazy val given method given_String String givens/InventedNames$package.given_X. => final implicit given object given_X extends Object with X { self: given_X.type => +2 decls } givens/InventedNames$package.given_X.doX(). => method doX => Int <: givens/X#doX(). -givens/InventedNames$package.given_Y# => class given_Y extends Object with Y { self: given_Y => +3 decls } +givens/InventedNames$package.given_Y# => implicit given class given_Y extends Object with Y { self: given_Y => +3 decls } givens/InventedNames$package.given_Y#``(). => primary ctor ()(implicit val given param x$1: X): given_Y givens/InventedNames$package.given_Y#``().(x$1) => implicit val given param x$1: X givens/InventedNames$package.given_Y#doY(). => method doY => String <: givens/Y#doY(). givens/InventedNames$package.given_Y#x$1. => protected implicit val given method x$1 X givens/InventedNames$package.given_Y(). => final implicit given method given_Y (implicit given param x$1: X): given_Y givens/InventedNames$package.given_Y().(x$1) => implicit given param x$1: X -givens/InventedNames$package.given_Z_T# => class given_Z_T [typeparam T ] extends Object with Z[T] { self: given_Z_T[T] => +3 decls } +givens/InventedNames$package.given_Z_T# => implicit given class given_Z_T [typeparam T ] extends Object with Z[T] { self: given_Z_T[T] => +3 decls } givens/InventedNames$package.given_Z_T#[T] => typeparam T givens/InventedNames$package.given_Z_T#``(). => primary ctor [typeparam T ](): given_Z_T[T] givens/InventedNames$package.given_Z_T#doZ(). => method doZ => List[T] <: givens/Z#doZ().