Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ private sealed trait WarningSettings:
private val WenumCommentDiscard = BooleanSetting("-Wenum-comment-discard", "Warn when a comment ambiguously assigned to multiple enum cases is discarded.")
private val WtoStringInterpolated = BooleanSetting("-Wtostring-interpolated", "Warn a standard interpolator used toString on a reference type.")
private val WrecurseWithDefault = BooleanSetting("-Wrecurse-with-default", "Warn when a method calls itself with a default argument.")
private val WwrongArrow = BooleanSetting("-Wwrong-arrow", "Warn if function arrow was used instead of context literal ?=>.")
private val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting(
name = "-Wunused",
helpArg = "warning",
Expand Down Expand Up @@ -295,6 +296,7 @@ private sealed trait WarningSettings:
def toStringInterpolated(using Context): Boolean = allOr(WtoStringInterpolated)
def recurseWithDefault(using Context): Boolean = allOr(WrecurseWithDefault)
def checkInit(using Context): Boolean = allOr(YcheckInit)
def wrongArrow(using Context): Boolean = allOr(WwrongArrow)

/** -X "Extended" or "Advanced" settings */
private sealed trait XSettings:
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/init/Checker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class Checker extends Phase:
cancellable {
val classes = traverser.getClasses()

if ctx.settings.Whas.checkInit then
if ctx.settings.Whas.safeInit then
Semantic.checkClasses(classes)(using checkCtx)
}

Expand Down
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3283,6 +3283,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
val ifun = desugar.makeContextualFunction(paramTypes, tree, erasedParams)
typr.println(i"make contextual function $tree / $pt ---> $ifun")
typedFunctionValue(ifun, pt)
.tap:
case tree @ Block((m1: DefDef) :: _, _: Closure) if ctx.settings.Whas.wrongArrow =>
m1.rhs match
case Block((m2: DefDef) :: _, _: Closure) if m1.paramss.lengthCompare(m2.paramss) == 0 =>
val p1s = m1.symbol.info.asInstanceOf[MethodType].paramInfos
val p2s = m2.symbol.info.asInstanceOf[MethodType].paramInfos
if p1s.corresponds(p2s)(_ =:= _) then
report.warning(em"Context function adapts a lambda with the same parameter types, possibly ?=> was intended.", tree.srcPos)
case _ =>
case _ =>
}

/** Typecheck and adapt tree, returning a typed tree. Parameters as for `typedUnadapted` */
Expand Down
10 changes: 5 additions & 5 deletions compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class CompilationTests {
compileFilesInDir("tests/neg-deep-subtype", allowDeepSubtypes),
compileFilesInDir("tests/neg-custom-args/captures", defaultOptions.and("-language:experimental.captureChecking")),
compileFile("tests/neg-custom-args/sourcepath/outer/nested/Test1.scala", defaultOptions.and("-sourcepath", "tests/neg-custom-args/sourcepath")),
compileDir("tests/neg-custom-args/sourcepath2/hi", defaultOptions.and("-sourcepath", "tests/neg-custom-args/sourcepath2", "-Xfatal-warnings")),
compileDir("tests/neg-custom-args/sourcepath2/hi", defaultOptions.and("-sourcepath", "tests/neg-custom-args/sourcepath2", "-Werror")),
compileList("duplicate source", List(
"tests/neg-custom-args/toplevel-samesource/S.scala",
"tests/neg-custom-args/toplevel-samesource/nested/S.scala"),
Expand Down Expand Up @@ -214,7 +214,7 @@ class CompilationTests {
compileFilesInDir("tests/init/neg", options).checkExpectedErrors()
compileFilesInDir("tests/init/warn", defaultOptions.and("-Ysafe-init")).checkWarnings()
compileFilesInDir("tests/init/pos", options).checkCompile()
compileFilesInDir("tests/init/crash", options.without("-Xfatal-warnings")).checkCompile()
compileFilesInDir("tests/init/crash", options.without("-Werror")).checkCompile()
// The regression test for i12128 has some atypical classpath requirements.
// The test consists of three files: (a) Reflect_1 (b) Macro_2 (c) Test_3
// which must be compiled separately. In addition:
Expand All @@ -223,7 +223,7 @@ class CompilationTests {
// - the output from (a) _must not_ be on the classpath while compiling (c)
locally {
val i12128Group = TestGroup("checkInit/i12128")
val i12128Options = options.without("-Xfatal-warnings")
val i12128Options = options.without("-Werror")
val outDir1 = defaultOutputDir + i12128Group + "/Reflect_1/i12128/Reflect_1"
val outDir2 = defaultOutputDir + i12128Group + "/Macro_2/i12128/Macro_2"

Expand All @@ -242,7 +242,7 @@ class CompilationTests {
* an error when reading the files' TASTy trees. */
locally {
val tastyErrorGroup = TestGroup("checkInit/tasty-error/val-or-defdef")
val tastyErrorOptions = options.without("-Xfatal-warnings")
val tastyErrorOptions = options.without("-Werror")

val classA0 = defaultOutputDir + tastyErrorGroup + "/A/v0/A"
val classA1 = defaultOutputDir + tastyErrorGroup + "/A/v1/A"
Expand All @@ -265,7 +265,7 @@ class CompilationTests {
* an error when reading the files' TASTy trees. This fact is demonstrated by the compilation of Main. */
locally {
val tastyErrorGroup = TestGroup("checkInit/tasty-error/typedef")
val tastyErrorOptions = options.without("-Xfatal-warnings").without("-Ycheck:all")
val tastyErrorOptions = options.without("-Werror").without("-Ycheck:all")

val classC = defaultOutputDir + tastyErrorGroup + "/C/typedef/C"
val classA0 = defaultOutputDir + tastyErrorGroup + "/A/v0/A"
Expand Down
22 changes: 22 additions & 0 deletions tests/warn/i21187.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//> using options -Wall

def oops(msg: String) = sys.error(msg)

class Zone
object Zone:
inline def apply[T](inline f: Zone ?=> T): T = f(using new Zone)

inline def zone[A](inline f: Zone ?=> A) = Zone.apply(z => f(using z)) // warn suspicious contextualizing

def zone_?[A](f: Zone ?=> A) = Zone.apply(z => f(using z)) // warn

// intended
//inline def zone[A](inline f: Zone ?=> A): A = Zone.apply(z ?=> f(using z))

@main def hello =
// this swallows exceptions!
zone(oops("here")) // warn function value is not used
zone_?(oops("here")) // warn

// this doesn't
Zone(oops("not here"))