Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -168,6 +168,7 @@ private sealed trait WarningSettings:
private val WunstableInlineAccessors = BooleanSetting(WarningSetting, "WunstableInlineAccessors", "Warn an inline methods has references to non-stable binary APIs.")
private val WtoStringInterpolated = BooleanSetting(WarningSetting, "Wtostring-interpolated", "Warn a standard interpolator used toString on a reference type.")
private val WrecurseWithDefault = BooleanSetting(WarningSetting, "Wrecurse-with-default", "Warn when a method calls itself with a default argument.")
private val WdubiousContextual = BooleanSetting(WarningSetting, "Wwrong-arrow", "Warn if function arrow was used instead of context literal ?=>.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private val WdubiousContextual = BooleanSetting(WarningSetting, "Wwrong-arrow", "Warn if function arrow was used instead of context literal ?=>.")
private val WwrongArrow = BooleanSetting(WarningSetting, "Wwrong-arrow", "Warn if function arrow was used instead of context literal ?=>.")

private val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting(
WarningSetting,
name = "Wunused",
Expand Down Expand Up @@ -311,6 +312,7 @@ private sealed trait WarningSettings:
def unstableInlineAccessors(using Context): Boolean = allOr(WunstableInlineAccessors)
def toStringInterpolated(using Context): Boolean = allOr(WtoStringInterpolated)
def recurseWithDefault(using Context): Boolean = allOr(WrecurseWithDefault)
def dubiousContextual(using Context): Boolean = allOr(WdubiousContextual)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def dubiousContextual(using Context): Boolean = allOr(WdubiousContextual)
def wrongArrow(using Context): Boolean = allOr(WdubiousContextual)

def checkInit(using Context): Boolean = allOr(WcheckInit)

/** -X "Extended" or "Advanced" settings */
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 @@ -3824,6 +3824,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
val ifun = desugar.makeContextualFunction(paramTypes, paramNamesOrNil, 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.dubiousContextual =>
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
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"))
Loading