Skip to content
2 changes: 1 addition & 1 deletion community-build/community-projects/endpoints4s
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ final case class SbtCommunityProject(
)

private val baseCommand =
"clean; set logLevel in Global := Level.Error; set updateOptions in Global ~= (_.withLatestSnapshots(false)); "
"clean; set updateOptions in Global ~= (_.withLatestSnapshots(false)); "
++ s"""set dependencyOverrides in ThisBuild ++= ${dependencyOverrides.mkString("Seq(", ", ", ")")}; """
++ s"++$compilerVersion!; "

Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,12 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
if (isProp)
genExportProperty(alts, jsName, static)
else
genExportMethod(alts.map(Exported), jsName, static)
genExportMethod(alts.map(Exported.apply), jsName, static)
}
}

def genJSConstructorDispatch(alts: List[Symbol]): (Option[List[js.ParamDef]], js.JSMethodDef) = {
val exporteds = alts.map(Exported)
val exporteds = alts.map(Exported.apply)

val isConstructorOfNestedJSClass = exporteds.head.isConstructorOfNestedJSClass
assert(exporteds.tail.forall(_.isConstructorOfNestedJSClass == isConstructorOfNestedJSClass),
Expand Down Expand Up @@ -391,7 +391,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
} else {
val formalArgsRegistry = new FormalArgsRegistry(1, false)
val List(arg) = formalArgsRegistry.genFormalArgs()
val body = genExportSameArgc(jsName, formalArgsRegistry, setters.map(Exported), static, None)
val body = genExportSameArgc(jsName, formalArgsRegistry, setters.map(Exported.apply), static, None)
Some((arg, body))
}
}
Expand Down
24 changes: 1 addition & 23 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -676,28 +676,6 @@ object desugar {
mods.is(Private) || (!mods.is(Protected) && mods.hasPrivateWithin)
}

/** Does one of the parameter's types (in the first param clause)
* mention a preceding parameter?
*/
def isParamDependent = constrVparamss match
case vparams :: _ =>
val paramNames = vparams.map(_.name).toSet
vparams.exists(_.tpt.existsSubTree {
case Ident(name: TermName) => paramNames.contains(name)
case _ => false
})
case _ => false

val companionParent =
if constrTparams.nonEmpty
|| constrVparamss.length > 1
|| mods.is(Abstract)
|| restrictedAccess
|| isParamDependent
|| isEnumCase
then anyRef
else
constrVparamss.foldRight(classTypeRef)((vparams, restpe) => Function(vparams map (_.tpt), restpe))
val applyMeths =
if (mods.is(Abstract)) Nil
else {
Expand Down Expand Up @@ -727,7 +705,7 @@ object desugar {
val toStringMeth =
DefDef(nme.toString_, Nil, Nil, TypeTree(), Literal(Constant(className.toString))).withMods(Modifiers(Override | Synthetic))

companionDefs(companionParent, applyMeths ::: unapplyMeth :: toStringMeth :: companionMembers)
companionDefs(anyRef, applyMeths ::: unapplyMeth :: toStringMeth :: companionMembers)
}
else if (companionMembers.nonEmpty || companionDerived.nonEmpty || isEnum)
companionDefs(anyRef, companionMembers)
Expand Down
8 changes: 0 additions & 8 deletions compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -586,14 +586,6 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
case _ => false
}

/** Is tree a compiler-generated `.apply` node that refers to the
* apply of a function class?
*/
def isSyntheticApply(tree: Tree): Boolean = tree match {
case Select(qual, nme.apply) => tree.span.end == qual.span.end
case _ => false
}

/** Strips layers of `.asInstanceOf[T]` / `_.$asInstanceOf[T]()` from an expression */
def stripCast(tree: Tree)(using Context): Tree = {
def isCast(sel: Tree) = sel.symbol.isTypeCast
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ final class JrtClassPath(fs: java.nio.file.FileSystem) extends ClassPath with No
}

case class DirectoryClassPath(dir: JFile) extends JFileDirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {
override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl
override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl.apply

def findClassFile(className: String): Option[AbstractFile] = {
val relativePath = FileUtils.dirPath(className)
Expand All @@ -220,7 +220,7 @@ case class DirectorySourcePath(dir: JFile) extends JFileDirectoryLookup[SourceFi
protected def createFileEntry(file: AbstractFile): SourceFileEntryImpl = SourceFileEntryImpl(file)
protected def isMatchingFile(f: JFile): Boolean = endsScalaOrJava(f.getName)

override def findClass(className: String): Option[ClassRepresentation] = findSourceFile(className) map SourceFileEntryImpl
override def findClass(className: String): Option[ClassRepresentation] = findSourceFile(className) map SourceFileEntryImpl.apply

private def findSourceFile(className: String): Option[AbstractFile] = {
val relativePath = FileUtils.dirPath(className)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath wi
def asURLs: Seq[URL] = Seq(new URL(dir.name))
def asClassPathStrings: Seq[String] = Seq(dir.path)

override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl
override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl.apply

def findClassFile(className: String): Option[AbstractFile] = {
val relativePath = FileUtils.dirPath(className) + ".class"
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ object Parsers {
if source.isSelfContained then new ScriptParser(source)
else new Parser(source)

private val InCase: Region => Region = Scanners.InCase
private val InCond: Region => Region = Scanners.InBraces
private val InCase: Region => Region = Scanners.InCase.apply
private val InCond: Region => Region = Scanners.InBraces.apply

abstract class ParserCommon(val source: SourceFile)(using Context) {

Expand Down
38 changes: 24 additions & 14 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ object Typer {
*/
private[typer] val HiddenSearchFailure = new Property.Key[List[SearchFailure]]

/** Is tree a compiler-generated `.apply` node that refers to the
* apply of a function class?
*/
private[typer] def isSyntheticApply(tree: tpd.Tree): Boolean = tree match {
case tree: tpd.Select => tree.hasAttachment(InsertedApply)
case _ => false
}

/** Add `fail` to the list of search failures attached to `tree` */
def rememberSearchFailure(tree: tpd.Tree, fail: SearchFailure) =
tree.putAttachment(HiddenSearchFailure,
Expand Down Expand Up @@ -2843,11 +2851,6 @@ class Typer extends Namer
case _ => false
}

def isSyntheticApply(tree: Tree): Boolean = tree match {
case tree: Select => tree.hasAttachment(InsertedApply)
case _ => false
}

def tryApply(using Context) = {
val pt1 = pt.withContext(ctx)
val sel = typedSelect(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt1)
Expand Down Expand Up @@ -3222,9 +3225,6 @@ class Typer extends Namer
* Examples for these cases are found in run/implicitFuns.scala and neg/i2006.scala.
*/
def adaptNoArgsUnappliedMethod(wtp: MethodType, functionExpected: Boolean, arity: Int): Tree = {
def isExpandableApply =
defn.isContextFunctionClass(tree.symbol.maybeOwner) && functionExpected

/** Is reference to this symbol `f` automatically expanded to `f()`? */
def isAutoApplied(sym: Symbol): Boolean =
sym.isConstructor
Expand All @@ -3241,7 +3241,7 @@ class Typer extends Namer
!tree.symbol.isConstructor &&
!tree.symbol.isAllOf(InlineMethod) &&
!ctx.mode.is(Mode.Pattern) &&
!(isSyntheticApply(tree) && !isExpandableApply)) {
!(isSyntheticApply(tree) && !functionExpected)) {
if (!defn.isFunctionType(pt))
pt match {
case SAMType(_) if !pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot) =>
Expand All @@ -3266,16 +3266,26 @@ class Typer extends Namer
defn.isContextFunctionClass(underlying.classSymbol)
}

def adaptNoArgsOther(wtp: Type): Tree = {
if (isContextFunctionRef(wtp) &&
!untpd.isContextualClosure(tree) &&
def adaptNoArgsOther(wtp: Type, functionExpected: Boolean): Tree = {
val implicitFun = isContextFunctionRef(wtp) && !untpd.isContextualClosure(tree)
def caseCompanion =
functionExpected &&
tree.symbol.is(Module) &&
tree.symbol.companionClass.is(Case) &&
!tree.tpe.baseClasses.exists(defn.isFunctionClass) && {
report.warning("The method `apply` is inserted. The auto insertion will be deprecated, please write `" + tree.show + ".apply` explicitly.", tree.sourcePos)
true
}

if ((implicitFun || caseCompanion) &&
!isApplyProto(pt) &&
pt != AssignProto &&
!ctx.mode.is(Mode.Pattern) &&
!ctx.isAfterTyper &&
!ctx.isInlineContext) {
typr.println(i"insert apply on implicit $tree")
typed(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt, locked)
val sel = untpd.Select(untpd.TypedSplice(tree), nme.apply).withAttachment(InsertedApply, ())
try typed(sel, pt, locked) finally sel.removeAttachment(InsertedApply)
}
else if (ctx.mode is Mode.Pattern) {
checkEqualityEvidence(tree, pt)
Expand Down Expand Up @@ -3390,7 +3400,7 @@ class Typer extends Namer
}
adaptNoArgsUnappliedMethod(wtp, funExpected, arity)
case _ =>
adaptNoArgsOther(wtp)
adaptNoArgsOther(wtp, functionExpected)
}
}

Expand Down
10 changes: 5 additions & 5 deletions doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ class DocASTPhase extends Phase {
case c @ TypeDef(n, rhs) if c.symbol.isClass =>
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
val parameters = (c.symbol, annotations(c.symbol), n.show, collectMembers(rhs), flags(c), path(c.symbol), typeParams(c.symbol), constructors(c.symbol), superTypes(c), None, Nil, None)
if (c.symbol.is(Flags.CaseClass)) {
CaseClassImpl.tupled(parameters) :: Nil
} else {
ClassImpl.tupled(parameters) :: Nil
}
val constr =
if (c.symbol.is(Flags.CaseClass)) CaseClassImpl.apply
else ClassImpl.apply

constr.tupled(parameters) :: Nil

/** def */
case d: DefDef =>
Expand Down
2 changes: 1 addition & 1 deletion doc-tool/src/dotty/tools/dottydoc/util/MemberLookup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ trait MemberLookup {
): EntityLink = {
val link =
lookup(Some(entity), packages, query)
.map(LinkToEntity)
.map(LinkToEntity.apply)
.getOrElse(Tooltip(query))

EntityLink(title, link)
Expand Down
8 changes: 4 additions & 4 deletions scala3doc/src/dotty/dokka/tasty/ScalaDocSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ trait ScaladocSupport { self: TastyParser =>
addOpt(parsed.version)(dkkd.Version(_))
addOpt(parsed.since)(dkkd.Since(_))
addOpt(parsed.deprecated)(dkkd.Deprecated(_))
addSeq(parsed.todo)(ScalaTagWrapper.Todo)
addSeq(parsed.see)(ScalaTagWrapper.See)
addSeq(parsed.note)(ScalaTagWrapper.Note)
addSeq(parsed.example)(ScalaTagWrapper.Example)
addSeq(parsed.todo)(ScalaTagWrapper.Todo.apply)
addSeq(parsed.see)(ScalaTagWrapper.See.apply)
addSeq(parsed.note)(ScalaTagWrapper.Note.apply)
addSeq(parsed.example)(ScalaTagWrapper.Example.apply)

addOpt(parsed.constructor)(dkkd.Constructor(_))
addSeq(parsed.valueParams){ case (name, tag) =>
Expand Down
Empty file.
4 changes: 4 additions & 0 deletions tests/neg-custom-args/fatal-warnings/i6190b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Error: tests/neg-custom-args/fatal-warnings/i6190b.scala:3:29 -------------------------------------------------------
3 |def foo = List("1", "2").map(Rule) // error
| ^^^^
| The method `apply` is inserted. The auto insertion will be deprecated, please write `Rule.apply` explicitly.
3 changes: 3 additions & 0 deletions tests/neg-custom-args/fatal-warnings/i6190b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
case class Rule(name: String)

def foo = List("1", "2").map(Rule) // error
2 changes: 1 addition & 1 deletion tests/neg/enums.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum E4 {
case C4(x: Int)
}
object E4 {
val x1: Int => E4 = C4 // error: found: C4, required: Int => E4
val x1: Int => E4 = C4 // ok
val x2: Int => E4 = C4(_) // ok
}

Expand Down
6 changes: 6 additions & 0 deletions tests/neg/i6190.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Rule(name: String)
object Rule {
def apply(name: String): Rule = new Rule(name)
}

def foo = List("1", "2").map(Rule) // error
2 changes: 1 addition & 1 deletion tests/pos/t3137.scala → tests/neg/t3137.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ trait AA {
}

class BB extends AA {
case class C(v: Int)
case class C(v: Int) // error
}
6 changes: 6 additions & 0 deletions tests/pos-special/fatal-warnings/i6190a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
case class Rule(name: String)
object Rule extends (String => Rule) {
def apply(name: String): Rule = new Rule(name)
}

def foo = List("1", "2").map(Rule)
3 changes: 3 additions & 0 deletions tests/pos-special/fatal-warnings/i6190c.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
case class Rule(name: String)

def foo = List("1", "2").map(Rule.apply)
2 changes: 1 addition & 1 deletion tests/run-macros/tasty-extractors-2.check
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")
Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil)), Nil, None, List(DefDef("a", Nil, Nil, Inferred(), Some(Literal(Constant.Int(0))))))), Literal(Constant.Unit())))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, None, List(DefDef("copy", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), "<init>"), Nil))), ClassDef("Foo$", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), Applied(Inferred(), List(Inferred()))), Nil, Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))), DefDef("unapply", Nil, List(List(ValDef("x$1", Inferred(), None))), Singleton(Literal(Constant.Boolean(true))), Some(Literal(Constant.Boolean(true)))), DefDef("toString", Nil, Nil, Inferred(), Some(Literal(Constant.String("Foo"))))))), Literal(Constant.Unit())))
Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, None, List(DefDef("copy", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), "<init>"), Nil))), ClassDef("Foo$", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil)), Nil, Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))), DefDef("unapply", Nil, List(List(ValDef("x$1", Inferred(), None))), Singleton(Literal(Constant.Boolean(true))), Some(Literal(Constant.Boolean(true)))), DefDef("toString", Nil, Nil, Inferred(), Some(Literal(Constant.String("Foo"))))))), Literal(Constant.Unit())))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Block(List(ClassDef("Foo1", DefDef("<init>", Nil, List(List(ValDef("a", TypeIdent("Int"), None))), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil)), Nil, None, List(ValDef("a", Inferred(), None)))), Literal(Constant.Unit())))
Expand Down