Skip to content

mkAttributedQualifier(_1.type, <none>) compiler crash #11259

Open
@soronpo

Description

@soronpo

It took long to minimize 😢
Here is the code that demonstrates two bugs: an error and a compiler crash (see the comments at the end).

package DFiant

object Extras {
  type <>[DF <: DFAny, Dir <: DFDir] = DFAny.Port[DF, Dir] with DF
  //Direction of a Port
  sealed trait DFDir
  sealed trait IN extends DFDir
  implicit object IN extends IN
  sealed trait OUT extends DFDir
  implicit object OUT extends OUT
  ////////////////////////////////////////////////////////////////////////////////////
}

import Extras._

class IfWithRetVal[RV <: DFAny, Builder[L, R] <: DFAny.Op.Builder[L, R]] {
  protected[DFiant] class DFIfBlock(val cond : Boolean, block : => RV) {
    def elsedf[R](elseBlock: => Unit)(implicit op : Builder[RV, R]) : RV = ???
  }
  def apply[R](cond: Boolean)(block: => Unit)(implicit op : Builder[RV, R]) : DFIfBlock = ???
}

trait DFAny {
  type TVal <: DFAny.Unbounded[TCompanion]
  type TCompanion <: DFAny.Companion
  type TUnbounded = protComp.Unbounded
  protected[DFiant] val protComp : TCompanion
}



object DFAny {
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Head Types
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  trait Unbounded[T <: DFAny.Companion] extends DFAny {
    type TCompanion = T
  }

  trait Var extends DFAny {
    final def <> [RDIR <: DFDir](right: TVal <> RDIR) : Unit = ???
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////


  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Abstract Constructors
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  abstract class NewVar[DF <: DFAny](
    implicit cmp : Companion
  ) extends DFAny.Var {
    final protected[DFiant] lazy val protComp : TCompanion = cmp.asInstanceOf[TCompanion]
    def <> [Dir <: DFDir](dir : Dir)(implicit port : protComp.Port.Builder[TVal, Dir]) : Unit = {}
    final object ifdf extends IfWithRetVal[TVal, protComp.`Op:=`.Builder]
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////


  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Port
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  abstract class Port[DF <: DFAny, Dir <: DFDir](dfVar : DF, val dir : Dir)(
    implicit cmp : Companion
  ) extends DFAny.Var {
    final protected[DFiant] lazy val protComp : TCompanion = cmp.asInstanceOf[TCompanion]
  }
  object Port {
    trait Builder[L <: DFAny, Dir <: DFDir] {
      def apply(right : L, dir : Dir) : Unit
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Op
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  object Op {
    trait Builder[L, R] {
      type Comp <: DFAny
      def apply(left : L, rightR : R) : Comp
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////


  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Create Companion object of DFXXX extenders of DFAny
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  trait Companion {
    type Unbounded <: DFAny.Unbounded[this.type]

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Port
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    trait PortCO {
      type Builder[L <: DFAny, Dir <: DFDir] <: DFAny.Port.Builder[L, Dir]
    }
    val Port : PortCO
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Common Ops
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    trait `Op:=` {
      type Builder[L, R] <: DFAny.Op.Builder[L, R]
    }
    val `Op:=` : `Op:=`
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    implicit val cmp = this
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

}


trait DFBits extends DFBits.Unbounded {
}


object DFBits extends DFAny.Companion {
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Unbounded Val
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  trait Unbounded extends DFAny.Unbounded[DFBits.type] {
    type TVal = DFBits
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Var
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  trait Var extends DFBits with DFAny.Var {
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////


  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Public Constructors
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  def apply() : NewVar = ???
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////


  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Protected Constructors
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  protected[DFiant] final class NewVar extends DFAny.NewVar[DFBits] with Var {}
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Port
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  object Port extends PortCO {
    trait Builder[L <: DFAny, Dir <: DFDir] extends DFAny.Port.Builder[L, Dir]
    object Builder {
      implicit def conn[LW, Dir <: DFDir]
      : Builder[DFBits, Dir] = ???
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Assign & Connect
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  trait `Ops:=,<>` extends `Op:=` {
    @scala.annotation.implicitNotFound("Dataflow variable ${L} does not support assignment/connect operation with the type ${R}")
    trait Builder[L, R] extends DFAny.Op.Builder[L, R]

    object Builder {
      type Aux[L, R, Comp0] = Builder[L, R] {
        type Comp = Comp0
      }

      implicit def evDFBits_op_DFBits[LW, RW] : Aux[DFBits, DFBits, DFBits] = ???
    }
  }
  object `Op:=` extends `Ops:=,<>`
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

trait Bugs {
  val bug1 = DFBits() <> IN //error: does not take parameters
  val bug2 = DFBits().ifdf(true) {} elsedf {} //compiler crash: mkAttributedQualifier(_1.type, <none>)

  val workaround = DFBits()
  val ok1 = workaround <> IN
  val ok2 = workaround.ifdf(true) {} elsedf {}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions