Skip to content

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

Open
@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

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions