diff options
| author | Adam Izraelevitz | 2020-07-30 14:57:18 -0700 |
|---|---|---|
| committer | GitHub | 2020-07-30 21:57:18 +0000 |
| commit | 3b206b5054bc36706f295b3f48f170da8775031f (patch) | |
| tree | e16bb1f94eba3da446a134aec72382e7dc1a8d7f | |
| parent | fca89f6c8544a1e0b42e1cec34207f74bf238e8a (diff) | |
Broken auto-clonetype on Scala 2.11.12 (#1480)
* Added broken auto-clonetype test
* Added bugfix for 2.11
* Add descriptive comment for 2.11 special case
* Update src/test/scala/chiselTests/AutoClonetypeSpec.scala
* Update src/test/scala/chiselTests/AutoClonetypeSpec.scala
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
| -rw-r--r-- | core/src/main/scala/chisel3/Aggregate.scala | 15 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/AutoClonetypeSpec.scala | 22 |
2 files changed, 36 insertions, 1 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index 523d404d..4e9a95c1 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -824,7 +824,20 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { } } + val isAnonFunc = ".*\\$\\$anonfun\\$\\d+$".r + // In Scala 2.11, anonymous functions were compiled to their own classes, while in Scala 2.12, + // they are directly compiled into the enclosing classes. This meant that checking the enclosing + // parent in 2.12 would work, but in 2.11 they wouldn't. This fix just looks for the first enclosing class + // which is not an anonymous function. + def getNonFuncClass(clz: Class[_]): Option[Class[_]] = { + clz.getName match { + case isAnonFunc() => getNonFuncClass(clz.getEnclosingClass) + case _ => Some(clz) + } + } + val mirror = runtimeMirror(clazz.getClassLoader) + val classSymbolOption = try { Some(mirror.reflect(this).symbol) } catch { @@ -834,7 +847,7 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { val enclosingClassOption = (clazz.getEnclosingClass, classSymbolOption) match { case (null, _) => None case (_, Some(classSymbol)) if classSymbol.isStatic => None // allows support for members of companion objects - case (outerClass, _) => Some(outerClass) + case (parent, _) => getNonFuncClass(parent) } // For compatibility with pre-3.1, where null is tried as an argument to the constructor. diff --git a/src/test/scala/chiselTests/AutoClonetypeSpec.scala b/src/test/scala/chiselTests/AutoClonetypeSpec.scala index 88f6378b..d5607dc1 100644 --- a/src/test/scala/chiselTests/AutoClonetypeSpec.scala +++ b/src/test/scala/chiselTests/AutoClonetypeSpec.scala @@ -196,4 +196,26 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils { } } } } + + "Wrapped IO construction without parent reference" should "not fail for autoclonetype" in { + class TestModule extends MultiIOModule { + def thunk[T](f: => T): T = f + val works = thunk(IO(new Bundle { + val x = Output(UInt(3.W)) + })) + } + ChiselStage.elaborate { new TestModule } + } + + "Wrapped IO construction with parent references" should "not fail for autoclonetype" in { + class TestModule(blah: Int) extends MultiIOModule { + // Note that this currently fails only if f: =>T on Scala 2.11.12 + // This works successfully with 2.12.11 + def thunk[T](f: => T): T = f + val broken = thunk(IO(new Bundle { + val x = Output(UInt(blah.W)) + })) + } + ChiselStage.elaborate { new TestModule(3) } + } } |
