Skip to content

Add a lint/warning for the Interaction between using and default parameters #23541

@bracevac

Description

@bracevac

Compiler version

3.7.x

Minimized code

//> using scala 3.7.0

def fun(x: Int)(using p: Int, q: Int = 0): Int = 
  if x <= 0 then p * q
  else fun(x - 1)(using p = p + x)

@main def test = 
  println(fun(3)(using p = 0, q = 1))

Output

We would expect that the computation outputs (3 + 2 + 1) * 1 = 6, but
it's actually (3 + 2 + 1) * 0 = 0, because in the recursive call to fun, the default value p = 0 takes precedence over the enclosing p (which we set to 1 initially).

Expectation

That's extremely sneaky and feels wrong. I've seen instances of this interaction of defaults and implicits in the Scaladoc codebase (where implicit parameters keep getting added by people in AST traversals, in itself a problem for another time).

At least we should get a big fat warning that something surprising is going on,
but ideally, we change the behavior so that the default only applies if implicit resolution cannot find a binding in context.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions