Skip to content

Commit 0ba3c5d

Browse files
committed
Convert cloneType to an extension method
This removes much of the use of this.type in Chisel which is necessary to upgrade to Scala 3.
1 parent 06cb11a commit 0ba3c5d

File tree

18 files changed

+72
-50
lines changed

18 files changed

+72
-50
lines changed

core/src/main/scala-2/chisel3/Bits.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w
160160
* @note For [[SInt]]s only, this will do sign extension.
161161
* @group Bitwise
162162
*/
163-
final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg
163+
final def pad(that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg
164164

165165
/** @group SourceInfoTransformMacro */
166-
def do_pad(that: Int)(implicit sourceInfo: SourceInfo): this.type = _padImpl(that)
166+
def do_pad(that: Int)(implicit sourceInfo: SourceInfo): Bits = _padImpl(that)
167167

168168
/** Bitwise inversion operator
169169
*
@@ -182,8 +182,6 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends BitsImpl w
182182
* $sumWidthInt
183183
* @group Bitwise
184184
*/
185-
// REVIEW TODO: redundant
186-
// REVIEW TODO: should these return this.type or Bits?
187185
final def <<(that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
188186

189187
/** @group SourceInfoTransformMacro */

core/src/main/scala/chisel3/AggregateImpl.scala

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package chisel3
44

55
import chisel3.experimental.VecLiterals.AddVecLiteralConstructor
66
import chisel3.experimental.dataview.{isView, reify, reifyIdentityView, InvalidViewException}
7+
import chisel3.Data.DataExtensions
78

89
import scala.collection.immutable.{SeqMap, VectorMap}
910
import scala.collection.mutable.{HashSet, LinkedHashMap}
@@ -421,9 +422,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T,
421422
*/
422423
def apply(idx: Int): T = self(idx)
423424

424-
override def cloneType: this.type = {
425-
new Vec(gen.cloneTypeFull, length).asInstanceOf[this.type]
426-
}
425+
override def _cloneType: Vec[T] = new Vec(gen.cloneTypeFull, length)
427426

428427
override def getElements: Seq[Data] = self
429428

@@ -491,7 +490,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T,
491490
elementInitializers: (Int, T)*
492491
)(
493492
implicit sourceInfo: SourceInfo
494-
): this.type = {
493+
): Vec[T] = {
495494

496495
def checkLiteralConstruction(): Unit = {
497496
val dupKeys = elementInitializers.map { x => x._1 }.groupBy(x => x).flatMap {
@@ -543,7 +542,7 @@ private[chisel3] abstract class VecImpl[T <: Data] private[chisel3] (gen: => T,
543542
requireIsChiselType(this, "vec literal constructor model")
544543
checkLiteralConstruction()
545544

546-
val clone = cloneType
545+
val clone = this.cloneType
547546
val cloneFields = getRecursiveFields(clone, "(vec root)").toMap
548547

549548
// Create the Vec literal binding from litArgs of arguments
@@ -832,8 +831,10 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record =>
832831
}
833832
}
834833

835-
override def cloneType: this.type = {
836-
val clone = _cloneTypeImpl.asInstanceOf[this.type]
834+
// Note that _cloneTypeImpl is implemented by the compiler plugin and must be a different method name because
835+
// We want to run checkClone after calling _cloneTypeImpl
836+
final override def _cloneType: Data = {
837+
val clone = _cloneTypeImpl
837838
checkClone(clone)
838839
clone
839840
}
@@ -953,10 +954,10 @@ private[chisel3] trait RecordImpl extends AggregateImpl { thiz: Record =>
953954
* )
954955
* }}}
955956
*/
956-
private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*)(implicit sourceInfo: SourceInfo): this.type = {
957+
private[chisel3] def _makeLit(elems: (Data => (Data, Data))*)(implicit sourceInfo: SourceInfo): Data = {
957958

958959
requireIsChiselType(this, "bundle literal constructor model")
959-
val clone = cloneType
960+
val clone = this.cloneType
960961
val cloneFields = getRecursiveFields(clone, "_").toMap
961962

962963
// Create the Bundle literal binding from litargs of arguments

core/src/main/scala/chisel3/BitsImpl.scala

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
package chisel3
44

5+
import chisel3.Data.DataExtensions
56
import chisel3.experimental.{requireIsHardware, SourceInfo}
67
import chisel3.internal.{_resizeToWidth, throwException, BaseModule}
78
import chisel3.internal.Builder.pushOp
@@ -21,9 +22,9 @@ private[chisel3] trait BitsImpl extends Element { self: Bits =>
2122
// Arguments against: generates down to a FIRRTL UInt anyways
2223

2324
// Only used for in a few cases, hopefully to be removed
24-
private[chisel3] def cloneTypeWidth(width: Width): this.type
25+
private[chisel3] def cloneTypeWidth(width: Width): Bits
2526

26-
def cloneType: this.type = cloneTypeWidth(this.width)
27+
override def _cloneType: Data = cloneTypeWidth(this.width)
2728

2829
/** A non-ambiguous name of this `Bits` instance for use in generated Verilog names
2930
* Inserts the width directly after the typeName, e.g. UInt4, SInt1
@@ -167,7 +168,7 @@ private[chisel3] trait BitsImpl extends Element { self: Bits =>
167168
// Pad literal to that width
168169
protected def _padLit(that: Int): this.type
169170

170-
protected def _padImpl(that: Int)(implicit sourceInfo: SourceInfo): this.type = this.width match {
171+
protected def _padImpl(that: Int)(implicit sourceInfo: SourceInfo): Bits = this.width match {
171172
case KnownWidth(w) if w >= that => this
172173
case _ if this.isLit => this._padLit(that)
173174
case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that)
@@ -222,8 +223,7 @@ private[chisel3] trait UIntImpl extends BitsImpl with Num[UInt] { self: UInt =>
222223
}
223224
}
224225

225-
private[chisel3] override def cloneTypeWidth(w: Width): this.type =
226-
new UInt(w).asInstanceOf[this.type]
226+
private[chisel3] override def cloneTypeWidth(w: Width): UInt = new UInt(w)
227227

228228
override protected def _padLit(that: Int): this.type = {
229229
val value = this.litValue
@@ -403,8 +403,7 @@ private[chisel3] trait SIntImpl extends BitsImpl with Num[SInt] { self: SInt =>
403403
}
404404
}
405405

406-
private[chisel3] override def cloneTypeWidth(w: Width): this.type =
407-
new SInt(w).asInstanceOf[this.type]
406+
private[chisel3] override def cloneTypeWidth(w: Width): SInt = new SInt(w)
408407

409408
override protected def _padLit(that: Int): this.type = {
410409
val value = this.litValue
@@ -529,7 +528,7 @@ private[chisel3] trait ResetTypeImpl extends Element { self: Reset =>
529528

530529
override def toString: String = stringAccessor("Reset")
531530

532-
def cloneType: this.type = Reset().asInstanceOf[this.type]
531+
override def _cloneType: Data = Reset()
533532

534533
override def litOption: Option[BigInt] = None
535534

@@ -558,7 +557,7 @@ private[chisel3] trait AsyncResetImpl extends Element { self: AsyncReset =>
558557

559558
override def toString: String = stringAccessor("AsyncReset")
560559

561-
def cloneType: this.type = AsyncReset().asInstanceOf[this.type]
560+
override def _cloneType: Data = AsyncReset()
562561

563562
override def litOption: Option[BigInt] = None
564563

@@ -599,9 +598,9 @@ private[chisel3] trait BoolImpl extends UIntImpl { self: Bool =>
599598
}
600599
}
601600

602-
private[chisel3] override def cloneTypeWidth(w: Width): this.type = {
601+
private[chisel3] override def cloneTypeWidth(w: Width): Bool = {
603602
require(!w.known || w.get == 1)
604-
new Bool().asInstanceOf[this.type]
603+
new Bool()
605604
}
606605

607606
/** Convert to a [[scala.Option]] of [[scala.Boolean]] */

core/src/main/scala/chisel3/ChiselEnumImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ private[chisel3] abstract class EnumTypeImpl(private[chisel3] val factory: Chise
3030
}
3131
}
3232

33-
override def cloneType: this.type = factory().asInstanceOf[this.type]
33+
override def _cloneType: Data = factory()
3434

3535
private[chisel3] def compop(sourceInfo: SourceInfo, op: PrimOp, other: EnumType): Bool = {
3636
requireIsHardware(this, "bits operated on")

core/src/main/scala/chisel3/ClockImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ private[chisel3] trait ClockImpl extends Element {
1313

1414
override def toString: String = stringAccessor("Clock")
1515

16-
def cloneType: this.type = Clock().asInstanceOf[this.type]
16+
override def _cloneType: Data = Clock()
1717

1818
override def connect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
1919
that match {

core/src/main/scala/chisel3/DataImpl.scala

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package chisel3
44

55
import chisel3.experimental.dataview.reify
66

7+
import chisel3.Data.DataExtensions
78
import chisel3.experimental.{requireIsChiselType, requireIsHardware, Analog, BaseModule}
89
import chisel3.experimental.{prefix, SourceInfo, UnlocatableSourceInfo}
910
import chisel3.experimental.dataview.{reifyIdentityView, reifySingleTarget, DataViewable}
@@ -781,28 +782,12 @@ private[chisel3] trait DataImpl extends HasId with NamedComponent { self: Data =
781782
private[chisel3] def width: Width
782783
private[chisel3] def firrtlConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit
783784

784-
/** Internal API; Chisel users should look at chisel3.chiselTypeOf(...).
785+
/** Private implementation of cloneType
785786
*
786-
* cloneType must be defined for any Chisel object extending Data.
787-
* It is responsible for constructing a basic copy of the object being cloned.
788-
*
789-
* @return a copy of the object.
790-
*/
791-
def cloneType: this.type
792-
793-
/** Internal API; Chisel users should look at chisel3.chiselTypeOf(...).
794-
*
795-
* Returns a copy of this data type, with hardware bindings (if any) removed.
796-
* Directionality data and probe information is still preserved.
787+
* _cloneType must be defined for any Chisel object extending Data.
788+
* It is implemented by Chisel itself or by the compiler plugin for user-defined types.
797789
*/
798-
private[chisel3] def cloneTypeFull: this.type = {
799-
val clone = this.cloneType // get a fresh object, without bindings
800-
// Only the top-level direction needs to be fixed up, cloneType should do the rest
801-
clone.specifiedDirection = specifiedDirection
802-
probe.setProbeModifier(clone, probeInfo)
803-
clone.isConst = isConst
804-
clone
805-
}
790+
def _cloneType: Data
806791

807792
/** The "strong connect" operator.
808793
*
@@ -994,6 +979,7 @@ private[chisel3] trait ObjectDataImpl {
994979
*
995980
* @param lhs The [[Data]] hardware on the left-hand side of the equality
996981
*/
982+
// TODO fold this into DataExtensions
997983
implicit class DataEquality[T <: Data](lhs: T)(implicit sourceInfo: SourceInfo) {
998984

999985
/** Dynamic recursive equality operator for generic [[Data]]
@@ -1072,6 +1058,33 @@ private[chisel3] trait ObjectDataImpl {
10721058
}
10731059
}
10741060
}
1061+
1062+
implicit class DataExtensions[T <: Data](self: T) {
1063+
1064+
/** Internal API; Chisel users should look at chisel3.chiselTypeOf(...).
1065+
*
1066+
* cloneType must be defined for any Chisel object extending Data.
1067+
* It is responsible for constructing a basic copy of the object being cloned.
1068+
*
1069+
* @return a copy of the object.
1070+
*/
1071+
def cloneType: T = self._cloneType.asInstanceOf[T]
1072+
1073+
/** Internal API; Chisel users should look at chisel3.chiselTypeOf(...).
1074+
*
1075+
* Returns a copy of this data type, with hardware bindings (if any) removed.
1076+
* Directionality data and probe information is still preserved.
1077+
*/
1078+
private[chisel3] def cloneTypeFull: T = {
1079+
val clone = self.cloneType // get a fresh object, without bindings
1080+
// Only the top-level direction needs to be fixed up, cloneType should do the rest
1081+
clone.specifiedDirection = self.specifiedDirection
1082+
// TODO do we need to exclude probe and const from cloneTypeFull on Properties?
1083+
probe.setProbeModifier(clone, self.probeInfo)
1084+
clone.isConst = self.isConst
1085+
clone.asInstanceOf[T]
1086+
}
1087+
}
10751088
}
10761089

10771090
trait WireFactory {
@@ -1243,7 +1256,8 @@ final case object DontCare extends Element with connectable.ConnectableDocs {
12431256
private[chisel3] override val width: Width = UnknownWidth
12441257

12451258
bind(DontCareBinding(), SpecifiedDirection.Output)
1246-
override def cloneType: this.type = DontCare
1259+
1260+
override def _cloneType: Data = DontCare
12471261

12481262
override def toString: String = "DontCare()"
12491263

core/src/main/scala/chisel3/IO.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package chisel3
22

3+
import chisel3.Data.DataExtensions
34
import chisel3.internal.{throwException, Builder}
45
import chisel3.experimental.{noPrefix, requireIsChiselType, SourceInfo}
56
import chisel3.properties.{Class, Property}

core/src/main/scala/chisel3/Intrinsic.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package chisel3
44

55
import chisel3._
6+
import chisel3.Data.DataExtensions
67
import chisel3.experimental.{requireIsChiselType, Param, SourceInfo}
78
import chisel3.internal.firrtl.ir._
89
import chisel3.internal.Builder

core/src/main/scala/chisel3/MemImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import chisel3.internal.binding._
99
import chisel3.internal.Builder.pushCommand
1010
import chisel3.internal.firrtl.ir._
1111
import chisel3.experimental.{requireIsChiselType, requireIsHardware, SourceInfo, SourceLine}
12+
import chisel3.Data.DataExtensions
1213

1314
private[chisel3] trait ObjectMemImpl {
1415

core/src/main/scala/chisel3/ModuleImpl.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import chisel3.internal.plugin.autoNameRecursively
2828
import chisel3.util.simpleClassName
2929
import chisel3.experimental.{annotate, ChiselAnnotation}
3030
import chisel3.experimental.hierarchy.Hierarchy
31+
import chisel3.Data.DataExtensions
3132

3233
private[chisel3] trait ObjectModuleImpl {
3334

@@ -370,7 +371,7 @@ package internal {
370371
private[chisel3] class ClonePorts(elts: (String, Data)*) extends Record {
371372
val elements: ListMap[String, Data] = ListMap(elts.map { case (name, d) => name -> d.cloneTypeFull }: _*)
372373
def apply(field: String) = elements(field)
373-
override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type]
374+
override protected def _cloneTypeImpl: Record = (new ClonePorts(elts: _*))
374375
}
375376

376377
private[chisel3] def cloneIORecord(

0 commit comments

Comments
 (0)