From 747d16311bdf185d2e98e452b14cb5d8ccca004c Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Tue, 11 Jan 2022 10:10:20 -0800 Subject: Lookupable: add Either version (#2335) * Add Lookupable for Either * Lookupable: enhance the @public/@instantiable error message to include traits and Eithers Co-authored-by: Jack Koenig --- .../experimental/hierarchy/Lookupable.scala | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'core') diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala index 1223d6ce..8552267a 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala @@ -18,8 +18,8 @@ import chisel3.internal.{throwException, AggregateViewBinding, Builder, ChildBin * Sealed. */ @implicitNotFound( - "@public is only legal within a class marked @instantiable and only on vals of type" + - " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable or Option" + "@public is only legal within a class or trait marked @instantiable, and only on vals of type" + + " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable, Option, or Either" ) trait Lookupable[-B] { type C // Return type of the lookup @@ -381,6 +381,27 @@ object Lookupable { ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) } } } + implicit def lookupEither[L, R]( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions, + lookupableL: Lookupable[L], + lookupableR: Lookupable[R] + ) = new Lookupable[Either[L, R]] { + type C = Either[lookupableL.C, lookupableR.C] + def definitionLookup[A](that: A => Either[L, R], definition: Definition[A]): C = { + val ret = that(definition.proto) + ret.map { x: R => lookupableR.definitionLookup[A](_ => x, definition) }.left.map { x: L => + lookupableL.definitionLookup[A](_ => x, definition) + } + } + def instanceLookup[A](that: A => Either[L, R], instance: Instance[A]): C = { + import instance._ + val ret = that(proto) + ret.map { x: R => lookupableR.instanceLookup[A](_ => x, instance) }.left.map { x: L => + lookupableL.instanceLookup[A](_ => x, instance) + } + } + } implicit def lookupIsInstantiable[B <: IsInstantiable]( implicit sourceInfo: SourceInfo, compileOptions: CompileOptions -- cgit v1.2.3