diff --git a/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyLookup.scala b/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyLookup.scala index 9f122908613..666968963c9 100644 --- a/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyLookup.scala +++ b/core/src/main/scala-3/chisel3/experimental/hierarchy/HierarchyLookup.scala @@ -24,15 +24,26 @@ private[hierarchy] object HierarchyLookupMacro { )(using q: Quotes): (q.reflect.Symbol, q.reflect.TypeRepr) = { import q.reflect.* val tpe = TypeRepr.of[A] - val typeSym = tpe.typeSymbol + // For intersection types like `RawModule & HasProtocolInterface`, + // typeSymbol returns only one arm. Walk both arms so a @public + // field on either side can be resolved. + def classParts(t: TypeRepr): List[Symbol] = t.dealias match { + case AndType(l, r) => classParts(l) ::: classParts(r) + case other => List(other.typeSymbol) + } + val syms = classParts(tpe) // Handle vals inherited from parent of an instance: fieldMember // is declared in the Instance, while methodMember is the Scala 3 // representation of vals inherited from the parent - val fieldSym = typeSym.fieldMember(name) match { - case s if s != Symbol.noSymbol => s - case _ => - typeSym.methodMember(name).find(_.paramSymss.flatten.isEmpty).getOrElse(Symbol.noSymbol) + val fieldSym = syms.iterator.map { typeSym => + typeSym.fieldMember(name) match { + case s if s != Symbol.noSymbol => s + case _ => + typeSym.methodMember(name).find(_.paramSymss.flatten.isEmpty).getOrElse(Symbol.noSymbol) + } } + .find(_ != Symbol.noSymbol) + .getOrElse(Symbol.noSymbol) if (fieldSym == Symbol.noSymbol) { report.errorAndAbort( s"value `$name` is not a member of ${tpe.show}" diff --git a/src/test/scala-2/chiselTests/experimental/InlineTestSpec.scala b/src/test/scala/chiselTests/experimental/InlineTestSpec.scala similarity index 99% rename from src/test/scala-2/chiselTests/experimental/InlineTestSpec.scala rename to src/test/scala/chiselTests/experimental/InlineTestSpec.scala index c3faae1d4e9..c9c8822de96 100644 --- a/src/test/scala-2/chiselTests/experimental/InlineTestSpec.scala +++ b/src/test/scala/chiselTests/experimental/InlineTestSpec.scala @@ -26,14 +26,14 @@ class TestHarnessWithMonitorSocket[M <: RawModule with HasMonitorSocket](test: T } object TestHarnessWithMonitorSocket { - implicit def testharnessGenerator[M <: RawModule with HasMonitorSocket] = + implicit def testharnessGenerator[M <: RawModule with HasMonitorSocket]: TestHarnessGenerator[M] = TestHarnessGenerator[M](new TestHarnessWithMonitorSocket(_)) } @instantiable trait HasMonitorSocket { this: RawModule => protected def makeProbe(bundle: ProtocolBundle): ProtocolBundle = { - val monProbe = IO(probe.Probe(chiselTypeOf(bundle))) + val monProbe = chisel3.IO(probe.Probe(chiselTypeOf(bundle))) probe.define(monProbe, probe.ProbeValue(bundle)) monProbe } @@ -67,7 +67,7 @@ object ProtocolChecks { } } -trait HasTestsProperty { this: RawModule with HasTests => +trait HasTestsProperty extends RawModule with HasTests { def enableTestsProperty: Boolean val testNames = Option.when(enableTestsProperty) {