scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

update method in structural type will crash compiler. #3175

Closed scabug closed 13 years ago

scabug commented 14 years ago

If the structural type has the update method with empty or 1 argument, it will crash scalac and REPL on 2.8Beta1 and nightly build.

Welcome to Scala version 2.8.0.r21161-b20100314141756 (Java HotSpot(TM) Client VM, Java 1.6.0_16).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def foo(x:{def update:Unit})=x.update
Exception in thread "main" java.lang.IndexOutOfBoundsException
        at scala.collection.LinearSeqLike$$class.apply(LinearSeqLike.scala:78)
        at scala.collection.immutable.List.apply(List.scala:46)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.genArrayCall$$1(CleanUp.scala:377)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.callAsReflective$$1(CleanUp.scala:392)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transform(CleanUp.scala:445)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transformStats$$1.apply(Trees.scala:850)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transformStats$$1.apply(Trees.scala:848)
        at scala.collection.immutable.List.loop$$1(List.scala:116)
        at scala.collection.immutable.List.mapConserve(List.scala:133)
        at scala.tools.nsc.ast.Trees$$Transformer.transformStats(Trees.scala:848)
        at scala.tools.nsc.ast.Trees$$Transformer.transform(Trees.scala:760)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transform(CleanUp.scala:599)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transform$$5.apply(Trees.scala:744)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transform$$5.apply(Trees.scala:742)
        at scala.tools.nsc.ast.Trees$$Transformer.atOwner(Trees.scala:858)
        at scala.tools.nsc.ast.Trees$$Transformer.transform(Trees.scala:741)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transform(CleanUp.scala:599)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transformTrees$$1.apply(Trees.scala:832)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transformTrees$$1.apply(Trees.scala:832)
        at scala.collection.immutable.List.loop$$1(List.scala:116)
        at scala.collection.immutable.List.mapConserve(List.scala:133)
        at scala.tools.nsc.ast.Trees$$Transformer.transformTrees(Trees.scala:832)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transform(CleanUp.scala:493)
        at scala.tools.nsc.ast.Trees$$Transformer.transformTemplate(Trees.scala:834)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transform$$2.apply(Trees.scala:728)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transform$$2.apply(Trees.scala:727)
        at scala.tools.nsc.ast.Trees$$Transformer.atOwner(Trees.scala:858)
        at scala.tools.nsc.ast.Trees$$Transformer.transform(Trees.scala:726)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transform(CleanUp.scala:555)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transformStats$$1.apply(Trees.scala:850)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transformStats$$1.apply(Trees.scala:848)
        at scala.collection.immutable.List.loop$$1(List.scala:116)
        at scala.collection.immutable.List.mapConserve(List.scala:133)
        at scala.tools.nsc.ast.Trees$$Transformer.transformStats(Trees.scala:848)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transform$$1.apply(Trees.scala:722)
        at scala.tools.nsc.ast.Trees$$Transformer$$$$anonfun$$transform$$1.apply(Trees.scala:722)
        at scala.tools.nsc.ast.Trees$$Transformer.atOwner(Trees.scala:858)
        at scala.tools.nsc.ast.Trees$$Transformer.transform(Trees.scala:721)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transform(CleanUp.scala:599)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transformUnit(CleanUp.scala:55)
        at scala.tools.nsc.transform.CleanUp$$CleanUpTransformer.transformUnit(CleanUp.scala:25)
        at scala.tools.nsc.transform.Transform$$Phase.apply(Transform.scala:31)
        at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$applyPhase$$1.apply(Global.scala:270)
        at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$applyPhase$$1.apply(Global.scala:270)
        at scala.tools.nsc.reporters.Reporter.withSource(Reporter.scala:49)
        at scala.tools.nsc.Global$$GlobalPhase.applyPhase(Global.scala:270)
        at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$run$$1.apply(Global.scala:248)
        at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$run$$1.apply(Global.scala:248)
        at scala.collection.Iterator$$class.foreach(Iterator.scala:582)
        at scala.collection.mutable.ListBuffer$$$$anon$$1.foreach(ListBuffer.scala:287)
        at scala.tools.nsc.Global$$GlobalPhase.run(Global.scala:248)
        at scala.tools.nsc.Global$$Run.compileSources(Global.scala:727)
        at scala.tools.nsc.Interpreter.compileAndSaveRun(Interpreter.scala:549)
        at scala.tools.nsc.Interpreter$$Request.objRun(Interpreter.scala:904)
        at scala.tools.nsc.Interpreter$$Request.compile(Interpreter.scala:927)
        at scala.tools.nsc.Interpreter.interpret(Interpreter.scala:616)
        at scala.tools.nsc.Interpreter.interpret(Interpreter.scala:608)
        at scala.tools.nsc.InterpreterLoop.reallyInterpret$$1(InterpreterLoop.scala:500)
        at scala.tools.nsc.InterpreterLoop.interpretStartingWith(InterpreterLoop.scala:537)
        at scala.tools.nsc.InterpreterLoop.command(InterpreterLoop.scala:393)
        at scala.tools.nsc.InterpreterLoop.processLine$$1(InterpreterLoop.scala:246)
        at scala.tools.nsc.InterpreterLoop.repl(InterpreterLoop.scala:259)
        at scala.tools.nsc.InterpreterLoop.main(InterpreterLoop.scala:574)
        at scala.tools.nsc.MainGenericRunner$$.main(MainGenericRunner.scala:67)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

Originally, this bug was reported at http://old.nabble.com/-scala--a-compiler-crash-on-2.8.Beta1-to27846332.html The attached patch will fix this crash bug.

scabug commented 14 years ago

Imported From: https://issues.scala-lang.org/browse/SI-3175?orig=1 Reporter: Atsuhiko Yamanaka (ymnk) Attachments:

scabug commented 14 years ago

Atsuhiko Yamanaka (ymnk) said: a patch to fix the reported crash bug

scabug commented 14 years ago

@paulp said: (In r21164) Tighten update check in cleanup. Closes #3175. No review.

scabug commented 14 years ago

@paulp said: Thanks for the patch.

scabug commented 14 years ago

Atsuhiko Yamanaka (ymnk) said: IMHO, this is not a bug, but the first argument of "update" and "apply" methods should be checked if it is Int type or not. Without such a check, the dead code(, which never be invoked) will be generated.

          def isArrayMethodSignature =
            (methSym.name == nme.length && params.isEmpty) ||
            (methSym.name == nme.update &&
             (structResType.typeSymbol eq UnitClass) &&
             params.size == 2) ||
            (methSym.name == nme.apply  && params.size == 1) ||
            (methSym.name == nme.clone_ && params.isEmpty)
scabug commented 14 years ago

@paulp said: Replying to [comment:3 ymnk]:

IMHO, this is not a bug, but the first argument of "update" and "apply" methods should be checked if it is Int type or not.

No, it's a bug, there's no reason it shouldn't utilize all available information. Array only has 4 methods, we ought to be able to nail them! I checked in something closer to optimal in r21224.

scabug commented 14 years ago

@paulp said: (In r21226) During my last look at r21224 I noticed what must be a long standing bug in Array.update handling. Fixing this probably never to be noticed corner case (see bug3175.scala) seduced me into drumming out some duplication. At least we got some nice commenting out of it. Review by dubochet.