Skip to content

inline if over an inline def doesn't work when overriding a method #12072

Closed
@japgolly

Description

@japgolly

Compiler version

Both:

  • 3.0.0-RC1
  • 3.0.1-RC1-bin-20210411-b44cafa-NIGHTLY

Minimized code

object T {

  transparent inline def f(inline s: String): String | Null =
    null

  inline val V = "V"
  inline def D = "D"

  trait Trait { def s: String }

  // ===========================================================================
  // inline {if,match} over inline {val,def}

  transparent inline def if_v: String =
    inline if V == "V" then "o" else "x"

  transparent inline def if_d: String =
    inline if D == "D" then "o" else "x"

  transparent inline def match_v: String =
    inline V match { case "V" => "o"; case _   => "x" }

  transparent inline def match_d: String =
    inline D match { case "D" => "o"; case _   => "x" }

  // ===========================================================================
  // inline {if,match} over inline f(inline {val,def})

  transparent inline def if_fv: String =
    inline if f(V) == "V" then "o" else "x"

  transparent inline def if_fd: String =
    inline if f(D) == "D" then "o" else "x"

  transparent inline def match_fv: String =
    inline f(V) match { case "V" => "o"; case _   => "x" }

  transparent inline def match_fd: String =
    inline f(D) match { case "D" => "o"; case _   => "x" }

  // ===========================================================================
  // inline {if,match} over inline {val,def} in overridden method

  object IfV extends Trait {
    override transparent inline def s: String =
      inline if V == "V" then "o" else "x"
  }

  object IfD extends Trait {
    override transparent inline def s: String =
      inline if D == "D" then "o" else "x" // <--------------------------- error
  }

  object MatchV extends Trait {
    override transparent inline def s: String =
      inline V match { case "V" => "o"; case _   => "x" }
  }

  object MatchD extends Trait {
    override transparent inline def s: String =
      inline D match { case "D" => "o"; case _   => "x" }
  }

  // ===========================================================================
  // inline {if,match} over inline f(inline {val,def}) in overridden method

  object IfFV extends Trait {
    override transparent inline def s: String =
      inline if f(V) == "V" then "o" else "x" // <------------------------ error
  }

  object IfFD extends Trait {
    override transparent inline def s: String =
      inline if f(D) == "D" then "o" else "x" // <------------------------ error
  }

  object MatchFV extends Trait {
    override transparent inline def s: String =
      inline f(V) match { case "V" => "o"; case _   => "x" }
  }

  object MatchFD extends Trait {
    override transparent inline def s: String =
      inline f(D) match { case "D" => "o"; case _   => "x" }
  }
}

Output

[error] -- Error: BUG.scala:51:6 --------------
[error] 51 |      inline if D == "D" then "o" else "x" // <--------------------------- error
[error]    |      ^
[error]    |Cannot reduce `inline if` because its condition is not a constant value: ("D":String).==("D")
[error]    | This location contains code that was inlined from BUG.scala:51
[error] -- Error: BUG.scala:69:6 --------------
[error] 69 |      inline if f(V) == "V" then "o" else "x" // <------------------------ error
[error]    |      ^
[error]    |Cannot reduce `inline if` because its condition is not a constant value: null.==("V")
[error]    | This location contains code that was inlined from BUG.scala:69
[error] -- Error: BUG.scala:74:6 --------------
[error] 74 |      inline if f(D) == "D" then "o" else "x" // <------------------------ error
[error]    |      ^
[error]    |Cannot reduce `inline if` because its condition is not a constant value: null.==("D")
[error]    | This location contains code that was inlined from BUG.scala:74
[error] three errors found

Expectation

It should all compile.

What's even more interesting about this is that you change

  transparent inline def f(inline s: String): String | Null = null

to

  transparent inline def f(inline s: String): String | Null = "f"

then errors 2 and 3 disappear, but the first error remains.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions