New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple assignment does not do correct typing #140
Comments
Imported From: https://issues.scala-lang.org/browse/SI-140?orig=1 |
@odersky said: |
David Pollak (dpp) said: I scanned through the spec for mention of this form of assignment, but could not find anything. A pointer would be appreciated. If I rewrite the code to: val (tis, not: Option[String]) = ("a", "b") match {
case ("b", _) => (Some("Dog"), None)
case _ => (Some((1,2)), Some("Dog"))
}
val is: Option[String] = tis The compiler picks up the error. Thanks! |
@odersky said: Value definitions can alternatively have a pattern ... -- Martin |
@odersky said: |
@dcsobral said: The semantics I'd personally like to see is: if the inferred/ascribed type cannot satisfy the pre-erasure type of pattern match statements (valid for val, for and match), return an error. Just to compare and combine with #900, these are things I'd expect: for (i: Int <- List('symbol, "string", true)) yield i // compiles |
@dcsobral said: for (i: Int <- List('symbol, "string", true)) yield i // compiles
for (i: Int <- List(false, true, false)) yield i // error |
@soc said: scala> val (is: Option[String], not: Option[String]) = ("a", "b") match {
| case ("b", _) => (Some("Dog"), None)
| case _ => (Some((1,2)), Some("Dog"))
| }
java.lang.Error: symbol value x$$1 does not exist in <init>
at scala.tools.nsc.symtab.SymbolTable.abort(SymbolTable.scala:35)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:1027)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.genLoadQualifier(GenICode.scala:1175)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:921)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.genLoadQualifier(GenICode.scala:1175)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:738)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genStat(GenICode.scala:163)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$genStat$$1.apply(GenICode.scala:143)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$genStat$$1.apply(GenICode.scala:143)
at scala.collection.LinearSeqOptimized$$class.foldLeft(LinearSeqOptimized.scala:111)
at scala.collection.immutable.List.foldLeft(List.scala:45)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.genStat(GenICode.scala:143)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:1052)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:114)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.collection.LinearSeqOptimized$$class.foreach(LinearSeqOptimized.scala:59)
at scala.collection.immutable.List.foreach(List.scala:45)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:69)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:136)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:88)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.collection.LinearSeqOptimized$$class.foreach(LinearSeqOptimized.scala:59)
at scala.collection.immutable.List.foreach(List.scala:45) scala> val (tis, not: Option[String]) = ("a", "b") match {
| case ("b", _) => (Some("Dog"), None)
| case _ => (Some((1,2)), Some("Dog"))
| }
java.lang.Error: symbol value x$$1 does not exist in <init>
at scala.tools.nsc.symtab.SymbolTable.abort(SymbolTable.scala:35)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:1027)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.genLoadQualifier(GenICode.scala:1175)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:921)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.genLoadQualifier(GenICode.scala:1175)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:738)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genStat(GenICode.scala:163)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$genStat$$1.apply(GenICode.scala:143)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$genStat$$1.apply(GenICode.scala:143)
at scala.collection.LinearSeqOptimized$$class.foldLeft(LinearSeqOptimized.scala:111)
at scala.collection.immutable.List.foldLeft(List.scala:45)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.genStat(GenICode.scala:143)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.scala$$tools$$nsc$$backend$$icode$$GenICode$$ICodePhase$$$$genLoad(GenICode.scala:1052)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:114)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.collection.LinearSeqOptimized$$class.foreach(LinearSeqOptimized.scala:59)
at scala.collection.immutable.List.foreach(List.scala:45)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:69)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:136)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.gen(GenICode.scala:88)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$gen$$1.apply(GenICode.scala:69)
at scala.collection.LinearSeqOptimized$$class.foreach(LinearSeqOptimized.scala:59)
at scala.collection.immutable.List.foreach(List.scala:45) and the last two don't compile: scala> for (i: Int <- List('symbol, "string", true)) yield i // compiles
<console>:8: error: type mismatch;
found : (Int) => Int
required: (Any) => ?
for (i: Int <- List('symbol, "string", true)) yield i // compiles
^ scala> for (i: Int <- List(false, true, false)) yield i // error
<console>:8: error: type mismatch;
found : (Int) => Int
required: (Boolean) => ?
for (i: Int <- List(false, true, false)) yield i // error
^ |
@som-snytt said:
|
Given @som-snytt's has shown the code block no longer compiles (still the behaviour today in 2.12.2), can't this closed now? |
to be sure, we have to alter Som's code a bit:
but this is covered by the erasure warning; the overall pattern match is correctly typed as |
is: Option[String] = Some(1) 😨 here be dragons |
yeah that type erasure warning should probably have skulls and knives in it... pretty common to see beginners just ignoring it |
Consider adding a compiler option |
more seriously: perhaps we ought to break with tradition here and make the absence of |
|
The following code should not compile:
Note that 'is' is typed as an Option[String], but it is assigned either Option[String] or Option[(Int, Int)]
This leads to a runtime error.
The text was updated successfully, but these errors were encountered: