Skip to content

Commit bbd194e

Browse files
committed
Merge branch 'master' of github.com:lampepfl/dotty into dotty-scopt
2 parents 9f813b1 + 8d22904 commit bbd194e

File tree

29 files changed

+280
-77
lines changed

29 files changed

+280
-77
lines changed

compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,14 @@ trait PatternTypeConstrainer { self: TypeComparer =>
189189
case _ => false
190190
}
191191

192-
def widenVariantParams = new TypeMap {
193-
def apply(tp: Type) = mapOver(tp) match {
194-
case tp @ AppliedType(tycon, args) =>
195-
val args1 = args.zipWithConserve(tycon.typeParams)((arg, tparam) =>
196-
if (tparam.paramVarianceSign != 0) TypeBounds.empty else arg
197-
)
198-
tp.derivedAppliedType(tycon, args1)
199-
case tp =>
200-
tp
201-
}
192+
def widenVariantParams(tp: Type) = tp match {
193+
case tp @ AppliedType(tycon, args) =>
194+
val args1 = args.zipWithConserve(tycon.typeParams)((arg, tparam) =>
195+
if (tparam.paramVarianceSign != 0) TypeBounds.empty else arg
196+
)
197+
tp.derivedAppliedType(tycon, args1)
198+
case tp =>
199+
tp
202200
}
203201

204202
val widePt =

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
531531
case ClazzTag => "classOf[" ~ toText(const.typeValue) ~ "]"
532532
case CharTag => literalText(s"'${escapedChar(const.charValue)}'")
533533
case LongTag => literalText(const.longValue.toString + "L")
534+
case DoubleTag => literalText(const.doubleValue.toString + "d")
535+
case FloatTag => literalText(const.floatValue.toString + "f")
534536
case _ => literalText(String.valueOf(const.value))
535537
}
536538

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,10 +1998,9 @@ import transform.SymUtils._
19981998
|whose behavior may have changed since version change."""
19991999
}
20002000

2001-
class UnableToEmitSwitch(tooFewCases: Boolean)(using Context)
2001+
class UnableToEmitSwitch()(using Context)
20022002
extends SyntaxMsg(UnableToEmitSwitchID) {
2003-
def tooFewStr: String = if (tooFewCases) " since there are not enough cases" else ""
2004-
def msg = em"Could not emit switch for ${hl("@switch")} annotated match$tooFewStr"
2003+
def msg = em"Could not emit switch for ${hl("@switch")} annotated match"
20052004
def explain = {
20062005
val codeExample =
20072006
"""val ConstantB = 'B'

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -977,30 +977,32 @@ object PatternMatcher {
977977
/** If match is switch annotated, check that it translates to a switch
978978
* with at least as many cases as the original match.
979979
*/
980-
private def checkSwitch(original: Match, result: Tree) = original.selector match {
980+
private def checkSwitch(original: Match, result: Tree) = original.selector match
981981
case Typed(_, tpt) if tpt.tpe.hasAnnotation(defn.SwitchAnnot) =>
982-
val resultCases = result match {
982+
val resultCases = result match
983983
case Match(_, cases) => cases
984984
case Block(_, Match(_, cases)) => cases
985+
case Block((_: ValDef) :: Block(_, Match(_, cases)) :: Nil, _) => cases
985986
case _ => Nil
986-
}
987-
def typesInPattern(pat: Tree): List[Type] = pat match {
987+
val caseThreshold =
988+
if ValueClasses.isDerivedValueClass(tpt.tpe.typeSymbol) then 1
989+
else MinSwitchCases
990+
def typesInPattern(pat: Tree): List[Type] = pat match
988991
case Alternative(pats) => pats.flatMap(typesInPattern)
989992
case _ => pat.tpe :: Nil
990-
}
991993
def typesInCases(cdefs: List[CaseDef]): List[Type] =
992994
cdefs.flatMap(cdef => typesInPattern(cdef.pat))
993995
def numTypes(cdefs: List[CaseDef]): Int =
994996
typesInCases(cdefs).toSet.size: Int // without the type ascription, testPickling fails because of #2840.
995-
if (numTypes(resultCases) < numTypes(original.cases)) {
997+
val numTypesInOriginal = numTypes(original.cases)
998+
if numTypesInOriginal >= caseThreshold && numTypes(resultCases) < numTypesInOriginal then
996999
patmatch.println(i"switch warning for ${ctx.compilationUnit}")
9971000
patmatch.println(i"original types: ${typesInCases(original.cases)}%, %")
9981001
patmatch.println(i"switch types : ${typesInCases(resultCases)}%, %")
9991002
patmatch.println(i"tree = $result")
1000-
report.warning(UnableToEmitSwitch(numTypes(original.cases) < MinSwitchCases), original.srcPos)
1001-
}
1003+
report.warning(UnableToEmitSwitch(), original.srcPos)
10021004
case _ =>
1003-
}
1005+
end checkSwitch
10041006

10051007
val optimizations: List[(String, Plan => Plan)] = List(
10061008
"mergeTests" -> mergeTests,

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
package dotty.tools.dotc
1+
package dotty.tools
2+
package dotc
23
package typer
34

45
import transform._
@@ -800,7 +801,34 @@ object RefChecks {
800801
report.error(problem(), clazz.srcPos)
801802
}
802803

804+
// check that basetype and subtype agree on types of trait parameters
805+
//
806+
// I.e. trait and class parameters not only need to conform to the expected
807+
// type of the corresponding base-trait, but also to the type as seen by the
808+
// inheriting subtype.
809+
def checkTraitParametersOK() = for {
810+
parent <- clazz.info.parents
811+
parentSym = parent.classSymbol
812+
if parentSym.isClass
813+
cls = parentSym.asClass
814+
if cls.paramAccessors.nonEmpty
815+
param <- cls.paramAccessors
816+
} {
817+
val tpeFromParent = parent.memberInfo(param)
818+
val tpeFromClazz = clazz.thisType.memberInfo(param)
819+
if (!(tpeFromParent <:< tpeFromClazz)) {
820+
val msg =
821+
em"""illegal parameter: The types of $param do not match.
822+
|
823+
| $param in $cls has type: $tpeFromParent
824+
| but $clazz expects $param to have type: $tpeFromClazz"""
825+
826+
report.error(msg, clazz.srcPos)
827+
}
828+
}
829+
803830
checkParameterizedTraitsOK()
831+
checkTraitParametersOK()
804832
}
805833

806834
/** Check that `site` does not inherit conflicting generic instances of `baseCls`,

docs/docs/reference/changed-features/eta-expansion.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def next(): T
2828
```
2929

3030
Given a simple reference to `next` does not auto-convert to a function.
31-
One has to write explicitly `() => next()` to achieve that
31+
One has to write explicitly `() => next()` to achieve that.
3232
Once again since the `_` is going to be deprecated it's better to write it this way
3333
rather than `next _`.
3434

docs/docs/reference/dropped-features/limit22.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ The limits of 22 for the maximal number of parameters of function types and the
77
maximal number of fields in tuple types have been dropped.
88

99
* Functions can now have an arbitrary number of parameters. Functions beyond
10-
`Function22` are erased to a new trait `scala.FunctionXXL`
10+
[`scala.Function22`](https://www.scala-lang.org/api/current/scala/Function22.html) are erased to a new trait [`scala.runtime.FunctionXXL`](https://dotty.epfl.ch/api/scala/runtime/FunctionXXL.html).
1111

12-
* Tuples can also have an arbitrary number of fields. Tuples beyond `Tuple22`
13-
are erased to a new trait `scala.TupleXXL`. Furthermore, they support generic
12+
* Tuples can also have an arbitrary number of fields. Tuples beyond [`scala.Tuple22`](https://www.scala-lang.org/api/current/scala/Tuple22.html)
13+
are erased to a new class [`scala.runtime.TupleXXL`](https://dotty.epfl.ch/api/scala/runtime/TupleXXL.html) (which extends the trait [`scala.Product`](https://dotty.epfl.ch/api/scala/Product.html)). Furthermore, they support generic
1414
operation such as concatenation and indexing.
1515

1616
Both of these are implemented using arrays.

docs/docs/reference/dropped-features/xml.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,35 @@ title: "Dropped: XML Literals"
44
---
55

66
XML Literals are still supported, but will be dropped in the near future, to
7-
be replaced with XML string interpolation:
7+
be replaced with [XML string interpolation](https://github.com/lampepfl/xml-interpolator):
8+
89
```scala
9-
xml""" ... """
10+
import dotty.xml.interpolator.*
11+
12+
case class Person(name: String) { override def toString = name }
13+
14+
@main def test: Unit =
15+
val bill = Person("Bill")
16+
val john = Person("John")
17+
val mike = Person("Mike")
18+
val todoList = List(
19+
(bill, john, "Meeting", "Room 203, 11:00am"),
20+
(john, mike, "Holiday", "March 22-24")
21+
)
22+
// XML literals (to be dropped)
23+
val mails1 = for (from, to, heading, body) <- todoList yield
24+
<message>
25+
<from>{from}</from><to>{to}</to>
26+
<heading>{heading}</heading><body>{body}</body>
27+
</message>
28+
println(mails1)
29+
// XML string interpolation
30+
val mails2 = for (from, to, heading, body) <- todoList yield xml"""
31+
<message>
32+
<from>${from}</from><to>${to}</to>
33+
<heading>${heading}</heading><body>${body}</body>
34+
</message>"""
35+
println(mails2)
1036
```
37+
38+
For more information, see the semester project [XML String Interpolator for Dotty](https://infoscience.epfl.ch/record/267527) by Yassin Kammoun (2019).

docs/docs/reference/metaprogramming/inline.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,12 @@ Inline methods can override other non-inline methods. The rules are as follows:
181181

182182
### Relationship to `@inline`
183183

184-
Scala 2 also defines a `@inline` annotation which is used as a hint
185-
for the backend to inline code. The `inline` modifier is a more powerful
186-
option: Expansion is guaranteed instead of best effort,
187-
it happens in the frontend instead of in the backend, and it also applies
188-
to recursive methods.
184+
Scala 2 also defines a `@inline` annotation which is used as a hint for the
185+
backend to inline code. The `inline` modifier is a more powerful option:
186+
187+
- expansion is guaranteed instead of best effort,
188+
- expansion happens in the frontend instead of in the backend and
189+
- expansion also applies to recursive methods.
189190

190191
To cross compile between both Scala 3 and Scala 2, we introduce a new `@forceInline`
191192
annotation which is equivalent to the new `inline` modifier. Note that
@@ -379,7 +380,7 @@ val intTwo: 2 = natTwo
379380

380381
## The `scala.compiletime` Package
381382

382-
The `scala.compiletime` package contains helper definitions that provide support for compile time operations over values. They are described in the following.
383+
The [`scala.compiletime`](https://dotty.epfl.ch/api/scala/compiletime.html) package contains helper definitions that provide support for compile time operations over values. They are described in the following.
383384

384385
### `constValue`, `constValueOpt`, and the `S` combinator
385386

@@ -499,7 +500,7 @@ fail(identity("foo")) // error: failed on: identity("foo")
499500

500501
### The `scala.compiletime.ops` package
501502

502-
The `scala.compiletime.ops` package contains types that provide support for
503+
The [`scala.compiletime.ops`](https://dotty.epfl.ch/api/scala/compiletime/ops.html) package contains types that provide support for
503504
primitive operations on singleton types. For example,
504505
`scala.compiletime.ops.int.*` provides support for multiplying two singleton
505506
`Int` types, and `scala.compiletime.ops.boolean.&&` for the conjunction of two

docs/docs/reference/other-new-features/explicit-nulls.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ So far, we have found the following useful:
6262

6363
When imported, `T | Null` can be used as `T`, similar to regular Scala (without explicit nulls).
6464

65-
See [UnsafeNulls](#UnsafeNulls) section for more details.
65+
See [UnsafeNulls](#unsafenulls) section for more details.
6666

6767
## Unsoundness
6868

@@ -425,7 +425,7 @@ When dealing with local mutable variables, there are two questions:
425425
x = null
426426
```
427427

428-
See [more examples](../../../../tests/explicit-nulls/neg/flow-varref-in-closure.scala).
428+
See [more examples](https://github.com/lampepfl/dotty/blob/master/tests/explicit-nulls/neg/flow-varref-in-closure.scala).
429429

430430
Currently, we are unable to track paths with a mutable variable prefix.
431431
For example, `x.a` if `x` is mutable.

docs/docs/reference/other-new-features/opaques.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ title: "Opaque Type Aliases"
66
Opaque types aliases provide type abstraction without any overhead. Example:
77

88
```scala
9-
object Logarithms:
9+
object MyMath:
1010

1111
opaque type Logarithm = Double
1212

@@ -27,21 +27,21 @@ object Logarithms:
2727
def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y))
2828
def * (y: Logarithm): Logarithm = x + y
2929

30-
end Logarithms
30+
end MyMath
3131
```
3232

3333
This introduces `Logarithm` as a new abstract type, which is implemented as `Double`.
3434
The fact that `Logarithm` is the same as `Double` is only known in the scope where
35-
`Logarithm` is defined which in the above example corresponds to the object `Logarithms`.
35+
`Logarithm` is defined which in the above example corresponds to the object `MyMath`.
3636
Or in other words, within the scope it is treated as type alias, but this is opaque to the outside world
3737
where in consequence `Logarithm` is seen as an abstract type and has nothing to do with `Double`.
3838

3939
The public API of `Logarithm` consists of the `apply` and `safe` methods defined in the companion object.
4040
They convert from `Double`s to `Logarithm` values. Moreover, an operation `toDouble` that converts the other way, and operations `+` and `*` are defined as extension methods on `Logarithm` values.
41-
The following operations would be valid because they use functionality implemented in the `Logarithms` object.
41+
The following operations would be valid because they use functionality implemented in the `MyMath` object.
4242

4343
```scala
44-
import Logarithms.Logarithm
44+
import MyMath.Logarithm
4545

4646
val l = Logarithm(1.0)
4747
val l2 = Logarithm(2.0)

docs/docs/reference/overview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
layout: doc-page
33
title: "Overview"
44
---
5-
The forthcoming Scala 3 implements many language changes and improvements over Scala 2.
5+
Scala 3 implements many language changes and improvements over Scala 2.
66
In this reference, we discuss design decisions and present important differences compared to Scala 2.
77

88
## Goals
@@ -18,7 +18,7 @@ The language redesign was guided by three main goals:
1818
- Further improve the consistency and expressiveness of Scala's language constructs.
1919

2020
Corresponding to these goals, the language changes fall into seven categories:
21-
(1) Core constructs to strengthen foundations, (2) simplifications and (3) [restrictions](#restrictions), to make the language easier and safer to use, (4) dropped constructs to make the language smaller and more regular, (5) [changed constructs](#changes) to remove warts, and increase consistency and usability, (6) [new constructs](#new-constructs) to fill gaps and increase expressiveness, (7) a new, principled approach to metaprogramming that replaces [Scala 2 experimental macros](https://docs.scala-lang.org/overviews/macros/overview.html).
21+
(1) Core constructs to strengthen foundations, (2) simplifications and (3) [restrictions](#restrictions), to make the language easier and safer to use, (4) [dropped constructs](#dropped-constructs) to make the language smaller and more regular, (5) [changed constructs](#changes) to remove warts, and increase consistency and usability, (6) [new constructs](#new-constructs) to fill gaps and increase expressiveness, (7) a new, principled approach to metaprogramming that replaces [Scala 2 experimental macros](https://docs.scala-lang.org/overviews/macros/overview.html).
2222

2323
## Essential Foundations
2424

project/Build.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,9 @@ object Build {
415415
libraryDependencies ++= Seq(
416416
"org.scala-lang.modules" % "scala-asm" % "9.1.0-scala-1", // used by the backend
417417
Dependencies.oldCompilerInterface, // we stick to the old version to avoid deprecation warnings
418-
"org.jline" % "jline-reader" % "3.15.0", // used by the REPL
419-
"org.jline" % "jline-terminal" % "3.15.0",
420-
"org.jline" % "jline-terminal-jna" % "3.15.0" // needed for Windows
418+
"org.jline" % "jline-reader" % "3.19.0", // used by the REPL
419+
"org.jline" % "jline-terminal" % "3.19.0",
420+
"org.jline" % "jline-terminal-jna" % "3.19.0" // needed for Windows
421421
),
422422

423423
// For convenience, change the baseDirectory when running the compiler

scaladoc-testcases/src/tests/genericMethods.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Types:
99
def mixedAndAndOr(base: Int & String, nested: List[Int | Double] & Seq[String]): Unit
1010
= ???
1111

12-
def literal(i: 1, d: 3.3, c: 'c'): 34
12+
def literal(i: 1, d: 3.3d, c: 'c'): 34
1313
= 34
1414

1515
def byName(a: => Int, b: => String | Int): Unit

tests/neg-custom-args/fatal-warnings/i3561.scala

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,4 @@ class Test {
1313
case '5' | Constant => 3
1414
case '4' => 4
1515
}
16-
17-
def test3(x: Any) = (x: @annotation.switch) match { // error: could not emit switch - too few cases
18-
case 1 => 1
19-
case 2 => 2
20-
case x: String => 4
21-
}
2216
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import scala.annotation.switch
2+
3+
sealed trait Fruit
4+
5+
object Fruit {
6+
case object Apple extends Fruit
7+
case object Banana extends Fruit
8+
case object Lemon extends Fruit
9+
case object Lime extends Fruit
10+
case object Orange extends Fruit
11+
12+
def isCitrus(fruit: Fruit): Boolean =
13+
(fruit: @switch) match { // error Could not emit switch for @switch annotated match
14+
case Orange => true
15+
case Lemon => true
16+
case Lime => true
17+
case _ => false
18+
}
19+
}
20+
21+
22+
sealed trait TaggedFruit {
23+
def tag: Int
24+
}
25+
26+
object TaggedFruit {
27+
case object Apple extends TaggedFruit {
28+
val tag = 1
29+
}
30+
case object Banana extends TaggedFruit {
31+
val tag = 2
32+
}
33+
case object Orange extends TaggedFruit {
34+
val tag = 3
35+
}
36+
37+
def isCitrus(fruit: TaggedFruit): Boolean =
38+
(fruit.tag: @switch) match { // error Could not emit switch for @switch annotated match
39+
case Apple.tag => true
40+
case 2 => true
41+
case 3 => true
42+
case _ => false
43+
}
44+
45+
// fewer than four cases, so no warning
46+
def succ1(fruit: TaggedFruit): Boolean =
47+
(fruit.tag: @switch) match {
48+
case 3 => false
49+
case 2 | Apple.tag => true
50+
}
51+
52+
// fewer than four cases, so no warning
53+
def succ2(fruit: TaggedFruit): Boolean =
54+
(fruit.tag: @switch) match {
55+
case 3 => false
56+
case 2 => true
57+
case Apple.tag => true
58+
}
59+
}

0 commit comments

Comments
 (0)